From ab83dacb761c1ff2e718ef093ba6b9b75c8720fb Mon Sep 17 00:00:00 2001 From: lanvent Date: Thu, 20 Apr 2023 01:46:23 +0800 Subject: [PATCH] feat(wechatcom): add support for sending voice messages --- .pre-commit-config.yaml | 1 + channel/wechatcom/wechatcom_channel.py | 36 +++++++++++++++++++++----- voice/audio_convert.py | 18 +++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5dd0d7d..0c39abf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,6 +18,7 @@ repos: hooks: - id: isort exclude: '(\/|^)lib\/' + args: [ -l, '88'] - repo: https://github.com/psf/black rev: 23.3.0 hooks: diff --git a/channel/wechatcom/wechatcom_channel.py b/channel/wechatcom/wechatcom_channel.py index 1fbeccd..6bb4f1f 100644 --- a/channel/wechatcom/wechatcom_channel.py +++ b/channel/wechatcom/wechatcom_channel.py @@ -1,10 +1,12 @@ #!/usr/bin/env python # -*- coding=utf-8 -*- +import os + import web from wechatpy.enterprise import WeChatClient, create_reply, parse_message from wechatpy.enterprise.crypto import WeChatCrypto from wechatpy.enterprise.exceptions import InvalidCorpIdException -from wechatpy.exceptions import InvalidSignatureException +from wechatpy.exceptions import InvalidSignatureException, WeChatClientException from bridge.context import Context from bridge.reply import Reply, ReplyType @@ -13,11 +15,12 @@ from channel.wechatcom.wechatcom_message import WechatComMessage from common.log import logger from common.singleton import singleton from config import conf +from voice.audio_convert import any_to_amr @singleton class WechatComChannel(ChatChannel): - NOT_SUPPORT_REPLYTYPE = [ReplyType.IMAGE, ReplyType.VOICE] + NOT_SUPPORT_REPLYTYPE = [ReplyType.IMAGE] def __init__(self): super().__init__() @@ -43,11 +46,32 @@ class WechatComChannel(ChatChannel): web.httpserver.runsimple(app.wsgifunc(), ("0.0.0.0", port)) def send(self, reply: Reply, context: Context): - print("send reply: ", reply.content, context["receiver"]) receiver = context["receiver"] - reply_text = reply.content - self.client.message.send_text(self.agent_id, receiver, reply_text) - logger.info("[send] Do send to {}: {}".format(receiver, reply_text)) + if reply.type in [ReplyType.TEXT, ReplyType.ERROR, ReplyType.INFO]: + self.client.message.send_text(self.agent_id, receiver, reply.content) + logger.info("[wechatcom] sendMsg={}, receiver={}".format(reply, receiver)) + elif reply.type == ReplyType.VOICE: + try: + file_path = reply.content + amr_file = os.path.splitext(file_path)[0] + ".amr" + any_to_amr(file_path, amr_file) + response = self.client.media.upload("voice", open(amr_file, "rb")) + logger.debug("[wechatcom] upload voice response: {}".format(response)) + except WeChatClientException as e: + logger.error("[wechatcom] upload voice failed: {}".format(e)) + return + try: + os.remove(file_path) + if amr_file != file_path: + os.remove(amr_file) + except Exception: + pass + self.client.message.send_voice( + self.agent_id, receiver, response["media_id"] + ) + logger.info( + "[wechatcom] sendVoice={}, receiver={}".format(reply.content, receiver) + ) class Query: diff --git a/voice/audio_convert.py b/voice/audio_convert.py index 241a3a6..4819b49 100644 --- a/voice/audio_convert.py +++ b/voice/audio_convert.py @@ -69,6 +69,24 @@ def any_to_sil(any_path, sil_path): raise NotImplementedError("Not support file type: {}".format(any_path)) +def any_to_amr(any_path, amr_path): + """ + 把任意格式转成amr文件 + """ + if any_path.endswith(".amr"): + shutil.copy2(any_path, amr_path) + return + if ( + any_path.endswith(".sil") + or any_path.endswith(".silk") + or any_path.endswith(".slk") + ): + raise NotImplementedError("Not support file type: {}".format(any_path)) + audio = AudioSegment.from_file(any_path) + audio = audio.set_frame_rate(8000) # only support 8000 + audio.export(amr_path, format="amr") + + def mp3_to_wav(mp3_path, wav_path): """ 把mp3格式转成pcm文件