注册

成为海王的日子——我做了一个微信自动聊天的工具

一直幻想着能够成为一个海王,于是做了一个微信自动聊天的工具。


测试微信版本:wechat 3.9.12.17


采用技术:



  • Bmob后端云(AI对话和存储需要自动聊天的人和prompt)
  • uiautomation
  • pyautogui

开发语言:



  • python,conda环境下运行

最终的效果大家可以看B站:http://www.bilibili.com/video/BV1yK…


一、获取微信对话内容


这里采用了网上的一些开源项目进行修改,写了一个自己的WeChat控制类,采用的是uiautomation和pyautogui组件进行UI的控制,模拟人的操作。


WeChat控制类的内容比较多,为了方便阅读,这里只呈现一部分,有需要的朋友可以联系我获取。


class WeChat:
def __init__(self, path, locale="zh-CN"):
# 微信打开路径
self.path = path

# 用于复制内容到剪切板
self.app = QApplication([])

self.lc = WeChatLocale(locale)

# 鼠标移动到控件上
def move(self,element):
x, y = element.GetPosition()
auto.SetCursorPos(x, y)

# 鼠标快速点击控件
def click(self,element):
x, y = element.GetPosition()
auto.Click(x, y)

# 鼠标右键点击控件
def right_click(self,element):
x, y = element.GetPosition()
auto.RightClick(x, y)


# 鼠标快速点击两下控件
def double_click(self,element):
x, y = element.GetPosition()
auto.SetCursorPos(x, y)
element.DoubleClick()


# 打开微信客户端
def open_wechat(self):
subprocess.Popen(self.path)

# 搜寻微信客户端控件
def get_wechat(self):
return auto.WindowControl(Depth=1, Name=self.lc.weixin)

# 防止微信长时间挂机导致掉线
def prevent_offline(self):
self.open_wechat()
self.get_wechat()

search_box = auto.EditControl(Depth=8, Name=self.lc.search)
self.click(search_box)

# 搜索指定用户
def get_contact(self, name):
self.open_wechat()
self.get_wechat()

search_box = auto.EditControl(Depth=8, Name=self.lc.search)
self.click(search_box)

pyperclip.copy(name)
auto.SendKeys("{Ctrl}v")

# 等待客户端搜索联系人
time.sleep(0.3)
search_box.SendKeys("{enter}")

# 鼠标移动到发送按钮处点击发送消息
def press_enter(self):
# 获取发送按钮
send_button = auto.ButtonControl(Depth=15, Name=self.lc.send)
self.click(send_button)

# 检测微信发新消息的用户
def check_new_user(self):
self.open_wechat()
self.get_wechat()

users = []

# 获取左侧聊天按钮
chat_btn = auto.ButtonControl(Name=self.lc.chats)
self.double_click(chat_btn)

# 持续点击聊天按钮,直到获取完全部新消息
item = auto.ListItemControl(Depth=10)
prev_name = item.ButtonControl().Name
while True:
# 判断该联系人是否有新消息
pane_control = item.PaneControl()
if len(pane_control.GetChildren()) == 3:
users.append(item.ButtonControl().Name)

self.click(item)

# 跳转到下一个新消息
self.double_click(chat_btn)
item = auto.ListItemControl(Depth=10)

# 已经完成遍历,退出循环
if prev_name == item.ButtonControl().Name:
break

prev_name = item.ButtonControl().Name

return users


二、获取需要自动聊天的人和对应的prompt


这部分信息我存储在Bmob后端云上面,对应的表结构(表名为:autochat,创建的字段为:nameprompt)和测试的内容如下:


image.png


获取信息的时候,我采用了子线程的方式,每隔300秒获取一次新的需要自动对话的微信和对应的prompt,代码如下:


# Bmob对象
bmob = Bmob(config['bmob_appid'], config['bmob_secret'])

# 存储从Bmob后端云获取到的自动对话的微信名和对应的prompt
name_prompts = {}

# 从Bmob后端云获取自动聊天的微信名和prompt
def get_user_prompt():
users = bmob.findObjects('autochat')
name_prompts.clear()
for user in users:
name_prompts[user.name] = user.prompt

# 每隔5分钟获取一次要自动聊天微信名称和对应的prompt
def run_with_interval():
while True:
get_user_prompt()
time.sleep(300)

if __name__ == "__main__":
t = threading.Thread(target=run_with_interval)
t.start()


三、组装对话上下文和自动对话


这里主要用到了WeChat类的获取新对话人名字获取某个人历史聊天记录的方法,和Bmob后端云的AI功能,具体代码如下:


# 执行自动聊天功能
def main():
wechat = WeChat(path=config['wechat_path'])
# 创建一个锁
lock = threading.Lock()

while True:
try:
comtypes.CoInitialize()
# 确保微信操作的线程安全
with lock:
wechat.click(auto.ButtonControl(Name=wechat.lc.facorites))
users = wechat.check_new_user()
if len(users) <= 0:
time.sleep(5)
print("暂时没有新消息")
continue

for user in users:
if user not in name_prompts.keys():
time.sleep(5)
print(f"{user}不在需要自动问答的名单上")
continue
else:
# 获取聊天记录,30这个数字可以调整,越大的话,AI会越了解你,但消耗的token也越多
msgList = wechat.get_dialogs(user, 30)
if len(msgList) <= 0:
continue

# 组装上下文对话记录
ai = []
ai.append({"content": name_prompts[user], "role": "system"})
for msg in msgList:
chatmsg = msg[2].replace('[动画表情]','')
if chatmsg=='':
continue

if msg[1] == user:
ai.append({"content": chatmsg, "role": "user"})
else:
ai.append({"content": chatmsg, "role": "assistant"})

bmob.connectAI()
to = bmob.chat2(ai)
bmob.closeAI()
print('ai:'+to)

if to != "":
wechat.send_msg(user, to)
except Exception as e:
print(e)

作者:小小琪_Bmob后端云
来源:juejin.cn/post/7422401535215435788

0 个评论

要回复文章请先登录注册