接上篇,實時獲取到微信聊天消息,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