简介
本教程主要实现:
QQ群发器:
获取和展示Q群列表
获取和展示好友列表
获取和展示讨论组列表
定时群发的配置
说明:
1.支持契约乾坤多Q框架
2.支持内置变量 防止消息内容相同 被屏蔽
3.使用易语言进行开发,需要大家有基础或者需要有恒心坚持看完
学习内容
通过本教程主要学习:
契约群发、私聊 功能的使用
发送内容: 文本、图片、卡片
定时功能的使用
联系我们
如果你有机器人开发问题或有需求不会开发,可与我们进行联系
QQ机器人开发交流群
声明
本教程非乾坤官方教程,为作者学习易语言过程的知识总结,将主要内容整理、汇总后,形成本教程。
致力于进行技术交流,帮助新人快速入门,少走弯路。
请在遵守中华人民共和国法律、腾讯相关规定和乾坤框架相关说明下进行使用
如您使用本技术,进行包括但不限于如下行为,软件作者并不知情,不承担任何法律风险
1.违法行为
2.违法腾讯规定
3.违法乾坤框架规定
插件下载地址
已经做好的插件下载地址:
乾坤-良驹QQ群发助手
界面效果如下:
教程内容
环境准备
使用易语言软件,打开 sdk模版20191104.e 文件(我使用的是该版本,只要是从官方下载的sdk均可),是一个空的sdk
开始开发
界面制作
鼠标点击 窗口 -> 右键 -> 点击 插入新窗口 ,进入窗口操作界面,如下图
先在 新建窗口上,放一个树形控件 存放所有登录的QQ机器人号码,鼠标点击右侧 组件的 树形 控件,然后在窗口 界面点击鼠标左键 完成树形控件添加
点击 树形 控件,左侧 将会看到很多 树形配置,暂时我们只需要修改 是否有检查框 将其修改为 真,这样树形控件 中的内容前面 会多个复选框 供选择,进而进行其他操作
为了可以显示群列表、好友列表、讨论组列表等,因此添加一个 选择夹 ,如图所示:
点击 选择夹 右键鼠标,菜单中->设置子夹管理 最终效果如下:
在每个子夹上 添加一个 超级列表框 显示对应的群列表、好友列表、讨论组列表,如图所示:
设置列表框:
名称->超级列表框_群列表
类型->报表列表框
整行选择->真
显示表格线->真
是否有检查框->真
单一选择->假
设置报表列:点击超级列表框->右键鼠标->设置报表列
点 向后插入 依次添加 序号、群号、群名 3列 点击确认即可
好友界面和讨论组界面类似,可自行添加超级列表框
继续在右侧 添加一个 选项卡 同上,用于配置界面的分组,添加分页 基础配置、群发配置
主要进行群发配置,支持现在群发 和 定时发送,界面的设计基本上大同小异,在右边的工作箱 选择自己的组件,拖拽到界面上即可,根据本课程 最终设计的界面效果如下
将界面和插件关联
在 程序 页面中 找到IR_SetUp 函数 进行如下修改即可
.版本 2
.子程序 IR_SetUp, , 公开, 当用户按下“设置”执行本函数
载入 (窗口2, , 假)
如备注中所写的,当用户点击 插件的 设置 时,将弹出窗体
此时我们可以进行实际测试,将代码编译成插件 放到乾坤框架进行测试
在易语言编辑器中 选择 编译 -> 编译为指定类型 -> windows 动态链接库
选择要保存的文件路径 即可。本教程直接将其放到 契约框架的 plugin目录下
运行契约框架 -> 载入插件 会看到我们编译的插件,然后点击 启用 按钮,点击 菜单 -> 设置A 则会看到 我们刚开发的窗口 界面
如果你觉得插件上 介绍信息太土 需要在哪里进行修改? 乾坤的IR_Create中进行修改即可
.版本 2
.子程序 IR_Create, 文本型, 公开, 初始化代码可丢在此
' 此处请尽量不要改动info函数,以免出错
插件.名称 = “CleverQQ开发sdk模版” ' 此参数应修改为你自己的插件名字,如用户私自修改插件名称,CleverQQ将会拒绝载入
插件.版本 = “1.0.0” ' 插件版本号
插件.作者 = “作者名” ' 插件作者名,不能以CleverQQ官方名义发布,不能包含IRQQ或CleverQQ
插件.说明 = “这个是一个测试插件 测试:自行修改 这个是一个测试插件” ' 此参数将会显示在CleverQQ插件界面说明处
插件.skey = “8956RTEWDFG3216598WERDF3” ' 这里SKEY请不要做任何更改,关于用途以后再说
插件.SDK = “S3” ' SDK版本号,如不确定拿到的SDK版本不建议修改
置错误提示管理 (&E语言类型异常处理) ' 用于CleverQQ捕获插件异常并及时终止,如不确定能否保证插件稳定性,不建议删除
.如果真 (文件是否存在 (取运行目录 () + “\config\” + 插件.名称) = 假) ' 用于应用目录判断,不建议删除
创建目录 (取运行目录 () + “\config\” + 插件.名称) ' 用于应用目录创建,不建议删除
.如果真结束
应用目录 = 取运行目录 () + “\config\” + 插件.名称 ' 请各位开发者规范插件文件放置目录,更能方便用户使用
返回 (插件信息_处理 (插件))
功能开发
在树形控件 显示所有机器人QQ号码
需要用到的乾坤的API
Api_GetOnLineList() '可以获得所有登录的机器人QQ号
所以变形的函数为如下,获得所有QQ号码 将其加入到树形控件中
.版本 2
.支持库 iext
.子程序 load_qq_lists
.局部变量 name, 文本型
.局部变量 wenbenshuzu, 文本型, , "0"
.局部变量 i, 整数型
name = Api_GetOnLineList ()
wenbenshuzu = 分割文本 (name, #换行符, )
.计次循环首 (取数组成员数 (wenbenshuzu), i)
树型框1.加入项目 (, wenbenshuzu [i], 0, , , , )
.计次循环尾 ()
什么时候调用该方法 更新列表树形框中的机器人个数?
窗口初始化后 按钮触发事件 即可
树形控件 点击机器人号码后 刷新机器人所在群列表
需要的API
Api_GetGroupList() ’将会获得所有群信息 群号 和群名称
树形框 事件: 窗口2->点击树形框,在此次选择加入事件处理子程序 中 选择 检查框状态被改变 ,加入如下代码:
.版本 2
.支持库 iext
.子程序 _树型框1_检查框状态被改变
.参数 表项索引, 整数型
.参数 检查框状态, 整数型
.如果真 (检查框状态 = 1)
robotqq = 树型框1.取项目文本 (表项索引)
flush_qunlist (robotqq)
.如果真结束
.子程序 flush_qunlist
.参数 rqq, 文本型
.局部变量 ret, 文本型
.局部变量 abc, 类_json
.局部变量 i, 整数型
.局部变量 index, 整数型
' 显示群发的群列表
超级列表框_群列表.全部删除 ()
ret = Api_GetGroupList (rqq)
ret = 文本_替换 (ret, , , , “_GetGroupPortal_Callback(”, “”, “);”, “”)
abc.解析 (ret)
abc = abc.取属性 (“data”)
.计次循环首 (abc.成员数 (“group”), i)
index = 超级列表框_群列表.插入表项 (, , , , , )
超级列表框_群列表.置标题 (index, 0, 到文本 (i))
超级列表框_群列表.置标题 (index, 1, abc.取通用属性 (“group[” + 到文本 (i - 1) + “].groupid”))
超级列表框_群列表.置标题 (index, 2, abc.取通用属性 (“group[” + 到文本 (i - 1) + “].groupname”))
.计次循环尾 ()
重点说一下 解析Api_GetGroupList 函数(获得所有群列表),返回的是一个json数据,因此需要进行解析,如上所示
菜单功能 选择所有群号 并且添加到右侧文本框
.版本 2
.支持库 iext
.子程序 _全部选中_被选择
.局部变量 i, 整数型
.计次循环首 (超级列表框_群列表.取表项数 (), i)
超级列表框_群列表.置状态图片 (i - 1, 1)
.计次循环尾 ()
编辑框_关键字_群号.内容 = “0” ' 全部选择群号
菜单功能 取消所有群号选中状态 并且添加到右侧文本框
.版本 2
.支持库 iext
.局部变量 i, 整数型
.计次循环首 (超级列表框_群列表.取表项数 (), i)
超级列表框_群列表.置状态图片 (i - 1, 0)
.计次循环尾 ()
编辑框_关键字_群号.内容 = “”
菜单功能 刷新好友列表
.版本 2
.支持库 iext
.子程序 _刷新列表_好友_被选择
.局部变量 ret, 文本型
.局部变量 abc, 类_json
.局部变量 i, 整数型
.局部变量 index, 整数型
.局部变量 群列表, 文本型
.局部变量 群列表数组, 文本型, , "0"
.局部变量 shuzu, 文本型, , "0"
' 显示群发的群列表
超级列表框_好友.全部删除 ()
群列表 = Api_GetFriendList (获取QQID ())
群列表数组 = 分割文本 (群列表, #换行符, )
.计次循环首 (取数组成员数 (群列表数组), i)
.如果真 (寻找文本 (群列表数组 [i], “<|>”, , 假) > -1)
shuzu = 分割文本 (群列表数组 [i], “<|>”, )
index = 超级列表框_好友.插入表项 (, , , , , )
超级列表框_好友.置标题 (index, 0, 到文本 (i))
超级列表框_好友.置标题 (index, 1, shuzu [1])
超级列表框_好友.置标题 (index, 2, shuzu [2])
.如果真结束
.计次循环尾 ()
Api_GetFriendList 返回的数据是使用<|>进行分割的,因此需要特殊处理
菜单功能 全选好友 和 取消选中
.版本 2
.支持库 iext
.子程序 _全部选中_好友_被选择
.局部变量 i, 整数型
.计次循环首 (超级列表框_好友.取表项数 (), i)
超级列表框_好友.置状态图片 (i - 1, 1)
.计次循环尾 ()
编辑框_关键字_群号.内容 = “0” ' 全部选择群号
.版本 2
.支持库 iext
.子程序 _全部取消_好友_被选择
.局部变量 i, 整数型
.计次循环首 (超级列表框_好友.取表项数 (), i)
超级列表框_好友.置状态图片 (i - 1, 0)
.计次循环尾 ()
编辑框_关键字_群号.内容 = “” ' 全部选择群号
菜单功能 显示讨论组列表
.版本 2
.支持库 iext
.子程序 _刷新列表_讨论_被选择
.局部变量 群列表, 文本型
.局部变量 群列表数组, 文本型, , "0"
群列表 = Api_GetDisGroupList (获取QQID ())
群列表数组 = 分割文本 (群列表, #换行符, )
.计次循环首 (取数组成员数 (群列表数组), i)
index = 超级列表框_好友.插入表项 (, , , , , )
超级列表框_讨论组.置标题 (index, 0, 到文本 (i))
超级列表框_讨论组.置标题 (index, 1, 群列表数组[i])
.计次循环尾 ()
菜单功能 全选讨论组列表 和取消全选
.版本 2
.支持库 iext
.子程序 _全部选中_讨论_被选择
.局部变量 i, 整数型
.计次循环首 (超级列表框_讨论组.取表项数 (), i)
超级列表框_讨论组.置状态图片 (i - 1, 1)
.计次循环尾 ()
编辑框_关键字_群号.内容 = “0” ' 全部选择群号
.子程序 _全部取消_讨论_被选择
.局部变量 i, 整数型
.计次循环首 (超级列表框_讨论组.取表项数 (), i)
超级列表框_讨论组.置状态图片 (i - 1, 0)
.计次循环尾 ()
编辑框_关键字_群号.内容 = “” ' 全部选择群号
至此 群号 、好友、 讨论组、 列表获取工作完成
群号、好友、讨论组 被选择后,将号码 加入到文本框中
选择超级列表框(群号、好友、讨论组) 添加 检查框状态被改变 事件,添加如下代码:
.版本 2
.支持库 iext
.子程序 _超级列表框_群列表_检查框状态被改变
.参数 表项索引, 整数型
.参数 检查框状态, 整数型
.局部变量 qq, 文本型
.如果真 (检查框状态 = 1)
qq = 超级列表框_群列表.取标题 (表项索引, 1)
.如果真 (寻找文本 (编辑框_关键字_群号.内容, qq, , 假) = -1)
编辑框_关键字_群号.内容 = 编辑框_关键字_群号.内容 + qq + “#”
.如果真结束
.版本 2
.支持库 iext
.子程序 _超级列表框_好友_检查框状态被改变
.参数 表项索引, 整数型
.参数 检查框状态, 整数型
.局部变量 qq, 文本型
.如果真 (检查框状态 = 1)
qq = 超级列表框_好友.取标题 (表项索引, 1)
.如果真 (寻找文本 (超级列表框_好友.内容, qq, , 假) = -1)
超级列表框_好友.内容 = 超级列表框_好友.内容 + qq + “#”
.如果真结束
.如果真结束
.子程序 _超级列表框_讨论组_检查框状态被改变
.参数 表项索引, 整数型
.参数 检查框状态, 整数型
.局部变量 qq, 文本型
.如果真 (检查框状态 = 1)
qq = 超级列表框_讨论组.取标题 (表项索引, 0) ' 讨论组 要讨论组id
.如果真 (寻找文本 (超级列表框_讨论组.内容, qq, , 假) = -1)
超级列表框_讨论组.内容 = 超级列表框_好友.内容 + qq + “#”
.如果真结束
注释:判断群号是否已经在文本框 如果不在,将当前群号 加入到文本框
开始发送 按钮的实现
判断配置是否有效
将消息转换成json数据
发送消息处理
详细代码如下:
.版本 2
.支持库 EThread
.支持库 spec
.子程序 _按钮_关键字_开始_被单击
.局部变量 config, 类_json
.局部变量 type, 文本型
.局部变量 MSG, 文本型
.局部变量 subtype, 文本型
.如果真 (is_valid ()) ' 校验是否成功
' 获取配置信息 到json
config.置属性 (“name”, 编辑框_关键字_名称.内容)
config.置属性 (“rqq”, 编辑框_关键字_机器人.内容)
config.置属性 (“status”, 组合框_关键字_开关.取项目文本 (组合框_关键字_开关.现行选中项))
type = “0”
.如果真 (单选框_关键字_群发.选中)
type = “1”
.如果真结束
.如果真 (单选框_关键字_群私聊.选中)
type = “2”
.如果真结束
.如果真 (单选框_关键字_好友.选中)
type = “3”
.如果真结束
.如果真 (单选框_关键字_讨论组.选中)
type = “4”
.如果真结束
config.置属性 (“type”, type)
config.置属性 (“hao”, 编辑框_关键字_群号.内容)
subtype = “1” ' 文本 子类型
MSG = 编辑框_关键字_消息内容.内容
.判断开始 (单选框_关键字_xml.选中)
subtype = “2”
.判断 (单选框_关键字_json.选中)
subtype = “3”
.默认
.判断结束
config.置属性 (“subtype”, subtype)
MSG = 子文本替换 (MSG, #换行符, “[n]”, , , 真)
MSG = 子文本替换 (MSG, “\”, “\\”, , , 真)
config.置属性 (“msg”, MSG)
config.置属性 (“s_time”, 编辑框_关键字_延迟开始.内容)
config.置属性 (“e_time”, 编辑框_关键字_延迟结束.内容)
thread_MSG = config.取数据文本 ()
启动线程 (&dingshi_send_message, 取变量数据地址 (thread_MSG), )
信息框 (“后台开始发送”, 0, , )
.如果真结束
.子程序 dingshi_send_message
.参数 xiabiao, 文本型
.局部变量 config, 类_json
.局部变量 type, 整数型
.局部变量 ST, 整数型
.局部变量 ET, 整数型
.局部变量 hao, 文本型
.局部变量 rqq, 文本型
.局部变量 数量, 整数型
.局部变量 r, 整数型
.局部变量 list, 文本型, , "0"
.局部变量 count, 整数型
.局部变量 j, 整数型
.局部变量 msg, 文本型
.局部变量 ret, 文本型
.局部变量 abc, 类_json
.局部变量 abc1, 类_json
.局部变量 i, 整数型
.局部变量 气泡, 整数型
.局部变量 subtype, 整数型
.局部变量 key, 文本型, , "0"
.局部变量 qq, 文本型
.局部变量 select_qunhao, 文本型
.局部变量 群列表, 文本型
.局部变量 群列表数组, 文本型, , "0"
.局部变量 shuzu, 文本型, , "0"
' QY.加入运行日志 (, , “time1”, 到文本 (xiabiao))
Api_OutPutLog_my (“线程参数 ” + 到文本 (xiabiao))
config.解析 (xiabiao)
type = 到整数 (config.取通用属性 (“type”)) ' 取属性
subtype = 1
.如果真 (config.属性是否存在 (“subtype”))
subtype = 到整数 (config.取通用属性 (“subtype”))
.如果真结束
ST = 到整数 (config.取通用属性 (“s_time”)) ' 开始时间
ET = 到整数 (config.取通用属性 (“e_time”)) ' 结束时间
hao = config.取通用属性 (“hao”) ' 号码
rqq = config.取通用属性 (“rqq”) ' 机器人
msg = config.取通用属性 (“msg”) ' 消息
msg = 获得随机表情消息 (msg) ' 消息转换
is_stop_send = 假
置随机数种子 ()
气泡 = 取随机数 (1, 400) ' 这里假定气泡最多为400,实际不止
.如果真 (取文本长度 (msg) = 0)
返回 ()
.如果真结束
.如果真 (type = 1) ' 群发
.如果 (hao = “0”) ' 所有群号
' QY.取群列表 (到长整数 (rqq), 群列表)
ret = Api_GetGroupList (rqq)
ret = 文本_替换 (ret, , , , “_GetGroupPortal_Callback(”, “”, “);”, “”)
abc.解析 (ret)
abc = abc.取属性 (“data”)
.计次循环首 (abc.成员数 (“group”), i)
ret = abc.取通用属性 (“group[” + 到文本 (i - 1) + “].groupid”)
Api_OutPutLog_my (“发送群号:” + ret)
.判断开始 (subtype = 1)
Api_SendMsg (rqq, #IRC_群, ret, “”, msg, 气泡)
.判断 (subtype = 2)
Api_SendXML (rqq, 1, #IRC_群, ret, “”, msg, 0)
.判断 (subtype = 3)
Api_SendJSON (rqq, 1, #IRC_群, ret, “”, msg)
.默认
.判断结束
程序_延时 (取随机数 (ST, ET), 1)
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.计次循环尾 ()
.否则
list = 分割文本 (hao, “#”, )
数量 = 取数组成员数 (list)
.计次循环首 (数量, r)
.如果真 (取文本长度 (list [r]) > 1) ' 如果取文本长度
ret = list [r]
Api_OutPutLog_my (“发送群号: ” + ret)
.判断开始 (subtype = 1)
Api_SendMsg (rqq, #IRC_群, ret, “”, msg, 气泡)
.判断 (subtype = 2)
Api_SendXML (rqq, 1, #IRC_群, ret, “”, msg, 0)
.判断 (subtype = 3)
Api_SendJSON (rqq, 1, #IRC_群, ret, “”, msg)
.默认
.判断结束
程序_延时 (取随机数 (ST, ET), 1)
.如果真结束
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.计次循环尾 ()
.如果结束
.如果真结束
.如果真 (type = 2) ' 群临时会话
.如果 (hao = “0”) ' 所有群号
ret = Api_GetGroupList (rqq)
ret = 文本_替换 (ret, , , , “_GetGroupPortal_Callback(”, “”, “);”, “”)
abc.解析 (ret)
abc = abc.取属性 (“data”)
.计次循环首 (abc.成员数 (“group”), i)
ret = abc.取通用属性 (“group[” + 到文本 (i - 1) + “].groupid”) ' 群号
Api_OutPutLog_my (“发送群号:” + ret)
ret = Api_GetGroupMemberList (rqq, ret)
abc1.解析 (ret)
abc1.取所有属性名 (key, “members”)
数量 = 取数组成员数 (key)
.计次循环首 (数量, r)
qq = 到文本 (key [r])
Api_OutPutLog_my (“发送QQ:” + qq)
select_qunhao = list [r]
.判断开始 (subtype = 1)
Api_SendMsg (rqq, #IRC_群临时会话, select_qunhao, qq, msg, 0)
.判断 (subtype = 2)
Api_SendXML (rqq, 1, #IRC_群临时会话, select_qunhao, qq, msg, 0)
.判断 (subtype = 3)
Api_SendJSON (rqq, 1, #IRC_群临时会话, select_qunhao, qq, msg)
.默认
.判断结束
程序_延时 (取随机数 (ST, ET), 1)
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.计次循环尾 ()
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.计次循环尾 ()
.否则
list = 分割文本 (hao, “#”, )
数量 = 取数组成员数 (list)
.计次循环首 (数量, r)
.如果真 (取文本长度 (list [r]) > 1) ' 群号为有效
Api_OutPutLog_my (“发送群号:” + list [r])
ret = Api_GetGroupMemberList (rqq, list [r])
abc.解析 (ret)
abc.取所有属性名 (key, “members”)
数量 = 取数组成员数 (key)
.计次循环首 (数量, r)
qq = 到文本 (key [r])
Api_OutPutLog_my (“发送QQ:” + qq)
select_qunhao = list [r]
.判断开始 (subtype = 1)
Api_SendMsg (rqq, #IRC_群临时会话, select_qunhao, qq, msg, 0)
.判断 (subtype = 2)
Api_SendXML (rqq, 1, #IRC_群临时会话, select_qunhao, qq, msg, 0)
.判断 (subtype = 3)
Api_SendJSON (rqq, 1, #IRC_群临时会话, select_qunhao, qq, msg)
.默认
.判断结束
程序_延时 (取随机数 (ST, ET), 1)
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.计次循环尾 ()
.如果真结束
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.计次循环尾 ()
.如果结束
.如果真结束
.如果真 (type = 3) ' 好友
.如果 (hao = “0”) ' 所有群号
' QY.取好友列表 (到长整数 (rqq), 好友列表)
' 数量 = 取数组成员数 (好友列表)
'
' QY.发送好友消息 (到长整数 (rqq), 好友列表 [r].QQID, msg)
' 程序_延时 (取随机数 (ST, ET), 1)
.' 如果真 (is_stop_send)
' 跳出循环 ()
.如果真结束
' 计次循环尾 ()
群列表 = Api_GetFriendList (rqq)
群列表数组 = 分割文本 (群列表, #换行符, )
.计次循环首 (取数组成员数 (群列表数组), i)
.如果真 (寻找文本 (群列表数组 [i], “<|>”, , 假) > -1)
shuzu = 分割文本 (群列表数组 [i], “<|>”, )
Api_OutPutLog_my (“发送好友QQ:” + shuzu [1])
.如果真 (取文本长度 (shuzu [1]) > 0)
.判断开始 (subtype = 1)
Api_SendMsg (rqq, #IRC_好友, “”, shuzu [1], msg, 0)
.判断 (subtype = 2)
Api_SendXML (rqq, 1, #IRC_好友, “”, shuzu [1], msg, 0)
.判断 (subtype = 3)
Api_SendJSON (rqq, 1, #IRC_好友, “”, shuzu [1], msg)
.默认
.判断结束
.如果真结束
程序_延时 (取随机数 (ST, ET), 1)
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.如果真结束
.计次循环尾 ()
.否则
list = 分割文本 (hao, “#”, )
数量 = 取数组成员数 (list)
.计次循环首 (数量, r)
.如果真 (取文本长度 (list [r]) > 1) ' 如果取文本长度
' QY.发送好友消息 (到长整数 (rqq), 到长整数 (list [r]), msg)
Api_OutPutLog_my (“发送好友QQ:” + list [r])
.判断开始 (subtype = 1)
Api_SendMsg (rqq, #IRC_好友, “”, list [r], msg, 0)
.判断 (subtype = 2)
Api_SendXML (rqq, 1, #IRC_好友, “”, list [r], msg, 0)
.判断 (subtype = 3)
Api_SendJSON (rqq, 1, #IRC_好友, “”, list [r], msg)
.默认
.判断结束
程序_延时 (取随机数 (ST, ET), 1)
.如果真结束
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.计次循环尾 ()
.如果结束
.如果真结束
.如果真 (type = 4) ' 讨论组
.如果 (hao = “0”) ' 所有群号
群列表 = Api_GetDisGroupList (rqq)
群列表数组 = 分割文本 (群列表, #换行符, )
.计次循环首 (取数组成员数 (群列表数组), i)
.如果真 (取文本长度 (群列表数组 [i]) > 1) ' 如果取文本长度
.判断开始 (subtype = 1)
Api_SendMsg (rqq, #IRC_讨论组, 群列表数组 [i], “”, msg, 0)
.判断 (subtype = 2)
Api_SendXML (rqq, 1, #IRC_讨论组, 群列表数组 [i], “”, msg, 0)
.判断 (subtype = 3)
Api_SendJSON (rqq, 1, #IRC_讨论组, 群列表数组 [i], “”, msg)
.默认
.判断结束
程序_延时 (取随机数 (ST, ET), 1)
.如果真结束
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.计次循环尾 ()
' QY.取讨论组列表 (到长整数 (rqq), 讨论组列表)
' 数量 = 取数组成员数 (讨论组列表)
.' 计次循环首 (数量, r)
' QY.发送讨论组消息 (到长整数 (rqq), 讨论组列表 [r].讨论组ID, msg)
' 程序_延时 (取随机数 (ST, ET), 1)
.' 如果真 (is_stop_send)
' 跳出循环 ()
.如果真结束
.' 计次循环尾 ()
.否则
list = 分割文本 (hao, “#”, )
数量 = 取数组成员数 (list)
.计次循环首 (数量, r)
.如果真 (取文本长度 (list [r]) > 1) ' 如果取文本长度
.判断开始 (subtype = 1)
Api_SendMsg (rqq, #IRC_讨论组, list [r], “”, msg, 0)
.判断 (subtype = 2)
Api_SendXML (rqq, 1, #IRC_讨论组, list [r], “”, msg, 0)
.判断 (subtype = 3)
Api_SendJSON (rqq, 1, #IRC_讨论组, list [r], “”, msg)
.默认
.判断结束
程序_延时 (取随机数 (ST, ET), 1)
.如果真结束
.如果真 (is_stop_send)
跳出循环 ()
.如果真结束
.计次循环尾 ()
.如果结束
加入定时任务配置
点击执行按钮相关代码
.版本 2
.支持库 iext
.子程序 _按钮_关键字_被单击
.局部变量 a, 日期时间型
.局部变量 jiange, 整数型
.局部变量 config, 类_json
.局部变量 index, 整数型
.局部变量 i, 整数型
.局部变量 tmp, 类_json
.局部变量 keywordsindex, 整数型
.局部变量 isold, 逻辑型
.局部变量 kaiguan, 文本型
.局部变量 t_name, 文本型
.局部变量 type, 文本型
.局部变量 MSG, 文本型
.局部变量 c, 文本型
.局部变量 name, 文本型
.局部变量 subtype, 文本型
.如果真 (is_valid ())
kaiguan = 组合框_关键字_开关.取项目文本 (组合框_关键字_开关.现行选中项)
config.置属性 (“name”, 编辑框_关键字_名称.内容)
config.置属性 (“rqq”, 编辑框_关键字_机器人.内容)
config.置属性 (“status”, 组合框_关键字_开关.取项目文本 (组合框_关键字_开关.现行选中项))
type = “0”
.如果真 (单选框_关键字_群发.选中)
type = “1”
t_name = “群发”
.如果真结束
.如果真 (单选框_关键字_群私聊.选中)
type = “2”
t_name = “群临时会话”
.如果真结束
.如果真 (单选框_关键字_好友.选中)
type = “3”
t_name = “好友”
.如果真结束
.如果真 (单选框_关键字_讨论组.选中)
type = “4”
t_name = “讨论组”
.如果真结束
config.置属性 (“type”, type)
config.置属性 (“hao”, 编辑框_关键字_群号.内容)
subtype = “1” ' 文本 子类型
MSG = 编辑框_关键字_消息内容.内容
.判断开始 (单选框_关键字_xml.选中)
subtype = “2”
.判断 (单选框_关键字_json.选中)
subtype = “3”
.默认
.判断结束
config.置属性 (“subtype”, subtype)
MSG = 子文本替换 (MSG, #换行符, “[n]”, , , 真)
MSG = 子文本替换 (MSG, “\”, “\\”, , , 真)
config.置属性 (“msg”, MSG)
config.置属性 (“s_time”, 编辑框_关键字_延迟开始.内容)
config.置属性 (“e_time”, 编辑框_关键字_延迟结束.内容)
' a = 时间_JSON转为时间 (到文本 (取年份 (取现行时间 ())) + “-” + 到文本 (取月份 (取现行时间 ())) + “-” + 到文本 (取日 (取现行时间 ())) + “ ” + 编辑框_关键字_时.内容 + “:” + 编辑框_关键字_分.内容 + “:” + 编辑框_关键字_秒.内容 + “.777Z”)
a = 到时间 (到文本 (取年份 (取现行时间 ())) + “-” + 到文本 (取月份 (取现行时间 ())) + “-” + 到文本 (取日 (取现行时间 ())) + “ ” + 编辑框_关键字_时.内容 + “:” + 编辑框_关键字_分.内容 + “:” + 编辑框_关键字_秒.内容)
config.置属性 (“n_time”, 时间_到时间戳 (a, 真))
jiange = 60
.如果真 (单选框_关键字_时.选中)
jiange = 60
.如果真结束
.如果真 (单选框_关键字_天.选中)
jiange = 24 × 60
.如果真结束
.如果真 (单选框_关键字_自定义.选中)
jiange = 到整数 (编辑框_关键字_分钟.内容)
.如果真结束
config.置属性 (“jiange”, 到文本 (jiange))
isold = 假
.计次循环首 (取数组成员数 (keywordsrules), i)
tmp.清除 ()
tmp.解析 (keywordsrules [i])
.如果真 (tmp.取通用属性 (“name”) = 编辑框_关键字_名称.内容)
keywordsindex = i ' 保存下标
index = i - 1 ' 列表框的下标
' 更新操作
isold = 真
跳出循环 ()
.如果真结束
.计次循环尾 ()
' 是否是新规则 还是老规则更新
.如果 (isold)
keywordsrules [keywordsindex] = config.取数据文本 () ' 替换掉原来的
.否则
加入成员 (keywordsrules, config.取数据文本 ())
index = 超级列表框_关键字_任务.插入表项 (, , , , , )
.如果结束
.如果 (kaiguan = “开”)
超级列表框_关键字_任务.置状态图片 (index, 1)
.否则
超级列表框_关键字_任务.置状态图片 (index, 0) ' 是否选中 检查框
.如果结束
超级列表框_关键字_任务.置标题 (index, 0, 到文本 (编辑框_关键字_名称.内容))
超级列表框_关键字_任务.置标题 (index, 1, kaiguan) ' 选中项 开/关
超级列表框_关键字_任务.置标题 (index, 2, t_name) ' 类型名称
超级列表框_关键字_任务.置标题 (index, 3, 编辑框_关键字_群号.内容) ' 群号
超级列表框_关键字_任务.置标题 (index, 4, 到文本 (jiange)) ' 间隔时间
c = “”
.计次循环首 (取数组成员数 (keywordsrules), i)
tmp.清除 ()
tmp.解析 (keywordsrules [i])
c = c + tmp.取数据文本 () + #换行符
' 保存到文件
.计次循环尾 ()
' 保存到文件
写到文件 (global_file_name, 到字节集 (c))
信息框 (“保存成功”, 0, “”, )
超级列表框(任务) 规则管理
修改规则开关
规则的超级列表框 检查框状态被改变 改变时,将随时调整规则的开关状态
.版本 2
.支持库 iext
.子程序 _超级列表框_关键字_任务_检查框状态被改变
.参数 表项索引, 整数型
.参数 检查框状态, 整数型
.局部变量 name, 文本型
.局部变量 tmp, 类_json
.局部变量 i, 整数型
.如果 (检查框状态 = 1)
超级列表框_关键字_任务.置标题 (表项索引, 1, “开”)
.否则
超级列表框_关键字_任务.置标题 (表项索引, 1, “关”)
.如果结束
name = 超级列表框_关键字_任务.取标题 (表项索引, 0) ' 取标题 修改规则
.计次循环首 (取数组成员数 (keywordsrules), i)
tmp.清除 ()
tmp.解析 (keywordsrules [i])
.如果真 (tmp.取通用属性 (“name”) = name)
.如果 (检查框状态 = 1)
tmp.置属性 (“status”, “开”)
.否则
tmp.置属性 (“status”, “关”)
.如果结束
跳出循环 ()
.如果真结束
.计次循环尾 ()
只进行规则的当前状态的改变,并未保存到记录中
删除规则
在规则超级列表框上 添加一个菜单 删除对应规则
删除按钮代码如下
.版本 2
.支持库 iext
.局部变量 i, 整数型
.局部变量 c, 文本型
.局部变量 tmp, 类_json
.局部变量 name, 文本型
.如果真 (信息框 (“是否删除规则”, #是否钮, , ) = #是钮)
name = 超级列表框_关键字_任务.取标题 (超级列表框_关键字_任务.现行选中项, 0)
.计次循环首 (取数组成员数 (keywordsrules), i)
tmp.清除 ()
tmp.解析 (keywordsrules [i])
.如果真 (tmp.取通用属性 (“name”) = name)
删除成员 (keywordsrules, i, 1)
超级列表框_关键字_任务.删除表项 (超级列表框_关键字_任务.现行选中项)
跳出循环 ()
.如果真结束
.计次循环尾 ()
c = “”
.计次循环首 (取数组成员数 (keywordsrules), i)
tmp.清除 ()
tmp.解析 (keywordsrules [i])
c = c + tmp.取数据文本 () + #换行符
' 保存到文件
.计次循环尾 ()
' 保存到文件
写到文件 (global_file_name, 到字节集 (c))
信息框 (“成功删除规则”, 0, , )
清空 按钮代码
.版本 2
.支持库 iext
.子程序 _任务清空_被选择
.局部变量 name, 文本型
.如果真 (信息框 (“确认要删除所有设置么”, #是否钮, , ) = #是钮)
清除数组 (keywordsrules)
超级列表框_关键字_任务.全部删除 () ' 全部删除
.如果真 (文件是否存在 (global_file_name))
删除文件 (global_file_name)
.如果真结束
规则超级列表框 编辑规则
添加一个左键点击事件,代码如下:
.版本 2
.支持库 iext
.子程序 _任务编辑_被选择
.局部变量 name, 文本型
.局部变量 config, 类_json
.局部变量 i, 整数型
.局部变量 c, 文本型
name = 超级列表框_关键字_任务.取标题 (超级列表框_关键字_任务.现行选中项, 0)
.计次循环首 (取数组成员数 (keywordsrules), i)
config.清除 ()
config.解析 (keywordsrules [i])
.如果真 (config.取通用属性 (“name”) = name)
编辑框_关键字_名称.内容 = config.取通用属性 (“name”)
编辑框_关键字_机器人.内容 = config.取通用属性 (“rqq”)
.如果真 (config.取通用属性 (“type”) = “1”)
单选框_关键字_群发.选中 = 真
.如果真结束
.如果真 (config.取通用属性 (“type”) = “2”)
单选框_关键字_群私聊.选中 = 真
.如果真结束
.如果真 (config.取通用属性 (“type”) = “3”)
单选框_关键字_好友.选中 = 真
.如果真结束
.如果真 (config.取通用属性 (“type”) = “4”)
单选框_关键字_讨论组.选中 = 真
.如果真结束
编辑框_关键字_群号.内容 = config.取通用属性 (“hao”)
编辑框_关键字_消息内容.内容 = config.取通用属性 (“msg”)
编辑框_关键字_延迟开始.内容 = config.取通用属性 (“s_time”)
编辑框_关键字_延迟结束.内容 = config.取通用属性 (“e_time”)
跳出循环 ()
.如果真结束
.计次循环尾 ()
c = “”
.计次循环首 (取数组成员数 (keywordsrules), i)
config.清除 ()
config.解析 (keywordsrules [i])
c = c + config.取数据文本 () + #换行符
' 保存到文件
.计次循环尾 ()
规则 超级列表框 右键添加菜单
.版本 2
.子程序 _超级列表框_关键字_任务_右键单击表项
弹出菜单 (任务菜单, , )
至此,核心的界面功能 就开发完成了 接下来开发新人入群事件
定时器开发
需要添加个定时器,每10秒执行一次所有规则,判断是否需要进行发送,在插件初始化事件 _eventStartup中添加如下代码
SetTimer (0, “timer”, 10000, &Start_time) ' 单位毫秒 10s
使用API功能添加一个定时器,回调事件 在Start_time中
.版本 2
.支持库 EThread
.支持库 spec
.子程序 Start_time, , , 开始时钟判断
.局部变量 i, 整数型
.局部变量 tmp, 类_json
.局部变量 msg, 文本型
.局部变量 c, 文本型
.局部变量 is_change, 逻辑型
is_change = 假
.计次循环首 (取数组成员数 (keywordsrules), i)
tmp.清除 ()
tmp.解析 (keywordsrules [i])
.如果真 (tmp.取通用属性 (“status”) = “开”)
.如果真 (到长整数 (时间_到时间戳 (, 真)) > 到长整数 (tmp.取通用属性 (“n_time”)))
msg = tmp.取数据文本 ()
is_change = 真
' 时间进行增加
tmp.置属性 (“n_time”, 到文本 (到长整数 (时间_到时间戳 (, 真)) + 到长整数 (tmp.取通用属性 (“jiange”)) × 60))
keywordsrules [i] = tmp.取数据文本 ()
' QY.加入运行日志 (, , “time”, 到文本 (i))
Api_OutPutLog_my (“检测QQ是否在线” + tmp.取通用属性 (“rqq”))
.如果真 (寻找文本 (Api_GetOnLineList (), tmp.取通用属性 (“rqq”), , 假) > 0) ' 账号状态是在线 发送
启动线程 (&dingshi_send_message, 取变量数据地址 (keywordsrules [i]), )
Api_OutPutLog_my (“检测QQ在线” + tmp.取通用属性 (“rqq”))
.如果真结束
.如果真结束
.如果真结束
.计次循环尾 ()
.如果真 (is_change)
c = “”
.计次循环首 (取数组成员数 (keywordsrules), i)
tmp.清除 ()
tmp.解析 (keywordsrules [i])
c = c + tmp.取数据文本 () + #换行符
' 保存到文件
.计次循环尾 ()
' 保存到文件
写到文件 (global_file_name, 到字节集 (c))
.如果真结束
.如果真 (是否已创建 (窗口2))
窗口2.编辑框_关键字_时.内容 = 到文本 (取小时 (取现行时间 ()))
窗口2.编辑框_关键字_分.内容 = 到文本 (取分钟 (取现行时间 ()))
窗口2.编辑框_关键字_秒.内容 = 到文本 (取秒 (取现行时间 ()))
.如果真结束
至此,我们需要的 基础功能 基本实现,定时器不断循环判断是否有需要发送的消息
插件初始化配置 加载规则文件
_eventStartup 事件中添加初始化代码
.版本 2
global_file_name = 应用目录 + “qunfa_config.txt”
清除数组 (keywordsrules) ' 初始化数组
.如果真 (文件是否存在 (global_file_name))
content = 到文本 (读入文件 (global_file_name))
清除数组 (array_list)
array_list = 分割文本 (content, #换行符, )
.计次循环首 (取数组成员数 (array_list), i)
.如果真 (取文本长度 (array_list [i]) > 4) ' 过滤掉空行
加入成员 (keywordsrules, array_list [i])
.如果真结束
.计次循环尾 ()
至此基本功能开发完成,整体流程ok了,我们接下来需要做一些调优
支持随机变量
让发送的消息支持更多随机变量,可以大大降低被封号的风险
代码如下:
.版本 2
.子程序 获得随机表情消息, 文本型
.参数 message, 文本型
.局部变量 ret, 文本型
ret = 子文本替换 (message, “[Time]”, 时间_到文本 (, 1, ), , , 真)
ret = 子文本替换 (ret, “[Rface]”, “[Face” + 到文本 (取随机数 (1, 212)) + “.gif]”, , , 真)
ret = 子文本替换 (ret, “[Num]”, 文本_取随机数字 (取随机数 (1, 20), ), , , 真)
ret = 子文本替换 (ret, “[Hanzi]”, 文本_取随机汉字 (取随机数 (5, 20), 0), , , 真)
ret = 子文本替换 (ret, “[Zimu]”, 文本_取随机字母 (取随机数 (1, 20), 2), , , 真)
ret = 子文本替换 (ret, “[n]”, #换行符, , , 真)
返回 (ret)
至此本次教程主要代码就逐个讲解完成,接下来进入我们最关键的环节,编译生成dll插件和调试
调试这个工作没有办法进行教学,因为每个人环境不同,只能根据易语言提示的报错信息进行修改相关代码,最终变成可以运行的,就可以了。
编译插件发布
在最终发布插件时,我们需要进行静态编译插件,因为只有静态编译才会将插件用的库文件打包到一起,防止插件放到别的电脑上,因缺少库文件 而无法运行。
静态编译很简单:
易语言编译器 编译->静态编译为指定类型->windows动态链接库 ,选择保存插件的位置即可完成编译。
静态编译后的插件文件会比其他编译的文件大一些。
联系我们
如有其他问题或发现教程bug 欢迎进入我们的Q群交流:QQ机器人开发交流群
本课程完整源代码售价88元
本课程为作者精心打造,所有代码都是利用业余时间码字出来,如果上面公布的代码还不够,可以赞助我们,获得本教程完整代码 售价88元
包括:本课程所有源代码+精易模块
购买链接
乾坤-QQ群发器助手源代码