【原创】乾坤机器人发消息源代码-新手|入门教程

简介

本教程主要实现:

QQ群发器:
获取和展示Q群列表
获取和展示好友列表
获取和展示讨论组列表
定时群发的配置

说明:
1.支持契约乾坤多Q框架
2.支持内置变量 防止消息内容相同 被屏蔽
3.使用易语言进行开发,需要大家有基础或者需要有恒心坚持看完

学习内容

通过本教程主要学习:

契约群发、私聊 功能的使用
发送内容: 文本、图片、卡片
定时功能的使用

联系我们

如果你有机器人开发问题或有需求不会开发,可与我们进行联系
QQ机器人开发交流群

声明

本教程非乾坤官方教程,为作者学习易语言过程的知识总结,将主要内容整理、汇总后,形成本教程。

致力于进行技术交流,帮助新人快速入门,少走弯路。

请在遵守中华人民共和国法律、腾讯相关规定和乾坤框架相关说明下进行使用

如您使用本技术,进行包括但不限于如下行为,软件作者并不知情,不承担任何法律风险
1.违法行为
2.违法腾讯规定
3.违法乾坤框架规定

插件下载地址

已经做好的插件下载地址:
乾坤-良驹QQ群发助手
界面效果如下:

乾坤-良驹QQ群发助手.png

教程内容

环境准备

易语言环境安装教程

使用易语言软件,打开 sdk模版20191104.e 文件(我使用的是该版本,只要是从官方下载的sdk均可),是一个空的sdk

开始开发

界面制作

鼠标点击 窗口 -> 右键 -> 点击 插入新窗口 ,进入窗口操作界面,如下图

2.创建新窗口.png

先在 新建窗口上,放一个树形控件 存放所有登录的QQ机器人号码,鼠标点击右侧 组件的 树形 控件,然后在窗口 界面点击鼠标左键 完成树形控件添加


3 添加树形 控件.png

点击 树形 控件,左侧 将会看到很多 树形配置,暂时我们只需要修改 是否有检查框 将其修改为 真,这样树形控件 中的内容前面 会多个复选框 供选择,进而进行其他操作

为了可以显示群列表、好友列表、讨论组列表等,因此添加一个 选择夹 ,如图所示:


4.选择夹使用.png

点击 选择夹 右键鼠标,菜单中->设置子夹管理 最终效果如下:

5.选择夹配置.png

在每个子夹上 添加一个 超级列表框 显示对应的群列表、好友列表、讨论组列表,如图所示:


6.群发超级列表框.png

设置列表框:
名称->超级列表框_群列表
类型->报表列表框
整行选择->真
显示表格线->真
是否有检查框->真
单一选择->假

设置报表列:点击超级列表框->右键鼠标->设置报表列
点 向后插入 依次添加 序号、群号、群名 3列 点击确认即可

好友界面和讨论组界面类似,可自行添加超级列表框

继续在右侧 添加一个 选项卡 同上,用于配置界面的分组,添加分页 基础配置、群发配置

主要进行群发配置,支持现在群发 和 定时发送,界面的设计基本上大同小异,在右边的工作箱 选择自己的组件,拖拽到界面上即可,根据本课程 最终设计的界面效果如下

7.最终界面设计完成.png

将界面和插件关联

在 程序 页面中 找到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群发器助手源代码

良心开发工作室介绍

本工作室自2019年12月1日成立,主要由对编程充满热情的学生组成,致力于在提高自身编程能力的同时,帮助您解决需求。

如果您有关于程序开发相关需求,可以联系我们工作室,将根据我们的课程安排,抽时间帮您开发,您可以赞助我们或也可以免费提需求。

良心论坛地址

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335