|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- # -*- coding: utf-8 -*-
- import io
- import imghdr
- import requests
- from bridge.context import *
- from bridge.reply import *
- from channel.chat_channel import ChatChannel
- from channel.wechatmp.wechatmp_client import WechatMPClient
- from channel.wechatmp.common import *
- from common.log import logger
- from common.singleton import singleton
- from config import conf
-
- import web
- # If using SSL, uncomment the following lines, and modify the certificate path.
- # from cheroot.server import HTTPServer
- # from cheroot.ssl.builtin import BuiltinSSLAdapter
- # HTTPServer.ssl_adapter = BuiltinSSLAdapter(
- # certificate='/ssl/cert.pem',
- # private_key='/ssl/cert.key')
-
-
- @singleton
- class WechatMPChannel(ChatChannel):
- def __init__(self, passive_reply=True):
- super().__init__()
- self.passive_reply = passive_reply
- self.flag = 0
-
- self.client = WechatMPClient()
- if self.passive_reply:
- self.NOT_SUPPORT_REPLYTYPE = [ReplyType.IMAGE, ReplyType.VOICE]
- # Cache the reply to the user's first message
- self.cache_dict = dict()
- # Record whether the current message is being processed
- self.running = set()
- # Count the request from wechat official server by message_id
- self.request_cnt = dict()
- else:
- self.NOT_SUPPORT_REPLYTYPE = []
-
-
- def startup(self):
- if self.passive_reply:
- urls = ("/wx", "channel.wechatmp.passive_reply.Query")
- else:
- urls = ("/wx", "channel.wechatmp.active_reply.Query")
- app = web.application(urls, globals(), autoreload=False)
- port = conf().get("wechatmp_port", 8080)
- web.httpserver.runsimple(app.wsgifunc(), ("0.0.0.0", port))
-
-
- def send(self, reply: Reply, context: Context):
- receiver = context["receiver"]
- if self.passive_reply:
- logger.info("[wechatmp] reply to {} cached:\n{}".format(receiver, reply))
- self.cache_dict[receiver] = reply.content
- else:
- if reply.type == ReplyType.TEXT or reply.type == ReplyType.INFO or reply.type == ReplyType.ERROR:
- reply_text = reply.content
- self.client.send_text(receiver, reply_text)
- logger.info("[wechatmp] Do send to {}: {}".format(receiver, reply_text))
-
- elif reply.type == ReplyType.VOICE:
- voice_file_path = reply.content
- logger.info("[wechatmp] voice file path {}".format(voice_file_path))
- with open(voice_file_path, 'rb') as f:
- filename = receiver + "-" + context["msg"].msg_id + ".mp3"
- media_id = self.client.upload_media("voice", (filename, f, "audio/mpeg"))
- self.client.send_voice(receiver, media_id)
- logger.info("[wechatmp] Do send voice to {}".format(receiver))
-
- elif reply.type == ReplyType.IMAGE_URL: # 从网络下载图片
- img_url = reply.content
- pic_res = requests.get(img_url, stream=True)
- print(pic_res.headers)
- image_storage = io.BytesIO()
- for block in pic_res.iter_content(1024):
- image_storage.write(block)
- image_storage.seek(0)
- image_type = imghdr.what(image_storage)
- filename = receiver + "-" + context["msg"].msg_id + "." + image_type
- content_type = "image/" + image_type
- # content_type = pic_res.headers.get('content-type')
- media_id = self.client.upload_media("image", (filename, image_storage, content_type))
- self.client.send_image(receiver, media_id)
- logger.info("[wechatmp] sendImage url={}, receiver={}".format(img_url, receiver))
-
- elif reply.type == ReplyType.IMAGE: # 从文件读取图片
- image_storage = reply.content
- image_storage.seek(0)
- image_type = imghdr.what(image_storage)
- filename = receiver + "-" + context["msg"].msg_id + "." + image_type
- content_type = "image/" + image_type
- media_id = self.client.upload_media("image", (filename, image_storage, content_type))
- self.client.send_image(receiver, media_id)
- logger.info("[wechatmp] sendImage, receiver={}".format(receiver))
-
- return
-
- def _success_callback(self, session_id, context, **kwargs): # 线程异常结束时的回调函数
- logger.debug(
- "[wechatmp] Success to generate reply, msgId={}".format(
- context["msg"].msg_id
- )
- )
- if self.passive_reply:
- self.running.remove(session_id)
-
- def _fail_callback(self, session_id, exception, context, **kwargs): # 线程异常结束时的回调函数
- logger.exception(
- "[wechatmp] Fail to generate reply to user, msgId={}, exception={}".format(
- context["msg"].msg_id, exception
- )
- )
- if self.passive_reply:
- assert session_id not in self.cache_dict
- self.running.remove(session_id)
|