Browse Source

feat: config auto load

master
zhayujie 1 year ago
parent
commit
f8fec2ef5b
6 changed files with 80 additions and 27 deletions
  1. +7
    -4
      README.md
  2. +4
    -2
      app.py
  3. +15
    -13
      bot/chatgpt/chat_gpt_bot.py
  4. +16
    -6
      channel/wechat/wechat_channel.py
  5. +5
    -2
      config.json
  6. +33
    -0
      config.py

+ 7
- 4
README.md View File

@@ -40,13 +40,16 @@ pip3 install itchat


配置文件在根目录的 `config.json` 中,示例文件及各配置项解析如下: (TODO) 配置文件在根目录的 `config.json` 中,示例文件及各配置项解析如下: (TODO)


```json
{

```bash
{
"session_token": "YOUR SESSION TOKEN", # 从页面获取的token
"single_chat_prefix": ["bot", "@bot"], # 私聊触发自动回复的前缀
"group_chat_prefix": ["@bot"], # 群聊触发自动回复的前缀
"group_name_white_list": ["群名称1", "群名称2"] # 开启自动回复的群名称
} }
``` ```


其中 token的设置需要在openAI网页端获取:
其中 session_token 需要在openAI网页端获取:


- 打开 <https://chat.openai.com/chat> 并登录,可使用测试账号 (lgfo353p@linshiyouxiang.net, 密码yy123123),账号来源为该[文章](https://www.bilibili.com/read/cv20257021) - 打开 <https://chat.openai.com/chat> 并登录,可使用测试账号 (lgfo353p@linshiyouxiang.net, 密码yy123123),账号来源为该[文章](https://www.bilibili.com/read/cv20257021)
- F12 进入开发者控制台 - F12 进入开发者控制台


+ 4
- 2
app.py View File

@@ -1,10 +1,12 @@
import config
from channel import channel_factory from channel import channel_factory


if __name__ == '__main__': if __name__ == '__main__':
# load config
config.load_config()

# create channel # create channel
channel = channel_factory.create_channel("wx") channel = channel_factory.create_channel("wx")


# startup channel # startup channel
channel.startup() channel.startup()

print("Hello bot")

+ 15
- 13
bot/chatgpt/chat_gpt_bot.py View File

@@ -2,17 +2,19 @@ import time
from bot.bot import Bot from bot.bot import Bot
from revChatGPT.revChatGPT import Chatbot from revChatGPT.revChatGPT import Chatbot
from common.log import logger from common.log import logger
from config import conf


config = {
"Authorization": "<Your Bearer Token Here>", # This is optional
"session_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..yUEdyIPaNgrKerHa.hQfnBM6Ry2npNvakpj1TL_4wr7fuMeLMWOmy-yOSzJxJw7DNyq5vwKeZBwOzthFBIuSu_CpHvYCK_SvRy2RW0gtjPh1XZMxoXejzwJ8VJaVrj3BjarIJdMKRaIHrFwYlRj6fdWa_nGWeueGf1EDE71aSHf4La-4YjoEX8Ou68XHXEsOYQqMuk06u8Wa_aRq5UAj3Clc99dEw3iHU7xvf8lMmB3T1G1LMaubH21niQj-76pUzlf1Kq278Yl8Q6fOGD_CA7mCvnA1LGYzo7u0P5A8dd-p7K3Oqbxw3Gn2TMyEkzZ2q_rTqSJwnbRG87SEYp5Y6HzYyfNoqM_Ew3OGQqk9PHbv8CjKN6sR53UMNRJeFxkW2owCsR0eCvc8kL-tc5RyHWF3zWVmlOxmzDaHZo_XlA0fgEpjlMZS1ClHCBT6_ZoQRvKan0dkFfhJEdp35aK_v9DLXs46Sfs2rqfN0Fdr698gv0UbGsLdeR00W7M9qMsvXoFDBW3-GnIqsxjjepDPlv4RInMKfSeVdISp4VPWW-GjGyzCB1ooWiyZybaGul1FsdXVSibMq6qsiGUQNr08uf_In3NUPFCKNxJ2iR6A_5-TEiIIjcK6ywbI87L13PFT3oCCXiFxRPjp4f1nUUTGxLcetGzYC_eYmQD004R5M5u1epQdWen4Of1Fzn7D0sOWibSHcl_J9xSxzzVt__b9NVDWieoaGYCO3MJCDVmucfFZ1UFPhIRwsr3nUnom8mnXJocDDSPlb0EWfZhCrMgjhPt7Iqcjg-uNB9QYZNjtHASAcQlUYx5GfP6IZs47UqqLPRlzUISsc65CPyQF6sFgwPO1GNy5Q7QcCUQreMmJdBUyYEUnrKCurZkfRWx2eEJ_1efnnprtUc_Upniar-5PJxAfsZ0Mw4QRweIriRB2CW7L24yZsLR7Q8xzm0vj4KeXeuZ7ZlJJw5f65xndTNwII0jS1-VriBsnKs1SDXJc3WEiviifG8Lx-IjirXoH8Q7RtcqPpRURJApu1aIaWtvSEw5mCGjynuINufN_GEu2r71i231_58IYSK9fBpmRKCkHmTZWkjJmiyhFaG2aYI8Z5UwXEUhOZoijb10ZGgcyW6cnSzuthWfa5VzcYFOa35tE69_xZ8W2A6YKuJeJlW01oXirYxtBazyG2o3dpg-mD_BD7hgU4_ONU8SBXubtbxtCzWqNzIg5F0d0e2pc5aNaDJH3yzK5X1y1nlBZe59l3vCmpmvBfgWzI2Q1pbM_me-1g5-w6ju_waQLvR-DPuUOown_EbiCZ7Zd7BAszVlPMgAMWIJ3AljMceIj6ned8YFldZztM_RdvM1qW_KohVurd_bt3vvIBD_c7gttJzAohod61TYBtu5esXNr-sHQNYfapPp8U8J6KZjJFJVEPdrNYeGFewVFVsgRCx_WfaEyIUTaoC9d_ZTDX_nFn_GJceUANqsJYB_FSbzz7aZLj2WKGK8WKw6ujkSMOrLpspt0meqohTWcV68aIMNDhLdOGS7R53vnTUoyrfGLi2HH9QyF5sjjy_YFz1Z9B1Pcv38c9XKBxHUCMNS9ws6IZlIMaA9z8F5_2s-LSKR88Atnb82gQy-BsRdffTI1IhnLLPeisPv_dVOChCdEVHmTMKDvkiYp9GobHW9V3WBm48K2mYDjR6eW459uJP1TVjGP00-O0FZDHTcBZ9L-pq93EbdhYv1VdT-S8UHWy_zoksV-D-iOmc8DKvEHU3CJcUlEf63vcRuBRzfJdeqvw2E4J5j9tt2tkAO814kng2fZaob8XUmjF3QKevYvY8NKAevp6cpoT7DIDZttT6mEkUy1pW02thh3FMqr_EfsCI5pR84BQCr-LIRDzhudnOxHxXOJXE_zuEt1QNNSAH0eqxA6Mx7N5p3WU7dU0ULGPMtEEXz1IwiGAJ21z8Z77EOrL3vOWUnq3Y1sAPD9PBzaPC8_wezBIXQqI6Ufa6D38xPdZnkoaxMd3PRFu91s9qMoYO4OZ1WfjbQJi51T4M76y1K73eBLGwVgWRguEs8Yqr2F-ctZ-BiSEa2RfOwYcmT5uRbFzZnQCtj32JTNMSIFGQ5It5bR0nPh5BK6LjK2_kbQny6dZ9d_KrBcl15REEKM9XhZOSGWRRwAmf_4iVsy6ceqXMuYMbEGL7xnw6tmBWzuuN21_1RnxY8JS8CtzjPC4LAIRgN7VE4M6LbEcQJiaw9hVsUzLueoP-CCtjBeqQ1ylsaz6C4rOpDISATG-jAQ66FE9P0YHXQXOAip4Bf7KO-IvSvZF_dKv2_RMdAE53dlpup5oCWqPk8qAVNgZXIT6LN8MiqRDVfObQDa-uElVtX8ll7ItOUXRoXUJfxabE6oW.bDrh_KN_-hbGsWTk_0z35g"
}
chatbot = Chatbot(config)
user_session = dict() user_session = dict()
last_session_refresh = time.time() last_session_refresh = time.time()



class ChatGPTBot(Bot): class ChatGPTBot(Bot):
def __init__(self):
config = {
"Authorization": "<Your Bearer Token Here>", # This is optional
"session_token": conf().get("session_token")
}
self.chatbot = Chatbot(config)

def reply(self, query, context=None): def reply(self, query, context=None):


from_user_id = context['from_user_id'] from_user_id = context['from_user_id']
@@ -22,22 +24,22 @@ class ChatGPTBot(Bot):
global last_session_refresh global last_session_refresh
if now - last_session_refresh > 60 * 8: if now - last_session_refresh > 60 * 8:
logger.info('[GPT]session refresh, now={}, last={}'.format(now, last_session_refresh)) logger.info('[GPT]session refresh, now={}, last={}'.format(now, last_session_refresh))
chatbot.refresh_session()
self.chatbot.refresh_session()
last_session_refresh = now last_session_refresh = now


if from_user_id in user_session: if from_user_id in user_session:
if time.time() - user_session[from_user_id]['last_reply_time'] < 60 * 5: if time.time() - user_session[from_user_id]['last_reply_time'] < 60 * 5:
chatbot.conversation_id = user_session[from_user_id]['conversation_id']
chatbot.parent_id = user_session[from_user_id]['parent_id']
self.chatbot.conversation_id = user_session[from_user_id]['conversation_id']
self.chatbot.parent_id = user_session[from_user_id]['parent_id']
else: else:
chatbot.reset_chat()
self.chatbot.reset_chat()
else: else:
chatbot.reset_chat()
self.chatbot.reset_chat()


logger.info("[GPT]convId={}, parentId={}".format(chatbot.conversation_id, chatbot.parent_id))
logger.info("[GPT]convId={}, parentId={}".format(self.chatbot.conversation_id, self.chatbot.parent_id))


try: try:
res = chatbot.get_chat_response(query, output="text")
res = self.chatbot.get_chat_response(query, output="text")
logger.info("[GPT]userId={}, res={}".format(from_user_id, res)) logger.info("[GPT]userId={}, res={}".format(from_user_id, res))


user_cache = dict() user_cache = dict()


+ 16
- 6
channel/wechat/wechat_channel.py View File

@@ -7,6 +7,7 @@ from itchat.content import *
from channel.channel import Channel from channel.channel import Channel
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from common.log import logger from common.log import logger
from config import conf


thead_pool = ThreadPoolExecutor(max_workers=8) thead_pool = ThreadPoolExecutor(max_workers=8)


@@ -21,9 +22,6 @@ def handler_group_msg(msg):
WechatChannel().handle_group(msg) WechatChannel().handle_group(msg)




group_white_list = ['测试群1', '测试群2']


class WechatChannel(Channel): class WechatChannel(Channel):
def __init__(self): def __init__(self):
pass pass
@@ -40,19 +38,22 @@ class WechatChannel(Channel):
from_user_id = msg['FromUserName'] from_user_id = msg['FromUserName']
other_user_id = msg['User']['UserName'] other_user_id = msg['User']['UserName']
content = msg['Text'] content = msg['Text']
if from_user_id == other_user_id and (content.lower().startswith('bot') or content.lower().startswith('@bot')):
if from_user_id == other_user_id and \
self.check_prefix(content, conf().get('group_chat_prefix')):
str_list = content.split('bot', 1) str_list = content.split('bot', 1)
if len(str_list) == 2: if len(str_list) == 2:
content = str_list[1].strip() content = str_list[1].strip()
thead_pool.submit(self._do_send, content, from_user_id) thead_pool.submit(self._do_send, content, from_user_id)




def handle_group(self, msg): def handle_group(self, msg):
logger.info("[WX]receive group msg: " + json.dumps(msg, ensure_ascii=False)) logger.info("[WX]receive group msg: " + json.dumps(msg, ensure_ascii=False))
group_id = msg['User']['UserName'] group_id = msg['User']['UserName']
group_name = msg['User'].get('NickName', None) group_name = msg['User'].get('NickName', None)
if not group_name: if not group_name:
return "" return ""
origin_content = msg['Content']
origin_content = msg['Content']
content = msg['Content'] content = msg['Content']
content_list = content.split(' ', 1) content_list = content.split(' ', 1)
context_special_list = content.split('\u2005', 1) context_special_list = content.split('\u2005', 1)
@@ -61,7 +62,9 @@ class WechatChannel(Channel):
elif len(content_list) == 2: elif len(content_list) == 2:
content = content_list[1] content = content_list[1]


if group_name in group_white_list and (msg['IsAt'] or origin_content.lower().startswith('@bot')):
config = conf()
if group_name in config.get('group_name_white_list') \
and (msg['IsAt'] or self.check_prefix(origin_content, config.get('group_chat_prefix'))):
thead_pool.submit(self._do_send_group, content, msg) thead_pool.submit(self._do_send_group, content, msg)


def send(self, msg, receiver): def send(self, msg, receiver):
@@ -83,3 +86,10 @@ class WechatChannel(Channel):
reply_text = '@' + msg['ActualNickName'] + ' ' + reply_text reply_text = '@' + msg['ActualNickName'] + ' ' + reply_text
if reply_text: if reply_text:
self.send(reply_text, msg['User']['UserName']) self.send(reply_text, msg['User']['UserName'])

def check_prefix(self, content, prefix_list):
for prefix in prefix_list:
if content.lower().startswith(prefix):
return True
return False


+ 5
- 2
config.json View File

@@ -1,3 +1,6 @@
{ {
"bot_": "123"
}
"session_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..yUEdyIPaNgrKerHa.hQfnBM6Ry2npNvakpj1TL_4wr7fuMeLMWOmy-yOSzJxJw7DNyq5vwKeZBwOzthFBIuSu_CpHvYCK_SvRy2RW0gtjPh1XZMxoXejzwJ8VJaVrj3BjarIJdMKRaIHrFwYlRj6fdWa_nGWeueGf1EDE71aSHf4La-4YjoEX8Ou68XHXEsOYQqMuk06u8Wa_aRq5UAj3Clc99dEw3iHU7xvf8lMmB3T1G1LMaubH21niQj-76pUzlf1Kq278Yl8Q6fOGD_CA7mCvnA1LGYzo7u0P5A8dd-p7K3Oqbxw3Gn2TMyEkzZ2q_rTqSJwnbRG87SEYp5Y6HzYyfNoqM_Ew3OGQqk9PHbv8CjKN6sR53UMNRJeFxkW2owCsR0eCvc8kL-tc5RyHWF3zWVmlOxmzDaHZo_XlA0fgEpjlMZS1ClHCBT6_ZoQRvKan0dkFfhJEdp35aK_v9DLXs46Sfs2rqfN0Fdr698gv0UbGsLdeR00W7M9qMsvXoFDBW3-GnIqsxjjepDPlv4RInMKfSeVdISp4VPWW-GjGyzCB1ooWiyZybaGul1FsdXVSibMq6qsiGUQNr08uf_In3NUPFCKNxJ2iR6A_5-TEiIIjcK6ywbI87L13PFT3oCCXiFxRPjp4f1nUUTGxLcetGzYC_eYmQD004R5M5u1epQdWen4Of1Fzn7D0sOWibSHcl_J9xSxzzVt__b9NVDWieoaGYCO3MJCDVmucfFZ1UFPhIRwsr3nUnom8mnXJocDDSPlb0EWfZhCrMgjhPt7Iqcjg-uNB9QYZNjtHASAcQlUYx5GfP6IZs47UqqLPRlzUISsc65CPyQF6sFgwPO1GNy5Q7QcCUQreMmJdBUyYEUnrKCurZkfRWx2eEJ_1efnnprtUc_Upniar-5PJxAfsZ0Mw4QRweIriRB2CW7L24yZsLR7Q8xzm0vj4KeXeuZ7ZlJJw5f65xndTNwII0jS1-VriBsnKs1SDXJc3WEiviifG8Lx-IjirXoH8Q7RtcqPpRURJApu1aIaWtvSEw5mCGjynuINufN_GEu2r71i231_58IYSK9fBpmRKCkHmTZWkjJmiyhFaG2aYI8Z5UwXEUhOZoijb10ZGgcyW6cnSzuthWfa5VzcYFOa35tE69_xZ8W2A6YKuJeJlW01oXirYxtBazyG2o3dpg-mD_BD7hgU4_ONU8SBXubtbxtCzWqNzIg5F0d0e2pc5aNaDJH3yzK5X1y1nlBZe59l3vCmpmvBfgWzI2Q1pbM_me-1g5-w6ju_waQLvR-DPuUOown_EbiCZ7Zd7BAszVlPMgAMWIJ3AljMceIj6ned8YFldZztM_RdvM1qW_KohVurd_bt3vvIBD_c7gttJzAohod61TYBtu5esXNr-sHQNYfapPp8U8J6KZjJFJVEPdrNYeGFewVFVsgRCx_WfaEyIUTaoC9d_ZTDX_nFn_GJceUANqsJYB_FSbzz7aZLj2WKGK8WKw6ujkSMOrLpspt0meqohTWcV68aIMNDhLdOGS7R53vnTUoyrfGLi2HH9QyF5sjjy_YFz1Z9B1Pcv38c9XKBxHUCMNS9ws6IZlIMaA9z8F5_2s-LSKR88Atnb82gQy-BsRdffTI1IhnLLPeisPv_dVOChCdEVHmTMKDvkiYp9GobHW9V3WBm48K2mYDjR6eW459uJP1TVjGP00-O0FZDHTcBZ9L-pq93EbdhYv1VdT-S8UHWy_zoksV-D-iOmc8DKvEHU3CJcUlEf63vcRuBRzfJdeqvw2E4J5j9tt2tkAO814kng2fZaob8XUmjF3QKevYvY8NKAevp6cpoT7DIDZttT6mEkUy1pW02thh3FMqr_EfsCI5pR84BQCr-LIRDzhudnOxHxXOJXE_zuEt1QNNSAH0eqxA6Mx7N5p3WU7dU0ULGPMtEEXz1IwiGAJ21z8Z77EOrL3vOWUnq3Y1sAPD9PBzaPC8_wezBIXQqI6Ufa6D38xPdZnkoaxMd3PRFu91s9qMoYO4OZ1WfjbQJi51T4M76y1K73eBLGwVgWRguEs8Yqr2F-ctZ-BiSEa2RfOwYcmT5uRbFzZnQCtj32JTNMSIFGQ5It5bR0nPh5BK6LjK2_kbQny6dZ9d_KrBcl15REEKM9XhZOSGWRRwAmf_4iVsy6ceqXMuYMbEGL7xnw6tmBWzuuN21_1RnxY8JS8CtzjPC4LAIRgN7VE4M6LbEcQJiaw9hVsUzLueoP-CCtjBeqQ1ylsaz6C4rOpDISATG-jAQ66FE9P0YHXQXOAip4Bf7KO-IvSvZF_dKv2_RMdAE53dlpup5oCWqPk8qAVNgZXIT6LN8MiqRDVfObQDa-uElVtX8ll7ItOUXRoXUJfxabE6oW.bDrh_KN_-hbGsWTk_0z35g",
"single_chat_prefix": ["bot", "@bot"],
"group_chat_prefix": ["@bot"],
"group_name_white_list": ["群名称1", "群名称2"]
}

+ 33
- 0
config.py View File

@@ -0,0 +1,33 @@
import json
import os
from common.log import logger

config = {}


def load_config():
global config
config_path = "config.json"
try:
if not os.path.exists(config_path):
logger.error('配置文件路径不存在')
return
config_str = read_file(config_path)
# 将json字符串反序列化为dict类型
config = json.loads(config_str)
logger.info("[INIT] load config: {}".format(config))
except Exception as e:
logger.error(e)


def get_root():
return os.path.dirname(os.path.abspath( __file__ ))


def read_file(path):
with open(path, 'r') as f:
return f.read()


def conf():
return config

Loading…
Cancel
Save