微信机器人

config.py

"""项目配置"""

# 图灵机器人,99元一月付费版,尽情享用!
tuling_api_key = '88f17f853d974387af64955bed9466f4'

# 自动回复
is_friend_auto_reply = True  # 好友自动回复
is_group_reply = True  # 此项表示群中是否回复
is_group_at_reply = True  # 上一项开启后此项才生效
is_forward_revoke_msg = True  # 开启防撤回模式
is_forward_group_at_msg = False  # 转发群@我的消息

# 机器人主人
bot_master_name = ''  # 使用备注名更安全,只允许一个,可远程控制机器人,如果不设置(空)则将文件助手设置为管理员,但不具备远程控制功能

# 监听某些好友群聊,如老板
is_listen_friend = False
listen_friend_names = '猪哥'  # 需要监听的人名称,使用备注名更安全,允许多个用|分隔,如:主管|项目经理|产品狗
listen_friend_groups = 'Python新手交流'  # 在这些群里监听好友说的话,匹配模式:包含“唯一集团工作群”的群


# 转发信息至群
is_forward_mode = False  # 打开转发模式,主人发送给机器人的消息都将转发至forward_groups群
forward_groups = 'Python新手交流'  # 需要将消息转发的群,匹配模式同上

# 群分享监控
is_listen_sharing = False
listen_sharing_groups = 'Python新手交流'  # 监控群分享,匹配模式同上
config.py

 

 

load.py

from wxpy import *

import config

logger = logging.getLogger('itchat')


def load_config_to_bot(bot):
    """加载配置项"""
    bot_status = '机器人登录成功!!!'
    # 未定义机器人管理员
    if not config.bot_master_name:
        bot.master = bot.file_helper
        bot_status += '\n未设置机器人管理员,信息将发送至文件助手,不能使用远程命令控制机器人!\n\n'
    else:
        master = search_friend(bot, config.bot_master_name)
        # 查找管理员
        if master:
            bot.master = master
            bot_status += '\n机器人管理员成功设置为:「{0}」,这里查看管理员命令手册->' \
                          'https://github.com/pig6/wxrobot\n\n'.format(config.bot_master_name)
        else:
            bot.master = bot.file_helper
            bot_status += '\n在好友列表中未找到名为「{}」的好友,信息将发送至文件助手,不能使用远程命令控制机器人!\n\n'.format(config.bot_master_name)
    # 设置开关
    bot.is_friend_auto_reply = config.is_friend_auto_reply
    bot.is_group_reply = config.is_group_reply
    bot.is_group_at_reply = config.is_group_at_reply
    bot.is_listen_friend = config.is_listen_friend
    bot.is_forward_mode = config.is_forward_mode
    bot.is_listen_sharing = config.is_listen_sharing
    bot.is_forward_revoke_msg = config.is_forward_revoke_msg
    bot.is_forward_group_at_msg = config.is_forward_group_at_msg
    # 加载对应好友和群
    load_listen_friend(bot)
    load_forward_groups(bot)
    load_listen_sharing_groups(bot)
    # 发送机器人状态信息
    bot_status = bot_status if '文件助手' in bot_status else bot_status + bot_status_detail(bot)
    bot.master.send(bot_status)
    logger.info(bot_status)


def load_listen_friend(bot):
    """加载需要监听的人和群"""
    if bot.is_listen_friend:
        bot.listen_friends = search_friends(bot, config.listen_friend_names)
        if not bot.listen_friends:
            bot.listen_friends = []
            bot.is_listen_friend = False
            return '未在好友中找到备注为「{}」的监听对象!'.format(str(config.listen_friend_names))

        bot.listen_friend_groups = bot.groups().search(config.listen_friend_groups)
        if len(bot.listen_friend_groups) < 1:
            bot.listen_friend_groups = []
            bot.is_listen_friend = False
            return '未找到群名包含「{}」的监听群!'.format(config.listen_friend_groups)
    return None


def load_forward_groups(bot):
    """加载需要转发的群"""
    if bot.is_forward_mode:
        bot.forward_groups = bot.groups().search(config.forward_groups)
        if len(bot.forward_groups) < 1:
            bot.forward_groups = []
            bot.is_forward_mode = False
            return '未找到群名包含「{}」的转发群!'.format(config.forward_groups)
    return None


def load_listen_sharing_groups(bot):
    """加载监控群"""
    if bot.is_listen_sharing:
        bot.listen_sharing_groups = bot.groups().search(config.listen_sharing_groups)
        if len(bot.listen_sharing_groups) < 1:
            bot.listen_sharing_groups = []
            bot.is_listen_sharing = False
            return '未找到群名包含「{}」的分享监控群!'.format(config.listen_sharing_groups)
    return None


def bot_status_detail(bot):
    """机器人配置状态"""
    bot_config_status = '机器人配置状态:'
    bot_config_status += '\n机器人管理员:{0}({1})'.format(bot.master.remark_name, bot.master.nick_name)
    if bot.is_forward_mode:
        bot_config_status += '\n转发模式已开启,您发送给我的任何信息都将被转发至:{},您可发送命令:关闭转发模式 来关闭转发模式。'.format(str(bot.forward_groups))
    bot_config_status += '\n好友自动回复:{}'.format(('' if bot.is_friend_auto_reply else ''))

    bot_config_status += '\n群聊回复:{}'.format(('' if bot.is_group_reply else ''))
    if bot.is_group_reply:
        bot_config_status += ',是否需要@才回复:{}'.format('' if bot.is_group_at_reply else '')

    bot_config_status += '\n是否开启转发群艾特模式:{}'.format(('' if bot.is_forward_group_at_msg else ''))

    bot_config_status += '\n是否开启防撤回模式:{}'.format(('' if bot.is_forward_revoke_msg else ''))

    bot_config_status += '\n是否开启监听模式:{}'.format('' if bot.is_listen_friend else '')
    if bot.is_listen_friend:
        bot_config_status += ',在{0}中监听{1}'.format(str(bot.listen_friend_groups), str(bot.listen_friends))

    bot_config_status += '\n是否开启转发模式:否'

    bot_config_status += '\n是否开启监控模式:{}'.format('' if bot.is_listen_sharing else '')
    if bot.is_listen_sharing:
        bot_config_status += ',将在以下群中监控分享:{}'.format(str(bot.listen_sharing_groups))
    return bot_config_status


def search_friend(bot, name):
    """查找某个好友
    优先级为:好友备注-好友昵称
    """
    nick_name_friend = None
    for friend in bot.friends():
        if getattr(friend, 'remark_name', None) == name:
            return friend
        elif not nick_name_friend and getattr(friend, 'nick_name', None) == name:
            nick_name_friend = friend
    return nick_name_friend or None


def search_friends(bot, names):
    """查找多个好友,用|分割
    匹配备注和微信昵称
    """
    split_names = names.split('|')
    result_list = []
    for friend in bot.friends():
        if getattr(friend, 'remark_name', None) in split_names:
            result_list.append(friend)
        elif getattr(friend, 'nick_name', None) in split_names:
            result_list.append(friend)
    return result_list
load.py

 

robot.py

from wxpy import *

import wx_reply
import wx_command
import load


# 微信机器人,缓存登录信息
# 如果你需要部署在服务器中,则在下面加入一个入参console_qr=True
# console_qr表示在控制台打出二维码,部署到服务器时需要加上
bot = Bot(cache_path=True)
# 加载配置信息到机器人
load.load_config_to_bot(bot)


"""好友功能"""
@bot.register(msg_types=FRIENDS)
def auto_accept_friends(msg):
    """自动接受好友请求"""
    wx_reply.auto_accept_friends(msg)


@bot.register(chats=Friend)
def friend_msg(msg):
    """接收好友消息"""
    if not msg.bot.is_friend_auto_reply:
        return None
    if msg.type == TEXT:
        wx_reply.auto_reply(msg)
        return None
    elif msg.type == RECORDING:
        return '不停不停,王八念经'
    else:
        pass


"""群功能"""
@bot.register(chats=Group)
def group_msg(msg):
    """接收群消息"""
    # 群@转发功能
    if msg.is_at and msg.bot.is_forward_group_at_msg:
        msg.forward(msg.bot.master, prefix='「{0}」在群「{1}」中艾特了你:'.format(msg.member.name, msg.chat.name))

    if msg.type == TEXT:
        # 群回复
        if msg.bot.is_group_reply:
            if msg.bot.is_group_at_reply:
                # @机器人才回复
                if msg.is_at:
                    wx_reply.auto_reply(msg)
            else:
                # 不用@直接回复
                wx_reply.auto_reply(msg)
    elif msg.type == SHARING and msg.bot.is_listen_sharing and msg.chat in msg.bot.listen_sharing_groups:
        # 群分享转发监控,防止分享广告
        msg.forward(msg.bot.master, prefix='分享监控:「{0}」在「{1}」分享了:'.format(msg.member.name, msg.chat.name))
    else:
        pass
    # 监听好友群聊,如老板讲话
    if msg.bot.is_listen_friend and msg.chat in msg.bot.listen_friend_groups and msg.member.is_friend in msg.bot.listen_friends:
        msg.forward(msg.bot.master, prefix='监听指定好友群消息:「{0}」在「{1}」发了消息:'.format(msg.member.is_friend.remark_name or msg.member.nick_name, msg.chat.name))
    return None


@bot.register(msg_types=NOTE)
def system_msg(msg):
    """接收系统消息"""
    wx_reply.handle_system_msg(msg)


"""管理员功能"""
@bot.register(chats=bot.master)
def do_command(msg):
    """执行管理员命令"""
    wx_command.do_command(msg)


# 堵塞进程,直到结束消息监听 (例如,机器人被登出时)
# embed() 互交模式阻塞,电脑休眠或关闭互交窗口则退出程序
bot.join()
robot.py

 

 

tuling_robot.py

import json
import requests

from wxpy import *

import config


"""
    免费申请图灵机器人,获取api_key
    图灵机器人免费申请地址 http://www.tuling123.com
"""
tuling = Tuling(api_key=config.tuling_api_key)


def auto_reply(msg):
    """回复消息,并返回答复文本"""
    return tuling.do_reply(msg)


if __name__ == '__main__':
    """
        直接点击测试图灵机器人
        此apikey为wxpy自带apikey,有使用次数限制,建议自己免费申请一个
        图灵机器人免费申请地址 http://www.tuling123.com
    """
    apikey = '7c8cdb56b0dc4450a8deef30a496bd4c'
    api_url = 'http://www.tuling123.com/openapi/api'
    data = {'key': apikey, 'info': '你好'}
    req = requests.post(api_url, data=data).text
    replys = json.loads(req)['text']
    print(replys)
tuling_robot.py

 

 

wx_command.py

import load


def do_command(msg):
    """执行管理员命令"""
    if '查看状态' == msg.text:
        msg.reply(load.bot_status_detail(msg.bot))
        return None

    if '关闭转发模式' == msg.text:
        msg.bot.is_forward_mode = False
        msg.reply('已关闭转发模式')
        return None

    if msg.bot.is_forward_mode:
        forward_result = remote_forward(msg)
        msg.bot.is_forward_mode = False
        msg.reply('已转发消息至:{},自动退出转发模式!'.format(forward_result))
        return None

    if '开启好友回复' == msg.text:
        msg.bot.is_friend_auto_reply = True
        msg.reply('已开启好友回复')
        return None

    if '关闭好友回复' == msg.text:
        msg.bot.is_friend_auto_reply = False
        msg.reply('已关闭好友回复')
        return None

    if '开启群聊回复' == msg.text:
        msg.bot.is_group_reply = True
        msg.reply('已开启群聊回复')
        return None

    if '关闭群聊回复' == msg.text:
        msg.bot.is_group_reply = False
        msg.reply('已关闭群聊回复')
        return None

    if '开启群聊艾特回复' == msg.text:
        msg.bot.is_group_at_reply = True
        msg.reply('已开启群聊艾特回复')
        return None

    if '关闭群聊艾特回复' == msg.text:
        msg.bot.is_group_at_reply = False
        msg.reply('已关闭群聊艾特回复')
        return None

    if '开启转发群艾特模式' == msg.text:
        msg.bot.is_forward_group_at_msg = True
        msg.reply('已开启转发群艾特模式')
        return None

    if '关闭转发群艾特模式' == msg.text:
        msg.bot.is_forward_group_at_msg = False
        msg.reply('已关闭转发群艾特模式')
        return None

    if '开启防撤回模式' == msg.text:
        msg.bot.is_forward_revoke_msg = True
        msg.reply('已开启防撤回模式')
        return None

    if '关闭防撤回模式' == msg.text:
        msg.bot.is_forward_revoke_msg = False
        msg.reply('已关闭防撤回模式')
        return None

    if '开启监听模式' == msg.text:
        msg.bot.is_listen_friend = True
        # 重新加载配置信息
        errmsg = load.load_listen_friend(msg.bot)
        if errmsg:
            msg.reply('开启监听模式失败,{}'.format(errmsg))
        else:
            msg.reply('已开启监听模式,在{0}中监听{1}'.format(str(msg.bot.listen_friend_groups), str(msg.bot.listen_friends)))
        return None

    if '关闭监听模式' == msg.text:
        msg.msg.bot.is_listen_friend = False
        msg.reply('已关闭监听模式')
        return None

    if '开启监控模式' == msg.text:
        msg.bot.is_listen_sharing = True
        # 重新加载配置信息
        errmsg = load.load_listen_sharing_groups(msg.bot)
        if errmsg:
            msg.reply('开启群分享监控失败,{}'.format(errmsg))
        else:
            msg.reply('已开启群分享监控,将监控这些群:{}'.format(str(msg.bot.listen_sharing_groups)))
        return None

    if '关闭监控模式' == msg.text:
        msg.bot.is_listen_sharing = False
        msg.reply('已关群分享监控')
        return None

    if '开启转发模式' == msg.text:
        msg.bot.is_forward_mode = True
        # 重新加载配置信息
        errmsg = load.load_forward_groups(msg.bot)
        if errmsg:
            msg.reply('开启转发模式失败,{}'.format(errmsg))
        else:
            msg.reply('已开启转发模式,直接发送消息给我就会转发到这些群:{0},如果不想转发可以对我说:{1}'.format(str(msg.bot.forward_groups), '关闭转发模式'))
        return None

    if '休眠' == msg.text:
        remote_down(msg)
        msg.reply('已休眠,所有功能暂停!')
        return None

    if '开启' == msg.text:
        remote_reup(msg)
        msg.reply('已开启')
        return None

    if '退出' == msg.text:
        msg.reply('机器人正在退出...')
        msg.bot.logout()
        return None

    if '查看状态' == msg.text:
        msg.reply(load.bot_status_detail(msg.bot))
        return None

    msg.reply('此命令无法识别:{}'.format(msg.text))
    return None


# 开启所有注册函数
def remote_reup(msg):
    msg.bot.registered.enable()


def remote_down(msg):
    """将除远程主人监听的其他监听注销"""
    do_command_register = msg.bot.registered.get_config(msg)
    msg.bot.registered.remove(do_command_register)
    msg.bot.registered.disable()
    msg.bot.registered.append(do_command_register)


def remote_forward(msg):
    """转发消息"""
    forward_groups = []
    for group in msg.bot.forward_groups:
        msg.forward(group, suffix='猪哥转发')
        forward_groups.append(group.name)
    return forward_groups
wx_command.py

 

 

wx_reply.py

# 好友功能
import re

import tuling_robot


def auto_accept_friends(msg):
    """自动接受好友"""
    # 接受好友请求
    new_friend = msg.card.accept()
    # 向新的好友发送消息
    new_friend.send('我已自动接受了你的好友请求')


def auto_reply(msg):
    """自动回复"""
    # 关键字回复 or 图灵机器人回复
    # handle_withdraw_msg(msg)
    keyword_reply(msg) or tuling_reply(msg)


def keyword_reply(msg):
    """关键字回复"""
    if '你叫啥' in msg.text or '你叫啥名字' in msg.text:
        return msg.reply('沃德天·维森莫·拉莫帅·帅德布耀')
    pass


def tuling_reply(msg):
    """图灵机器人回复"""
    tuling_robot.auto_reply(msg)


def handle_system_msg(msg):
    """处理系统消息"""
    raw = msg.raw
    # 4表示消息状态为撤回
    if raw['Status'] == 4 and msg.bot.is_forward_revoke_msg:
        # 转发撤回的消息
        forward_revoke_msg(msg)


def forward_revoke_msg(msg):
    """转发撤回的消息"""
    # 获取被撤回消息的ID
    revoke_msg_id = re.search('<msgid>(.*?)</msgid>', msg.raw['Content']).group(1)
    # bot中有缓存之前的消息,默认200条
    for old_msg_item in msg.bot.messages[::-1]:
        # 查找撤回的那条
        if revoke_msg_id == str(old_msg_item.id):
            # 判断是群消息撤回还是好友消息撤回
            if old_msg_item.member:
                sender_name = '群「{0}」中的「{1}」'.format(old_msg_item.chat.name, old_msg_item.member.name)
            else:
                sender_name = '「{}」'.format(old_msg_item.chat.name)
            # 名片无法转发
            if old_msg_item.type == 'Card':
                sex = '' if old_msg_item.card.sex == 1 else '' or '未知'
                msg.bot.master.send('「{0}」撤回了一张名片:\n名称:{1},性别:{2}'.format(sender_name, old_msg_item.card.name, sex))
            else:
                # 转发被撤回的消息
                old_msg_item.forward(msg.bot.master,
                                     prefix='{}撤回了一条消息:'.format(sender_name, get_msg_chinese_type(old_msg_item.type)))
            return None


def get_msg_chinese_type(msg_type):
    """转中文类型名"""
    if msg_type == 'Text':
        return '文本'
    if msg_type == 'Map':
        return '位置'
    if msg_type == 'Card':
        return '名片'
    if msg_type == 'Note':
        return '提示'
    if msg_type == 'Sharing':
        return '分享'
    if msg_type == 'Picture':
        return '图片'
    if msg_type == 'Recording':
        return '语音'
    if msg_type == 'Attachment':
        return '文件'
    if msg_type == 'Video':
        return '视频'
    if msg_type == 'Friends':
        return '好友请求'
    if msg_type == 'System':
        return '系统'
wx_reply.py

 

 

 

 

一些说明

requirements.txt

# need to install module
wxpy

 

Readme

## 一、启动步骤
1.下载wxpy库 `pip3 install -U wxpy -i "https://pypi.doubanio.com/simple/"`,使用的是国内源,如果使用anaconda直接在pycharm里面下载,注意项目环境问题!

2.启动`robot.py`,弹出登录二维码,手机微信扫一扫登录

3.邀请好友尽情调戏,新增群聊天和管理员功能,并且提供付费版图灵机器人免费供大家使用

4.在robot.py中修改了bot = Bot(cache_path=True, console_qr=True),console_qr=True表示在控制台打印二维码显示,方便部署到服务器,如果你不需要部署服务器可去掉这个入参


## 二、功能介绍

### 好友功能

针对微信好友的一些功能,如自动通过好友申请,与使用机器人好友聊天等

#### 1.自动通过好友申请
可匹配好友申请时的消息中关键字,例如:请求添加好友说明中包含"加群",则通过申请,其他则不做处理!

#### 2.机器人聊天
目前聊天仅支持文字

wxpy库已经深度整合图灵机器人与小i机器人,目前暂时只接入图灵机器人,后面可实现管理员口令自动切换

管理员可远程控制开关。

### 群功能

#### 1.机器人群聊
群聊中回复好友,默认开启并且需要@机器人,可在`config.py`修改默认配置!
如果配置了机器人管理员则可以用关键字远程控制相关配置。

#### 2.监控群分享
群中如果有谁发分享文章,机器人则会转发至机器人管理员,方便管理员第一时间监控是否有人发广告!
默认关闭,开启需要`config.py`中配置监控群。
管理员可远程控制开关。

#### 3.监听某人
监听某人(如老板)在群聊中的消息,只要他在某群中发布了消息则将消息转发至管理员!
默认关闭,开启需要config.py中配置监听群。
管理员可远程控制开关。

#### 4.转发至群
如果开启转发模式,管理员发送消息给机器人后,机器人将消息转发至指定群,如转发至:Python交流1群...Python交流n群。
默认关闭,开启需要`config.py`中配置转发群。
管理员可远程控制开关。

### 公众号功能
pass

### 管理员功能

如果你使用的是你的小号,那么你可以配置一个管理员,可以远程来控制此机器人,添加方式:
在`config.pyz`中修改配置项`bot_master_name=管理员名称`(最好使用备注名称)即可!

如果没有添加管理员,则无法使用远程控制功能,机器人日志消息将发送至机器人的文件助手中!

设置好机器人的管理员后,可以向机器人发送以下命令来远程控制机器人:

`查看状态`:查看机器人配置状态
<br/><br/>`开启转发模式`:开启之后管理员给机器人发什么他都会转发到指定群,可以发送:关闭转发模式 来关闭换发模式,慎用!<br/>`关闭转发模式`
<br/><br/>`休眠`:所有功能关闭,只允许管理员发指令<br/>`开启`:恢复功能<br/>`退出`:退出登录
<br/><br/>`开启好友回复`:自动聊天回复,默认开启<br/>`关闭好友回复`
<br/><br/>`开启群聊回复`:开启群聊回复,默认开启<br/>`关闭群聊回复`
<br/><br/>`开启群聊艾特回复`:群聊中是否需要@机器人才会回复,默认是需要<br/>`关闭群聊艾特回复`:关闭后则不需要@机器人就会自动回复,慎用!
<br/><br/>`开启转发群艾特模式`:当群聊中有人@你,则会将消息转发至机器管理员,默认开启<br/>`关闭转发群艾特模式`:
<br/><br/>`开启监听模式`:监听某些群中的某些人的群聊,默认关闭,开启前需要配置在哪些群中监听哪些人<br/>`关闭监听模式`
<br/><br/>`开启监控模式`:指定群中有人推分享则会转发到机器人管理员中(监控广告),默认关闭,开启前需要配置监控群<br/>`关闭监控模式`
<br/><br/>`开启防撤回模式`:当有好友或群聊中有人撤回消息,将会把被撤回的消息发送至管理员,默认开启<br/>`关闭防撤回模式`
<br/><br/>

## 三、文档说明

1.[wxpy官方文档](https://wxpy.readthedocs.io/zh/latest/)
Readme

 

posted @ 2019-08-05 09:47  -Rye-  阅读(363)  评论(0)    收藏  举报