commit 1ec0a530bf17fcd253acd64acdfeef5adf2148a0 Author: zhayujie Date: Wed Aug 10 00:04:10 2022 +0800 init: build minimum viable version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2d9075 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ +venv diff --git a/app.py b/app.py new file mode 100644 index 0000000..78e6c4e --- /dev/null +++ b/app.py @@ -0,0 +1,10 @@ +from channel import channel_factory + +if __name__ == '__main__': + # create channel + channel = channel_factory.create_channel("wx") + + # startup channel + channel.startup() + + print("Hello bot") \ No newline at end of file diff --git a/bot/__pycache__/bot.cpython-36.pyc b/bot/__pycache__/bot.cpython-36.pyc new file mode 100644 index 0000000..a006b42 Binary files /dev/null and b/bot/__pycache__/bot.cpython-36.pyc differ diff --git a/bot/__pycache__/bot_factory.cpython-36.pyc b/bot/__pycache__/bot_factory.cpython-36.pyc new file mode 100644 index 0000000..68002af Binary files /dev/null and b/bot/__pycache__/bot_factory.cpython-36.pyc differ diff --git a/bot/baidu/__pycache__/baidu_unit_bot.cpython-36.pyc b/bot/baidu/__pycache__/baidu_unit_bot.cpython-36.pyc new file mode 100644 index 0000000..9a1fff9 Binary files /dev/null and b/bot/baidu/__pycache__/baidu_unit_bot.cpython-36.pyc differ diff --git a/bot/baidu/baidu_unit_bot.py b/bot/baidu/baidu_unit_bot.py new file mode 100644 index 0000000..284eff5 --- /dev/null +++ b/bot/baidu/baidu_unit_bot.py @@ -0,0 +1,26 @@ +# encoding:utf-8 + +import json +import requests +from bot.bot import Bot + + +class BaiduUnitBot(Bot): + def reply(self, query): + token = self.get_token() + url = 'https://aip.baidubce.com/rpc/2.0/unit/service/v3/chat?access_token=' + token + post_data = "{\"version\":\"3.0\",\"service_id\":\"S73177\",\"session_id\":\"\",\"log_id\":\"7758521\",\"skill_ids\":[\"1221886\"],\"request\":{\"terminal_id\":\"88888\",\"query\":\"" + query + "\", \"hyper_params\": {\"chat_custom_bot_profile\": 1}}}" + print(post_data) + headers = {'content-type': 'application/x-www-form-urlencoded'} + response = requests.post(url, data=post_data.encode(), headers=headers) + if response: + return response.json()['result']['context']['SYS_PRESUMED_HIST'][1] + + def get_token(self): + access_key = '${YOUR_ACCESS_KEY}' + secret_key = '${YOUR_SECRET_KEY}' + host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + access_key + '&client_secret=' + secret_key + response = requests.get(host) + if response: + print(response.json()) + return response.json()['access_token'] diff --git a/bot/bot.py b/bot/bot.py new file mode 100644 index 0000000..8b441e9 --- /dev/null +++ b/bot/bot.py @@ -0,0 +1,13 @@ +""" +Auto-replay chat robot abstract class +""" + + +class Bot(object): + def reply(self, query): + """ + bot auto-reply content + :param req: received message + :return: reply content + """ + raise NotImplementedError diff --git a/bot/bot_factory.py b/bot/bot_factory.py new file mode 100644 index 0000000..919215f --- /dev/null +++ b/bot/bot_factory.py @@ -0,0 +1,16 @@ +""" +channel factory +""" + +from bot.baidu.baidu_unit_bot import BaiduUnitBot + + +def create_bot(bot_type): + """ + create a channel instance + :param channel_type: channel type code + :return: channel instance + """ + if bot_type == 'baidu': + return BaiduUnitBot() + raise RuntimeError \ No newline at end of file diff --git a/bridge/__pycache__/bridge.cpython-36.pyc b/bridge/__pycache__/bridge.cpython-36.pyc new file mode 100644 index 0000000..d25ba0c Binary files /dev/null and b/bridge/__pycache__/bridge.cpython-36.pyc differ diff --git a/bridge/bridge.py b/bridge/bridge.py new file mode 100644 index 0000000..3e5af00 --- /dev/null +++ b/bridge/bridge.py @@ -0,0 +1,9 @@ +from bot import bot_factory + + +class Bridge(object): + def __init__(self): + pass + + def fetch_reply_content(self, query): + return bot_factory.BaiduUnitBot().reply(query) diff --git a/channel/__pycache__/channel.cpython-36.pyc b/channel/__pycache__/channel.cpython-36.pyc new file mode 100644 index 0000000..d38f44b Binary files /dev/null and b/channel/__pycache__/channel.cpython-36.pyc differ diff --git a/channel/__pycache__/channel_factory.cpython-36.pyc b/channel/__pycache__/channel_factory.cpython-36.pyc new file mode 100644 index 0000000..d4c4ddc Binary files /dev/null and b/channel/__pycache__/channel_factory.cpython-36.pyc differ diff --git a/channel/channel.py b/channel/channel.py new file mode 100644 index 0000000..94f7b8b --- /dev/null +++ b/channel/channel.py @@ -0,0 +1,31 @@ +""" +Message sending channel abstract class +""" + +from bridge.bridge import Bridge + +class Channel(object): + def startup(self): + """ + init channel + """ + raise NotImplementedError + + def handle(self, msg): + """ + process received msg + :param msg: message object + """ + raise NotImplementedError + + def send(self, msg, receiver): + """ + send message to user + :param msg: message content + :param receiver: receiver channel account + :return: + """ + raise NotImplementedError + + def build_reply_content(self, query): + return Bridge().fetch_reply_content(query) diff --git a/channel/channel_factory.py b/channel/channel_factory.py new file mode 100644 index 0000000..5ecdbeb --- /dev/null +++ b/channel/channel_factory.py @@ -0,0 +1,15 @@ +""" +channel factory +""" + +from channel.wechat.wechat_channel import WechatChannel + +def create_channel(channel_type): + """ + create a channel instance + :param channel_type: channel type code + :return: channel instance + """ + if channel_type == 'wx': + return WechatChannel() + raise RuntimeError \ No newline at end of file diff --git a/channel/wechat/__pycache__/wechat_channel.cpython-36.pyc b/channel/wechat/__pycache__/wechat_channel.cpython-36.pyc new file mode 100644 index 0000000..1efc97c Binary files /dev/null and b/channel/wechat/__pycache__/wechat_channel.cpython-36.pyc differ diff --git a/channel/wechat/wechat_channel.py b/channel/wechat/wechat_channel.py new file mode 100644 index 0000000..bcae08e --- /dev/null +++ b/channel/wechat/wechat_channel.py @@ -0,0 +1,39 @@ +""" +wechat channel +""" +import itchat +import time +import random +import json +from itchat.content import * +from channel.channel import Channel + + +@itchat.msg_register([TEXT]) +def handler_receive_msg(msg): + WechatChannel().handle(msg) + + +class WechatChannel(Channel): + def __init__(self): + pass + + def startup(self): + # login by scan QRCode + itchat.auto_login() + + # start message listener + itchat.run() + + def handle(self, msg): + print("handle: ", msg) + print(json.dumps(msg, ensure_ascii=False)) + from_user_id = msg['FromUserName'] + other_user_id = msg['User']['UserName'] + if from_user_id == other_user_id: + self.send(super().build_reply_content(msg['Text']), from_user_id) + + def send(self, msg, receiver): + time.sleep(random.randint(1, 3)) + print(msg, receiver) + itchat.send(msg + " [bot]", toUserName=receiver)