itchat 真实部署过程

安装依赖

pip install itchat

2017年后,新注册的微信基本登录不了网页版,itchat-uos版本利用统信UOS的网页版微信,可以让你绕过网页微信的登录限制。

你只需要执行下条命令便能复活Itchat

pip install itchat-uos==1.5.0.dev0

由于扫码一直重复所以需要改源代码

pip3 show itchat-uos 

通过上面命令找到安装路径

然后找到对应的login

然后在 itchat/components/login.py 的 login() 函数中,在进入 while not isLoggedIn 循环前增加一个time.sleep(15)

然后启动项目 在15秒内扫码登录就好了

本人是用宝塔部署的一个基于itcht的一个阿里云的通义千文 需要安装 openai 这个包

pip3 install openai 

代码结构如下

chatAli.py

from openai import OpenAI


class AliyunChat:

    def __init__(self, apiKey='xxxxxx'):
        """
        初始化方法。
        """
        self.client = OpenAI(
            # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx",
            api_key=apiKey,
            base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
        )

    def send(self, content):
        if content:
            try:
                completion = self.client.chat.completions.create(
                    model="qwen-turbo",  # 模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
                    messages=[
                        {'role': 'system', 'content': 'You are a helpful assistant.'},
                        {'role': 'user', 'content': content}
                    ]
                )
                return completion.choices[0].message.content
            except Exception as e:
                print(f"错误信息:{e}")
                print("请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code")

main.py

"""
启动微信机器人并导入不同的功能模块
"""
import traceback
import threading
import queue
import logging
import itchat
from itchat.content import TEXT
from module.chatAli import AliyunChat
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(threadName)s %(message)s')


class WeChatBot:
    """
    微信机器人
    """

    def __init__(self):
        # 功能模块映射,根据消息前缀映射到对应的模块名
        # self.module_mapping = get_command_module_dict()

        # 定义消息队列
        self.message_queue = queue.Queue()
        self.num_worker_threads = 5  # 工作线程数

        # 初始化发送者锁字典和锁
        self.sender_locks = {}
        self.sender_locks_lock = threading.Lock()

        self.handle_private_message = None
        self.handle_group_message = None
        self.flag = True
        self.aliyunChat = AliyunChat()

        # 初始化 itchat  enableCmdQR=2
        itchat.auto_login(enableCmdQR=2,exitCallback=self.ec)

        # 注册消息处理函数
        self.register_handlers()

        # 启动消息处理线程
        self.start_worker_threads()
    def ec(self):
        logging.info("退出")
        self.flag = False
    def register_handlers(self):
        """
        注册消息处理器
        """

        # 由于装饰器的使用,我们需要将函数定义在这里,并使用 self 作为参数

        @itchat.msg_register(TEXT, isFriendChat=True)
        def handle_private_message(msg):
            # 将消息放入队列,不直接处理
            self.message_queue.put(('private', msg))

        @itchat.msg_register(TEXT, isGroupChat=True)
        def handle_group_message(msg):
            # 将消息放入队列,不直接处理
            if msg['IsAt']:
                self.message_queue.put(('group', msg))

        # 将函数绑定到实例
        self.handle_private_message = handle_private_message
        self.handle_group_message = handle_group_message

    def start_worker_threads(self):
        """
        启动工作线程
        """
        for i in range(self.num_worker_threads):
            thread_pool = threading.Thread(target=self.message_worker, name=f'Worker-{i + 1}')
            thread_pool.daemon = True
            thread_pool.start()

    def message_worker(self):
        """
        通过多线程和队列处理信息,使用锁确保一时间
        同一人只能占用一个线程
        """
        while self.flag:
            try:
                msg_type, msg_data = self.message_queue.get(timeout=1)
                sender_id = msg_data['FromUserName']

                # 获取或创建发送者的锁
                with self.sender_locks_lock:
                    if sender_id not in self.sender_locks:
                        self.sender_locks[sender_id] = threading.Lock()
                    sender_lock = self.sender_locks[sender_id]

                # 使用发送者的锁,确保同一时间只有一个线程处理该发送者的消息
                with sender_lock:
                    if msg_type == 'private':
                        self.handle_private_message_worker(msg_data)
                    elif msg_type == 'group':
                        self.handle_group_message_worker(msg_data)

                self.message_queue.task_done()
            except queue.Empty:
                continue
            except Exception as exception:
                logging.error("消息处理时发生异常:%s", exception)
        # thread_pool.

    def handle_private_message_worker(self, msg):
        """
        处理私聊消息
        """
        sender = msg['User']
        nickname = sender['NickName']
        content = msg['Text']
        logging.info("私聊消息 - 来自 %s:%s", nickname, content)
        reply = self.generate_reply(nickname, content)
        itchat.send(reply, toUserName=sender['UserName'])

    def handle_group_message_worker(self, msg):
        """
        处理群消息
        """
        if msg['IsAt']:
            group_name = msg['User']['NickName']
            sender_nickname = msg['ActualNickName']
            actual_content = msg['Content']
            # 获取自己的昵称
            my_nickname = itchat.search_friends()['NickName']
            # 去除@信息,提取实际内容
            content = actual_content.replace(f'@{my_nickname}', '').strip()
            logging.info("群聊消息 - %s 中 @%s 说:%s", group_name, sender_nickname, content)
            reply_content = self.generate_reply(sender_nickname, content)
            reply = f"@{sender_nickname} {reply_content}"
            itchat.send(reply, toUserName=msg['FromUserName'])

    def generate_reply(self, nickname, content):
        """
        调用不同的功能模块,处理消息生成回复
        """
        try:
        #     command_sign = content.split(" ")[0]
        #     if command_sign in self.module_mapping:
        #         module_instance = self.module_mapping[command_sign]
        #         reply = module_instance.process_messages(nickname, content)
        #     else:
        #         reply = "对不起,暂时还没有这个功能"
        #     return reply
            return self.aliyunChat.send(content)
        except Exception as exception:
            print(traceback.format_exc())
            logging.error("处理模块时发生异常:%s", exception)
            return '抱歉,出现了一些错误。'

    @staticmethod
    def run():
        """
        开始运行机器人
        """
        while True:
            try:
                itchat.run(blockThread=True)
            except KeyboardInterrupt:
                # 如果用户手动中断,退出循环
                logging.info("微信机器人已停止")
                break
            except Exception as exception:
                logging.error("主循环发生异常:%s", exception)
                if 'request' in str(exception) or 'Logout' in str(exception) or 'login' in str(exception).lower():
                    try:
                        itchat.auto_login(hotReload=True)
                        logging.info("重新登录成功")
                    except Exception as login_exception:
                        logging.error("重新登录失败:%s", login_exception)
                        print("无法重新登录,程序即将退出")
                        break  # 退出循环,不再尝试重新登录
                else:
                    logging.error("无法识别的异常,未能重新登录:%s", exception)
                    print("遇到无法识别的异常,程序即将退出")
                    break  # 退出循环,不再尝试


if __name__ == '__main__':
    bot = WeChatBot()
    bot.run()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值