接上篇,实时获取到微信聊天消息,hook数据库插入操作:https://blog.csdn.net/weixin_42127613/article/details/81840536
收到消息了,那么现在就要回复消息。我们暂时只考虑文本消息回复。
消息的回复,要调用微信自身的方法去执行。我们要构造回复内容,然后用Xposed去执行微信的回复方法,从而达到自动回复的效果。
新建一个类WechatUtils,专用于微信的一些执行方法。在类中添加文本消息回复方法replyTextMessage,调用此方法,实现消息回复。
后期我们还要优化主界面,所以我们将hook相关的方法,都放到同一个包中。在主包中新建一个包(package):xposed,将WechatUtils类建立到里面。如下图所示。
回复文本消息的方法。可以参考以下2篇文章,我也是参考的看雪里的文章。
看雪论坛文章:https://bbs.pediy.com/thread-228441.htm
简书上文章:https://www.jianshu.com/p/8d0d0b52bec6
这里要注意的是,微信的安装包做了混淆处理,每个版本即使是相同的功能,也有可能是不同的类名和方法名。所以在hook和调用执行时,一般都是针对特定的版本。
目前我针对的是安卓版V6.6.7,目前为最新版。等你看这篇文章时,可能就不一定了。
最终经测试,采用看雪文章链接的方法,针对微信V6.6.7版本,文本消息的回复代码如下。只要传递接收者和回复内容即可。
//回复文本消息
public static void replyTextMessage(XC_LoadPackage.LoadPackageParam loadPackageParam,
String strContent, final String strChatroomId) {
XposedBridge.log("准备回复消息内容:content:" + strContent + ",chatroomId:" + strChatroomId);
if (strContent == null || strChatroomId == null
|| strContent.length() == 0 || strChatroomId.length() == 0) {
return;
}
//构造new里面的参数:l iVar = new i(aao, str, hQ, i2, mVar.cvb().fD(talkerUserName, str));
Class<?> classiVar = XposedHelpers.findClassIfExists("com.tencent.mm.modelmulti.i", loadPackageParam.classLoader);
Object objectiVar = XposedHelpers.newInstance(classiVar,
new Class[]{String.class, String.class, int.class, int.class, Object.class},
strChatroomId, strContent, 1, 1, new HashMap<String, String>() {{
put(strChatroomId, strChatroomId);
}});
Object[] objectParamiVar = new Object[]{objectiVar, 0};
//创建静态实例对象au.DF(),转换为com.tencent.mm.ab.o对象
Class<?> classG = XposedHelpers.findClassIfExists("com.tencent.mm.kernel.g", loadPackageParam.classLoader);
Object objectG = XposedHelpers.callStaticMethod(classG, "Eh");
Object objectdpP = XposedHelpers.getObjectField(objectG, "dpP");
//查找au.DF().a()方法
Class<?> classDF = XposedHelpers.findClassIfExists("com.tencent.mm.ab.o", loadPackageParam.classLoader);
Class<?> classI = XposedHelpers.findClassIfExists("com.tencent.mm.ab.l", loadPackageParam.classLoader);
Method methodA = XposedHelpers.findMethodExactIfExists(classDF, "a", classI, int.class);
//调用发消息方法
try {
XposedBridge.invokeOriginalMethod(methodA, objectdpP, objectParamiVar);
XposedBridge.log("invokeOriginalMethod()执行成功");
} catch (Exception e) {
XposedBridge.log("调用微信消息回复方法异常");
XposedBridge.log(e);
}
}
在收到消息后,我们就回复。由于是测试,我们就把原内容直接回过去,在前面加上“回复”2个字。
回复的时机,就在收到消息后。因此我们在hook到新聊天消息后,调用回复方法,进行回复。
在回复前,还要做一些简单判断。
- 自己发的消息,不能回复。否则会陷入死循环。通过isSend值进行判断,为1时表示是自己发送。
- 暂时只回复好友消息。所以对群消息和公众号消息,过滤掉。通过talker进行判断,以“@chatroom”结尾的是群消息,以“gh_”开头的是公众号消息。
那么收到消息后,调用消息回复这部分的代码如下:
//提取消息内容
//1:表示是自己发送的消息
int isSend = contentValues.getAsInteger("isSend");
//消息内容
String strContent = contentValues.getAsString("content");
//说话人ID
String strTalker = contentValues.getAsString("talker");
//收到消息,进行回复(要判断不是自己发送的、不是群消息、不是公众号消息,才回复)
if (isSend != 1 && !strTalker.endsWith("@chatroom") && !strTalker.startsWith("gh_")) {
WechatUtils.replyTextMessage(loadPackageParam, "回复:" + strContent, strTalker);
}
现在编译、运行、重启,进行测试。
看看运行效果:可以看到已经自动回复了。
查看运行日志。成功执行了各个函数和方法。
至此,我们顺利的测试并完成了消息的自动回复功能。
当然,作为一个有志向有理想的机器人,不可能每次都这么傻X的回复,我们要更加智能的回复。由此,接下来,就是要完成根据关键词进行匹配,来回复相应的内容。
到目前为止,实际上已经解决了微信聊天机器人的两大难点:消息的获取、与消息的回复。剩下要做的功能,其实都是围绕这两大功能服务。
作为一个自己用的东西,基本凑合,稍微再改改,就能用了。但是作为一个产品,核心的难点功能可能只占20%,剩下的还有80%功能,是为这20%的核心服务的。接下来我们就要去完成这80%的工作。
目前代码已提交GitHub:https://github.com/dalu2048/WeChatGenius.git
下一篇,将创建主界面,以及在主界面中对模块是否激活进行判断。
连接:https://blog.csdn.net/weixin_42127613/article/details/81843771