使用python写了一个pc微信自动回复脚本,做一下记录分享,这个脚本需要电脑保持亮屏,通过模拟键盘和鼠标操作来完成消息自动回复。
通过订阅特定好友的聊天消息,并将消息整合发送给指定的ai大模型,生成回复。
脚本通过配置可以接入chatgpt、deepseek、通义千问等模型。不支持图片语音的识别,只能对文字做出回复。
环境准备
下载wxauto和openai库
pip install wxauto
pip install openai
配置文件
通过配置文件来指定运行环境变量
[DEFAULT]
api_key = # 你的API Key
base_url = # 你希望接入的API URL
model = # 你希望使用的模型
listen_friends = # 你希望自动回复的好友列表
system_prompt = # 系统提示词
消息接收类
import time
import threading
class WxReceiver(threading.Thread):
def __init__(self, wx, ai, msg_dic, lock):
threading.Thread.__init__(self)
self.wx = wx
self.ai = ai
self.msg_dic = msg_dic
self.lock = lock
def run(self):
while True:
self.lock.acquire()
try:
msgs = self.wx.GetListenMessage()
for chat in msgs:
# 获取聊天窗口名
who = chat.who
# 获取消息内容
one_msgs = msgs.get(chat)
for msg in one_msgs:
# 获取消息类型
msg_type = msg.type
if msg_type == 'friend':
# 获取消息内容,字符串类型的消息内容
content = msg.content
# 如果是/clear清除历史消息
if content == '/clear':
if who in self.msg_dic:
del self.msg_dic[who]
self.wx.SendMsg(self.ai.get_response(content), who)
# 消息加入队列
if who not in self.msg_dic:
self.msg_dic[who] = [time.time()]
# 重置时间
self.msg_dic[who][0] = time.time()
self.msg_dic[who].append(content)
# print('接受消息存储',self.msg_dic[who])
finally:
self.lock.release()
time.sleep(1)
消息发送类
import time
import threading
class WxSender(threading.Thread):
def __init__(self, wx, ai, msg_dic, lock):
threading.Thread.__init__(self)
self.wx = wx
self.ai = ai
self.msg_dic = msg_dic
self.lock = lock
def run(self):
while True:
self.lock.acquire()
try:
now = time.time()
for key in list(self.msg_dic.keys()):
# print('获取消息',self.msg_dic[key])
# 超过五秒没有收到新的消息则回复
if now - self.msg_dic[key][0] > 5:
msg = self.get_msg(key)
print(msg)
if msg == '':
msg = '对不起,我无法理解您的问题'
else:
msg = self.ai.get_response(key, msg)
self.wx.SendMsg(msg, key)
del self.msg_dic[key]
finally:
self.lock.release()
time.sleep(1)
def get_msg(self, who):
msgs = self.msg_dic[who][1:]
res = ''
# 过滤语音和表情包
for msg in msgs:
if msg.startswith('[语音'):
continue
if msg.startswith('[动画'):
continue
if msg.startswith('[') and len(msg) < 6:
continue
res += msg
# 多条消息之间添加空行
res += '\n\n'
return res
ai类
用于调用api获取ai模型的回复
from openai import OpenAI
class AI:
def __init__(self, api_key, base_url, model, system_prompt):
self.api_key = api_key
self.base_url = base_url
self.model = model
self.chat_dict = {}
self.system_prompt = system_prompt
def get_response(self, who, message):
if message == '/clear':
del self.chat_dict[who]
return '已清空历史聊天记录'
try:
client = OpenAI(
api_key=self.api_key,
base_url=self.base_url
)
completion = client.chat.completions.create(
model=self.model,
messages=self.get_history_chat(who, message)
)
response = completion.choices[0].message.content
self.chat_dict[who].append({'role': 'assistant', 'content': response})
return response
except Exception as e:
print(f"错误信息:{e}")
print("请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code")
def get_history_chat(self, who, message):
if who not in self.chat_dict:
self.chat_dict[who] = [{'role': 'system', 'content': self.system_prompt}]
self.chat_dict[who].append({'role': 'user', 'content': message})
while len(self.chat_dict[who]) > 10 or self.chat_dict[who][1]['role'] == 'assistant':
self.chat_dict[who].pop(1)
return self.chat_dict[who]
主类
主类实现所有对象的配置,以及接收者和发送者线程的开启
import threading
import configparser
import time
from wxauto import WeChat
from ai import AI
from wx_receiver import WxReceiver
from wx_sender import WxSender
#等待时间
wait = 1
# 监听的好友列表
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')
api_key = config.get('DEFAULT','api_key')
base_url = config.get('DEFAULT','base_url')
model = config.get('DEFAULT','model')
listen_friends = [item.strip() for item in config.get('DEFAULT','listen_friends').split(',')]
system_prompt = config.get('DEFAULT','system_prompt')
ai = AI(api_key, base_url, model, system_prompt)
wx = WeChat()
for listen_friend in listen_friends:
wx.AddListenChat(listen_friend)
msg_dic = {}
lock = threading.Lock()
wx_receiver_obj = WxReceiver(wx, ai, msg_dic, lock)
wx_sender_obj = WxSender(wx, ai,msg_dic, lock)
wx_receiver_obj.start()
wx_sender_obj.start()
wx_receiver_obj.join()
wx_sender_obj.join()