1.背景
这几天有些无聊,就想着自己倒腾个QQ机器人。其实也挺好实现的,主要接口都有人做好了,剩下的功能全靠自己想和爬虫实现了。本文的参考链接如下:参考一、参考二、参考三。还要感谢插件的作者,把接口都写好了。
2.需要准备的东西
- jdk1.8+。
- linux服务器(windows也行),也可以在本地环境,但是那样每次自己启动很麻烦。
- coolq及插件。
3.开工
- 如果你买的linux服务器。先在根目录下创建data/coolq-data目录,然后防火墙添加一个规则暴露一个端口(教程用的8001),其他步骤看这里,注意要让coolq后台运行,否则关掉终端就退出了。
- 如果你是windows,那么直接官网下载即可,其他步骤也类似。
- 下载jar包和coolq的插件这里。
- 通过winCSP把插件(org.ruiko.lemoc.cpk)传到服务器的coolq目录下的app目录。
- 上传完插件之后重载应用。设置时勾选自启动,并把本机连接的√去掉(发方便本地测试)。然后添加防火墙规则开放25303号端口。最后启用lemoc的Server。
- 删除之前的docker容器,增加一个映射端口。其中VNC_PASSWORD是远程连接密码,COOLQ_ACCOUNT是登录的QQ号。
docker rm $(docker ps -aq)
docker run --name=coolq -d -p 8001:9000 -p 25303:25303 -v /data/coolq-data:/home/user/coolq -e VNC_PASSWD=******* -e COOLQ_ACCOUNT=1532152713 coolq/wine-coolq
- 导入下载的jar包开始写代码。
- MyKQWebClient.java。继承自KQWebClient 然后重写了几个主要方法。
import java.net.URI;
import com.alibaba.fastjson.JSONObject;
import com.mumu.webclient.KQWebClient;
public class MyKQWebClient extends KQWebClient {
public MyKQWebClient(URI serverURI) {
super(serverURI);
}
/**
* 发送私聊
*/
@Override
public void sendPrivateMSG(String qq, String msg) {
try {
Thread.sleep(10L);
} catch (InterruptedException var4) {
var4.printStackTrace();
}
JSONObject sendMsg = new JSONObject();
sendMsg.put("act",106);
sendMsg.put("QQID",qq);
sendMsg.put("msg",msg);
super.send(sendMsg.toJSONString());
}
/**
* 发送群消息
*/
@Override
public void sendGroupMSG(String qq, String groupid, String msg, Boolean isAT) {
try {
Thread.sleep(10L);
} catch (InterruptedException var4) {
var4.printStackTrace();
}
JSONObject sendMsg = new JSONObject();
sendMsg.put("act",101);
sendMsg.put("groupid",groupid);
sendMsg.put("msg",msg);
super.send(sendMsg.toJSONString());
}
public void sendPraise(String qq) {
super.sendPraise(qq);
}
}
- MyQQAdapter.java。适配器,其他都写在注释里。不过public void RE_ASK_ADDFRIEND(AddFriends msg)、public void RE_ASK_ADDGROUP(ADDGroupExample msg)方法经过测试并没有被自动调用,其他在触发相应事件时会被调用。
import com.mumu.listenner.KQMSGAdapter;
import com.mumu.msg.ADDGroupExample;
import com.mumu.msg.AddAdmin;
import com.mumu.msg.AddFriends;
import com.mumu.msg.DeleteAdmin;
import com.mumu.msg.RE_MSG_Forum;
import com.mumu.msg.RE_MSG_Group;
import com.mumu.msg.RE_MSG_Private;
public class MyQQAdapter extends KQMSGAdapter {
private MyKQWebClient kqWebClient;
MyQQAdapter(MyKQWebClient kqWebClient) {
this.kqWebClient = kqWebClient;
}
/**
* 私聊消息
*/
public void Re_MSG_Private(RE_MSG_Private msg) {
System.out.println("接收到私聊信息 from:" + msg.getFromqq() + " \t msg:" + msg.getMsg());
kqWebClient.sendPrivateMSG(msg.getFromqq(), "我只是个robot[CQ:face,id=14]");
}
/**
* 讨论组消息
*/
public void RE_MSG_FORUM(RE_MSG_Forum msg) {
System.out.println("接收到消息 groupName:" + msg.getFromQQ() + "qq:" + msg.getFromQQ() + "msg:" + msg.getMsg());
}
/**
* 群聊消息
*/
public void RE_MSG_Group(RE_MSG_Group msg) {
String message = msg.getMsg().trim();
System.out.println("群:" + msg.getFromGroup() + " qq:" + msg.getFromQQ() + " msg:" + msg.getMsg());
String[] argv = message.split(" ");
if (argv[0].equals("##")) {
if (argv[1].equals("test")) {
kqWebClient.sendGroupMSG(msg.getFromQQ(), msg.getFromGroup(), "[CQ:at,qq=" + msg.getFromQQ() + "]" + " 我在呢", true);
} else if (argv[1].equals("help")) {
kqWebClient.sendGroupMSG(msg.getFromQQ(), msg.getFromGroup(), "[CQ:at,qq=" + msg.getFromQQ() + "] "
+ "以\"## \"开头即可和我聊天,目前支持命令:\n"
+ "1.## test 测试我是否正常运行\n"
+ "2.## help 查看帮助\n"
+ "3.## en word 查单词(en后面的最后一个空格后面的单词),输出有道的url\n"
+ "4.如需其他请联系管理员QQ:1532152713\n"
+ "例如:## test", true);
} else if(argv[1].equals("en")) {
kqWebClient.sendGroupMSG(msg.getFromQQ(), msg.getFromGroup(), "[CQ:at,qq=" + msg.getFromQQ() + "] " + message.substring(message.lastIndexOf(' ') + 1, message.length()) +
":http://www.youdao.com/w/eng/" + message.substring(message.lastIndexOf(' ') + 1, message.length()), true);
} else {
kqWebClient.sendGroupMSG(msg.getFromQQ(), msg.getFromGroup(), "[CQ:at,qq=" + msg.getFromQQ() + "] " + "命令格式错误\" ## help\"命令可以查看帮助", true);
}
}
}
/**
* 群成员减少
*/
public void RE_EXAMPLE_DEMBER(DeleteAdmin msg) {
System.out.println("群成员减少");
String type = msg.getSubType();
if(type.equals("1")) {
kqWebClient.sendGroupMSG(msg.getBeingOperateQQ(), msg.getFromGroup(), "有人离开了本群,群地位+1", true);
} else if(type.equals("2")) {
kqWebClient.sendGroupMSG(msg.getBeingOperateQQ(), msg.getFromGroup(), "有人被管理员移出本群,群地位+1", true);
}
}
/**
* 群成员添加
*/
public void RE_EXAMPLE_AMEMBER(AddAdmin msg) {
System.out.println("群成员添加");
kqWebClient.sendGroupMSG(msg.getBeingOperateQQ(), msg.getFromGroup(), "[CQ:at,qq=" + msg.getBeingOperateQQ() + "] 欢迎加入本群,我是robot。通过\"## help\"可以查看帮助。群地位-1。", true);
kqWebClient.sendPraise(msg.getBeingOperateQQ());
}
/**
* 请求添加好友
*/
public void RE_ASK_ADDFRIEND(AddFriends msg) {
System.out.println(msg.getFromQQ() + "请求添加好友");
}
/**
* 请求添加群
*/
public void RE_ASK_ADDGROUP(ADDGroupExample msg) {
System.out.println("请求添加群");
}
}
- KQClient.java。
import java.net.URI;
public class KQClient {
private static MyKQWebClient kqWebClient;
public static void runClient(String host){
try {
if(kqWebClient == null){
kqWebClient = new MyKQWebClient(new URI(host));
}
MyQQAdapter myQQAdapter = new MyQQAdapter(kqWebClient);
kqWebClient.addQQMSGListenner(myQQAdapter);
}catch (Exception e){
System.err.println("init KQ client fail e:"+e.getMessage());
e.printStackTrace();
}
}
}
- Main.java
public class Main {
public static void main(String[] args) {
KQClient.runClient("ws://127.0.0.1:25303");
}
}
- 打包放到服务器。选择好启动函数,然后打包成Runnable jar再通过WinCSP软件放到服务器。
- 服务器上后台运行这个jar文件。java -jar xxx.jar &。
4.更多
- 插件的作者及详细接口说明这里。