一直以来,我在想做一个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. 三、使用方法
- 启动 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