編寫微信聊天機器人5《聊天精靈WeChatGenius》:測試文本消息自動回覆功能。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章