一直以来,我在想做一个qq机器人,能够实现qq消息的转发,因为对于失物招领工作,其他的都挺满意的,但每天发那么多消息确实很浪费时间,所以就想做一个能够实现自动转发消息的机器人。对于这个需求如何实现,我也构思了很久。这个想法是大二下学期就有的,但一直没有去实现。暑假的时候在家中自学了前端,准备做好一个失物招领网站,但那又是一个半吊子项目,网站并没有完全达到我想要的那种结果。现在来做一个博客,来详细说明我的机器人是如何实现的:

在gooogle的时候,发现了一个很好的框架,一位github大佬写的qqbot框架。于是乎我们只需要调用他的api,以及他的框架来实现我们所想要的需求就可以了。当然,这是需要用python来实现的,所以需要会一些python的基础语法。

下面介绍github这位大佬的qqbot框架:

一、介绍 qqbot 是一个用 python 实现的、基于腾讯 SmartQQ 协议的 QQ 机器人,可运行在 Linux, Windows 和 Mac OSX 平台下。 本项目 github 地址: https://github.com/pandolia/qqbot

你可以通过扩展 qqbot 来实现:

监控、收集 QQ 消息 自动消息推送 聊天机器人 通过 QQ 远程控制你的设备 二、安装方法 在 Python 2.7/3.4+ 下使用,用 pip 安装: pip install qqbot 或者下载 源码 解压后 cd 到该目录并运行: pip install. 三、使用方法

  1. 启动 QQBot 在命令行输入: qqbot ,即可启动一个 QQBot 。 启动过程中会自动弹出二维码图片,需要用手机 QQ 客户端扫码并授权登录。启动成功后,会将本次登录信息保存到本地文件中,下次启动时,可以输入: qqbot -q qq号码 ,先尝试从本地文件中恢复登录信息(不需要手动扫码),只有恢复不成功或登录信息已过期时才会需要手动扫码登录。一般来说,保存的登录信息将在 2 天之后过期。

注意: Linux 下,需要系统中有 gvfs-open 或者 shotwell 命令才能自动弹出二维码图片(一般安装有 GNOME 虚拟文件系统 gvfs 的系统中都会含这两个命令之一)。 Windows10 下,需要系统中已设置了 png 图片文件的默认打开程序才能自动弹出二维码图片。

若系统无法自动弹出二维码图片,可以手动打开图片文件进行扫码,也可以将二维码显示模式设置为 邮箱模式 、 服务器模式 或 文本模式 进行扫码,详见本文档的第七节。

操作 QQBot QQBot 启动后,在另一个控制台窗口使用 qq 命令操作 QQBot ,目前提供以下命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

list 命令提供强大的联系人查询和搜索功能,用法示例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17

其中第三、四个参数如果是 key=val 的格式,则应为 name=xx|nick=xx|mark=xx|card=xx|qq=xx 的格式,如果不是 key=val 的格式,则按以下原则进行处理:若是一串数字,则按 QQ 号进行查询,否则,按名称进行查询。

如果存在重名现象,会列出所有重名的联系人。如:

1

将列出所有名为 “机器人测试” 的群。

如果在 list 命令的第三、四个参数中加入 “:like:” ,则会按部分匹配的模式进行搜索,用法示例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

从 v2.2.5 版开始, list 命令采用表格的形式输出联系人列表,其输出样式示例如下:

为保证表格在终端中的显示效果,建议将终端的输出字体设置为 consolas 、且每行可打印的最大字符数大于 120 。另外需要注意:为保证表格的显示效果,当联系人的名称、名片等属性的长度太长或含有特殊字符时,将对这些属性进行截断或过滤后再输出至终端。

update 命令更新指定的联系人列表,其参数含义和 list 命令相同,如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

可以在消息内容中嵌入“/可爱”等表情关键词来向对方发送表情,详见 facemap.py。还可以在消息内容中使用 \n,\t 这两个转义字符(如: send buddy jack 第一行\n第二行)。

以上所有命令都提供对应的 HTTP API 接口,供 web 前端开发者调用,接口的 url 地址为 http://127.0.0.1:8188/{command} ,只需要将 qq 后面的命令各参数用 “/” 分隔开替换 url 中的 command 就可以了,如: http://127.0.0.1:8188/send/buddy/jack/hello ,其他示例详见 urltestbot.md 。注意:如果命令中含有中文或特殊字符,需要先进行 url 编码( utf8 ),例如,调用 http://127.0.0.1:8188/send/buddy/jack/nihao%20%E4%BD%A0%E5%A5%BD%20wohao 将发送消息 ”nihao 你好 wohao“ 。(提示:在 JavaScript 中,可以使用 encodeURIComponent 函数进行编码)。

另外, QQBot 启动后,用本 QQ 号在其他客户端(如:手机 QQ )上向某个 群/讨论组 发消息 “–version” ,则 QQBot 会自动在该 群/讨论组 回复: “QQBot-v2.x.x” 。

四、实现你自己的 QQ 机器人 实现自己的 QQ 机器人非常简单,只需要定义一个自己的消息响应函数并按插件加载。示例代码:

# -*- coding: utf-8 -*-
def onQQMessage(bot, contact, member, content):
if content == ‘-hello’:
bot.SendTo(contact, ‘你好,我是QQ机器人’)
elif content == ‘-stop’:
bot.SendTo(contact, ‘QQ机器人已关闭’)
bot.Stop()

1 2 3 4 5 6 7 8 9


bot     : QQBot 对象,提供 List/SendTo/Stop/Restart 等接口,详见本文档第五节
contact : QContact 对象,消息的发送者,具有 ctype/qq/uin/nick/mark/card/name 等属性
member  : QContact 对象,仅当本消息为 群消息或讨论组消息 时有效,代表实际发消息的成员
content : str 对象,消息内容
contact 代表消息发送者,其 ctype 属性可以为 buddy/group/discuss ,代表 好友/群/讨论组 对象,表示本消息是 好友消息/群消息/讨论组消息 。

1 2 3 4 5 6 7 8 9 10 11 12


from qqbot import _bot as bot
bot.Login([’-q’, ‘1234’])

1 2 3 4 5 6


返回 好友列表:

bot.List(‘buddy’)

返回名为 ‘jack’ 的好友的列表:

bot.List(‘buddy’, ‘jack’)

返回 群列表:

bot.List(‘group’)

返回名为 “机器人测试” 的群的列表:

bot.List(‘group’, ‘机器人测试’)

1


g = bot.List(‘group’, "456班")[0]   # g 是一个 Group 对象(群“456班”)
bot.List(g)                         # 返回 群“456班” 的成员列表
bot.List(g, ‘card=jack’)            # 返回 群“456班” 中名片为 “jack” 的成员列表
注意上面第三句不允许是 bot.List(g, card=‘jack’) 的格式。

1 2 3 4 5 6 7


g = bot.List(‘group’)[0]   				# g 是一个 Group 对象
print([g, type(g), g.qq, g.name, g.uin, g.mark])	# 打印 g 的各项属性

1 2 3 4 5 6 7 8


更新 好友列表 :

bot.Update(‘buddy’)

更新 群列表 :

bot.Update(‘group’)

更新 某个群的成员列表 :

gl = bot.List(‘group’, "456班")
if gl:
g = gl[0]
bot.Update(g)

1 2 3 4 5 6 7 8 9 10 11 12 13 14


向 昵称 为 jack 的好友发消息

bl = bot.List(‘buddy’, ‘jack’)
if bl:
b = bl[0]
bot.SendTo(b, ‘hello’)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17


def onQQMessage(bot, contact, member, content):
if ‘@ME’ in content:
bot.SendTo(contact, member.name+’,艾特我干嘛呢?’)

1 2 3 4


def onQQMessage(bot, contact, member, content):
if bot.isMe(contact, member):
print(‘This is me’)

1 2


from qqbot import qqbotsched

@qqbotsched(hour=‘11,17’, minute=‘55’)
def mytask(bot):
gl = bot.List(‘group’, ‘456班’)
if gl is not None:
for group in gl:
bot.SendTo(group, ‘同志们:开饭啦啦啦啦啦啦!!!’)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37


{

# QQBot 的配置文件
# 使用 qqbot -u somebody 启动程序时,依次加载:
#     根配置 -> 默认配置 -> 用户 somebody 的配置 -> 命令行参数配置
# 使用 qqbot 启动程序时,依次加载:
#     根配置 -> 默认配置 -> 命令行参数配置

# 用户 somebody 的配置
"somebody" : {
    
    # QQBot-term (HTTP-API) 服务器端口号(该服务器监听 IP 为 127.0.0.1 )
    # 设置为 0 则不会开启本服务器(此时 qq 命令和 HTTP-API 接口都无法使用)。
    "termServerPort" : 8188,
    
    # 二维码 http 服务器 ip,请设置为公网 ip 或空字符串
    "httpServerIP" : "",
    
    # 二维码 http 服务器端口号
    "httpServerPort" : 8189,
    
    # 自动登录的 QQ 号
    "qq" : "3497303033",
    
    # 接收二维码图片的邮箱账号
    "mailAccount" : "3497303033@qq.com",
    
    # 该邮箱的 IMAP/SMTP 服务授权码
    "mailAuthCode" : "feregfgftrasdsew",
    
    # 是否以文本模式显示二维码
    "cmdQrcode" : False,

    # 显示/关闭调试信息
    "debug" : False,

    # QQBot 掉线后自动重启
    "restartOnOffline" : False,
    
    # 在后台运行 qqbot ( daemon 模式)
    "daemon": False,
    
    # 完成全部联系人列表获取之后才启动 QQBot 
    "startAfterFetch" : False,
    
    # 插件目录
    "pluginPath" : ".",
    
    # 启动时需加载的插件
    "plugins" : [],
    
    # 插件的配置(由用户自定义)
    "pluginsConf" : {},

},

# 可以在 默认配置 中配置所有用户都通用的设置
"默认配置" : {
    "qq" : "",
    "pluginPath" : "",
    "plugins" : [
        'qqbot.plugins.sampleslots',
        'qqbot.plugins.schedrestart',
    ],
    "pluginsConf" : {
        'qqbot.plugins.schedrestart': '8:00',
    }
},

# # 注意:根配置是固定的,用户无法修改(在本文件中修改根配置不会生效)
# "根配置" : {
#     "termServerPort" : 8188,
#     "httpServerIP" : "",
#     "httpServerPort" : 8189,
#     "qq" : "",
#     "mailAccount" : "",
#     "mailAuthCode" : "",
#     "cmdQrcode" : False,
#     "debug" : False,
#     "restartOnOffline" : False,
#     "daemon" : False,
#     "startAfterFetch" : False,
#     "pluginPath" : "",
#     "plugins" : [],
#     "pluginsConf" : {}
# },

}

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121


启动 weechat : weechat

连接本服务器: /connect localhost

进入 群聊天 会话: /join group-name

进入 讨论组聊天 会话: /join !discuss-name

进入 好友聊天 会话: /query buddy-name

进入 聊天会话 后,直接敲入文本并回车就可以向对方发送消息了。所有接收到的 QQ 消息也会被转发给相应的 聊天会话 。

在聊天会话之间切换: ctrl+P 或 ctrl+N

显示所有 群和讨论组 的名称: /list

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50


from qqbot import qqbotsched
def  onQQMessage(bot,cntact,member,content):
qian=bot.list(‘buddy’,‘不一’)[0]                 //将我qq号昵称检测到qian中
linux=bot.list(‘group’,‘驾校’)[0]                //将我们寝室群放到linux中
windows=bot.list(‘group’,‘Ingress’)[0]           //将另一个群放到windows中
if content from qian.name:                       //如果监测到消息中有我qq号的消息
bot.SendTo(linux,content)                    //那么将这条消息转发到指定的群

1 2


form qqbot import qqbotsched
def onQQMessage(bot,cntact,member,content):
linux=bot.List(‘group’,‘安工程失物招领群1’)
windows=bot.List(‘group’,‘安工程失物招领群2’)
deepin=bot.List(‘group’,‘安工程失物招领群3’)
if ‘@ME’ in content:
bot.SendTo()

1 2 3