101 lines
4.0 KiB
Python
101 lines
4.0 KiB
Python
"""
|
||
钉钉通道接入
|
||
|
||
@author huiwen
|
||
@Date 2023/11/28
|
||
"""
|
||
|
||
# -*- coding=utf-8 -*-
|
||
from channel.dingtalk.dingtalk_message import DingTalkMessage
|
||
from bridge.context import Context
|
||
from bridge.reply import Reply
|
||
from common.log import logger
|
||
from common.singleton import singleton
|
||
from config import conf
|
||
from common.expired_dict import ExpiredDict
|
||
from bridge.context import ContextType
|
||
from channel.chat_channel import ChatChannel
|
||
import logging
|
||
from dingtalk_stream import AckMessage
|
||
import dingtalk_stream
|
||
|
||
|
||
@singleton
|
||
class DingTalkChanel(ChatChannel, dingtalk_stream.ChatbotHandler):
|
||
dingtalk_client_id = conf().get('dingtalk_client_id')
|
||
dingtalk_client_secret = conf().get('dingtalk_client_secret')
|
||
|
||
def setup_logger(self):
|
||
logger = logging.getLogger()
|
||
handler = logging.StreamHandler()
|
||
handler.setFormatter(
|
||
logging.Formatter('%(asctime)s %(name)-8s %(levelname)-8s %(message)s [%(filename)s:%(lineno)d]'))
|
||
logger.addHandler(handler)
|
||
logger.setLevel(logging.INFO)
|
||
return logger
|
||
|
||
def __init__(self):
|
||
super().__init__()
|
||
super(dingtalk_stream.ChatbotHandler, self).__init__()
|
||
self.logger = self.setup_logger()
|
||
# 历史消息id暂存,用于幂等控制
|
||
self.receivedMsgs = ExpiredDict(60 * 60 * 7.1)
|
||
logger.info("[dingtalk] client_id={}, client_secret={} ".format(
|
||
self.dingtalk_client_id, self.dingtalk_client_secret))
|
||
# 无需群校验和前缀
|
||
conf()["group_name_white_list"] = ["ALL_GROUP"]
|
||
|
||
def startup(self):
|
||
credential = dingtalk_stream.Credential(self.dingtalk_client_id, self.dingtalk_client_secret)
|
||
client = dingtalk_stream.DingTalkStreamClient(credential)
|
||
client.register_callback_handler(dingtalk_stream.chatbot.ChatbotMessage.TOPIC, self)
|
||
client.start_forever()
|
||
|
||
def handle_single(self, cmsg: DingTalkMessage):
|
||
# 处理单聊消息
|
||
if cmsg.ctype == ContextType.VOICE:
|
||
logger.debug("[dingtalk]receive voice msg: {}".format(cmsg.content))
|
||
elif cmsg.ctype == ContextType.IMAGE:
|
||
logger.debug("[dingtalk]receive image msg: {}".format(cmsg.content))
|
||
elif cmsg.ctype == ContextType.PATPAT:
|
||
logger.debug("[dingtalk]receive patpat msg: {}".format(cmsg.content))
|
||
elif cmsg.ctype == ContextType.TEXT:
|
||
expression = cmsg.my_msg
|
||
cmsg.content = conf()["single_chat_prefix"][0] + cmsg.content
|
||
context = self._compose_context(cmsg.ctype, cmsg.content, isgroup=False, msg=cmsg)
|
||
if context:
|
||
self.produce(context)
|
||
|
||
def handle_group(self, cmsg: DingTalkMessage):
|
||
# 处理群聊消息
|
||
if cmsg.ctype == ContextType.VOICE:
|
||
logger.debug("[dingtalk]receive voice msg: {}".format(cmsg.content))
|
||
elif cmsg.ctype == ContextType.IMAGE:
|
||
logger.debug("[dingtalk]receive image msg: {}".format(cmsg.content))
|
||
elif cmsg.ctype == ContextType.PATPAT:
|
||
logger.debug("[dingtalk]receive patpat msg: {}".format(cmsg.content))
|
||
elif cmsg.ctype == ContextType.TEXT:
|
||
expression = cmsg.my_msg
|
||
cmsg.content = conf()["group_chat_prefix"][0] + cmsg.content
|
||
context = self._compose_context(cmsg.ctype, cmsg.content, isgroup=True, msg=cmsg)
|
||
context['no_need_at'] = True
|
||
if context:
|
||
self.produce(context)
|
||
|
||
async def process(self, callback: dingtalk_stream.CallbackMessage):
|
||
try:
|
||
incoming_message = dingtalk_stream.ChatbotMessage.from_dict(callback.data)
|
||
dingtalk_msg = DingTalkMessage(incoming_message)
|
||
if incoming_message.conversation_type == '1':
|
||
self.handle_single(dingtalk_msg)
|
||
else:
|
||
self.handle_group(dingtalk_msg)
|
||
return AckMessage.STATUS_OK, 'OK'
|
||
except Exception as e:
|
||
logger.error(e)
|
||
return self.FAILED_MSG
|
||
|
||
def send(self, reply: Reply, context: Context):
|
||
incoming_message = context.kwargs['msg'].incoming_message
|
||
self.reply_text(reply.content, incoming_message)
|