Ver código fonte

fix(wechatcomapp): split long text messages into multiple parts

master
lanvent 1 ano atrás
pai
commit
73c87d5959
6 arquivos alterados com 39 adições e 23 exclusões
  1. +4
    -2
      channel/wechatcom/README.md
  2. +13
    -3
      channel/wechatcom/wechatcomapp_channel.py
  3. +0
    -17
      channel/wechatmp/common.py
  4. +1
    -0
      channel/wechatmp/passive_reply.py
  5. +4
    -1
      channel/wechatmp/wechatmp_channel.py
  6. +17
    -0
      common/utils.py

+ 4
- 2
channel/wechatcom/README.md Ver arquivo

@@ -1,6 +1,8 @@
# 企业微信应用号channel

企业微信官方提供了客服、应用等API,本channel使用的是企业微信的应用API的能力。因为未来可能还会开发客服能力,所以本channel的类型名叫作`wechatcom_app`。
企业微信官方提供了客服、应用等API,本channel使用的是企业微信的应用API的能力。

因为未来可能还会开发客服能力,所以本channel的类型名叫作`wechatcom_app`。

`wechatcom_app` channel支持插件系统和图片声音交互等能力,除了无法加入群聊,作为个人使用的私人助理已绰绰有余。

@@ -29,7 +31,7 @@

- 在详情页如果点击`企业可信IP`的配置(没看到可以不管),填入你服务器的公网IP
- 点击`接收消息`下的启用API接收消息
- `URL`填写格式为`http://url:port/wxcomapp`,是程序监听的端口,默认是9898
- `URL`填写格式为`http://url:port/wxcomapp`,`port`是程序监听的端口,默认是9898
如果是未认证的企业,url可直接使用服务器的IP。如果是认证企业,需要使用备案的域名,可使用二级域名。
- `Token`可随意填写,停留在这个页面
- 在程序根目录`config.json`中增加配置(**去掉注释**),`wechatcomapp_aes_key`是当前页面的`wechatcomapp_aes_key`


+ 13
- 3
channel/wechatcom/wechatcomapp_channel.py Ver arquivo

@@ -2,6 +2,7 @@
import io
import os
import textwrap
import time

import requests
import web
@@ -17,10 +18,12 @@ from channel.wechatcom.wechatcomapp_client import WechatComAppClient
from channel.wechatcom.wechatcomapp_message import WechatComAppMessage
from common.log import logger
from common.singleton import singleton
from common.utils import compress_imgfile, fsize
from common.utils import compress_imgfile, fsize, split_string_by_utf8_length
from config import conf
from voice.audio_convert import any_to_amr

MAX_UTF8_LEN = 2048


@singleton
class WechatComAppChannel(ChatChannel):
@@ -50,8 +53,15 @@ class WechatComAppChannel(ChatChannel):
def send(self, reply: Reply, context: Context):
receiver = context["receiver"]
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))
reply_text = reply.content
texts = split_string_by_utf8_length(reply_text, MAX_UTF8_LEN)
if len(texts) > 1:
logger.info("[wechatcom] text too long, split into {} parts".format(len(texts)))
for i, text in enumerate(texts):
self.client.message.send_text(self.agent_id, receiver, text)
if i != len(texts) - 1:
time.sleep(0.5) # 休眠0.5秒,防止发送过快乱序
logger.info("[wechatcom] Do send text to {}: {}".format(receiver, reply_text))
elif reply.type == ReplyType.VOICE:
try:
file_path = reply.content


+ 0
- 17
channel/wechatmp/common.py Ver arquivo

@@ -43,20 +43,3 @@ def subscribe_msg():
输入'{trigger_prefix}#帮助' 查看详细指令。"""
)
return msg


def split_string_by_utf8_length(string, max_length, max_split=0):
encoded = string.encode("utf-8")
start, end = 0, 0
result = []
while end < len(encoded):
if max_split > 0 and len(result) >= max_split:
result.append(encoded[start:].decode("utf-8"))
break
end = min(start + max_length, len(encoded))
# 如果当前字节不是 UTF-8 编码的开始字节,则向前查找直到找到开始字节为止
while end < len(encoded) and (encoded[end] & 0b11000000) == 0b10000000:
end -= 1
result.append(encoded[start:end].decode("utf-8"))
start = end
return result

+ 1
- 0
channel/wechatmp/passive_reply.py Ver arquivo

@@ -11,6 +11,7 @@ from channel.wechatmp.common import *
from channel.wechatmp.wechatmp_channel import WechatMPChannel
from channel.wechatmp.wechatmp_message import WeChatMPMessage
from common.log import logger
from common.utils import split_string_by_utf8_length
from config import conf




+ 4
- 1
channel/wechatmp/wechatmp_channel.py Ver arquivo

@@ -18,6 +18,7 @@ from channel.wechatmp.common import *
from channel.wechatmp.wechatmp_client import WechatMPClient
from common.log import logger
from common.singleton import singleton
from common.utils import split_string_by_utf8_length
from config import conf
from voice.audio_convert import any_to_mp3

@@ -140,8 +141,10 @@ class WechatMPChannel(ChatChannel):
texts = split_string_by_utf8_length(reply_text, MAX_UTF8_LEN)
if len(texts) > 1:
logger.info("[wechatmp] text too long, split into {} parts".format(len(texts)))
for text in texts:
for i, text in enumerate(texts):
self.client.message.send_text(receiver, text)
if i != len(texts) - 1:
time.sleep(0.5) # 休眠0.5秒,防止发送过快乱序
logger.info("[wechatmp] Do send text to {}: {}".format(receiver, reply_text))
elif reply.type == ReplyType.VOICE:
try:


+ 17
- 0
common/utils.py Ver arquivo

@@ -32,3 +32,20 @@ def compress_imgfile(file, max_size):
if fsize(out_buf) <= max_size:
return out_buf
quality -= 5


def split_string_by_utf8_length(string, max_length, max_split=0):
encoded = string.encode("utf-8")
start, end = 0, 0
result = []
while end < len(encoded):
if max_split > 0 and len(result) >= max_split:
result.append(encoded[start:].decode("utf-8"))
break
end = min(start + max_length, len(encoded))
# 如果当前字节不是 UTF-8 编码的开始字节,则向前查找直到找到开始字节为止
while end < len(encoded) and (encoded[end] & 0b11000000) == 0b10000000:
end -= 1
result.append(encoded[start:end].decode("utf-8"))
start = end
return result

Carregando…
Cancelar
Salvar