vasani-arpit / WBOT

A simple Web based BOT for WhatsApp™ in NodeJS 😜. Working as of 📅 Feb 4th, 2024
Other
986 stars 314 forks source link

Reply with quotation & function response in bot.json #209

Closed ghost closed 3 years ago

ghost commented 3 years ago

1. Reply with quotation

Quote which message with a response.

2. Function response in bot.json

An example :

{
  "bot" : [
      {
          "exact": ["upper"],
          "func": function (message) {
             // Do with message
          }
      }
  ]

}
vasani-arpit commented 3 years ago

As the file is json we can't create function in it. https://www.json.org/json-en.html

I like the idea of exposing a function. I will look into a way this can be implement differently.

ghost commented 3 years ago

As the file is json we can't create function in it. https://www.json.org/json-en.html

I like the idea of exposing a function. I will look into a way this can be implement differently.

Yes, in some cases. it's necessary to do data processing to create anything other than plain text responses.

vasani-arpit commented 3 years ago

In that case use webhooks. They will give you complete control over the bot. if you want only webhook to work then remove all rules from bot.json. if you want to keep both (bot rules and webhook) on then you can do that as well.

ghost commented 3 years ago

In that case use webhooks. They will give you complete control over the bot. if you want only webhook to work then remove all rules from bot.json. if you want to keep both (bot rules and webhook) on then you can do that as well.

Maybe WebHook only for data processing then return as a clear result. But it's doesn't have to control WAPI to perform another way in reply a message.

vasani-arpit commented 3 years ago

Here. When you send a response to webhook you can reply to the whatsapp user. Quoting a message feature is not there but it can be easily added via a json property name "quoteMessage":"id_xxxxxxxx_WHATSAPP_MESSAGE_ID" in the webhook reponse.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

ghost commented 3 years ago

I try to use WAPI.ReplyMessage and passing different idMessage to that function.

message.chatId
message.id
message.chat.lastReceivedKey._serialized
message.chatId._serialized

I've got following error :

TypeError: messageObject.value is not a function
    at Object.window.WAPI.ReplyMessage (/WhatsApp/WBOT-0.15.1/src/WAPI.js:696:35)
    at Object.chat (/WhatsApp/WBOT-0.15.1/src/inject.js:14:22)
    at /WhatsApp/WBOT-0.15.1/src/inject.js:73:63
    at Array.forEach (<anonymous>)
    at /WhatsApp/WBOT-0.15.1/src/inject.js:66:30

So I made change the WAPI.js code

window.WAPI.ReplyMessage = function (idMessage, message, done) {
    var messageObject = window.Store.Msg.get(idMessage);
...

to

window.WAPI.ReplyMessage = function (idMessage, message, done) {
    var messageObject = window.Store.Msg.find(idMessage);
...

then another error appear

TypeError: Cannot destructure property `linkPreview` of 'undefined' or 'null'.
    at https://web.whatsapp.com/bootstrap_main.ef6b5ea9cb55cc0c4253.js:2:30276
    at Object.t.sendTextMsgToChat [as SendTextMsgToChat] (https://web.whatsapp.com/bootstrap_main.ef6b)
    at Object.window.Store.Chat.modelClass.sendMessage (/WhatsApp/WBOT-0.15.1/src)
    at Object.window.WAPI.ReplyMessage (/WhatsApp/WBOT-0.15.1/src/WAPI.js:730:18)
    at Object.chat (/WhatsApp/WBOT-0.15.1/src/inject.js:14:22)
    at /WhatsApp/WBOT-0.15.1/src/inject.js:73:63
    at Array.forEach (<anonymous>)
    at /WhatsApp/WBOT-0.15.1/src/inject.js:66:30
vasani-arpit commented 3 years ago

Will check and get back to you.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

vasani-arpit commented 3 years ago
 src/WAPI.js | 77 +++++++++++++++++++++++++------------------------------------
 1 file changed, 31 insertions(+), 46 deletions(-)

diff --git a/src/WAPI.js b/src/WAPI.js
index 7c338ce..6b4b990 100644
--- a/src/WAPI.js
+++ b/src/WAPI.js
@@ -25,6 +25,8 @@ if (!window.Store) {
                 { id: "State", conditions: (module) => (module.STATE && module.STREAM) ? module : null },
                 { id: "WapDelete", conditions: (module) => (module.sendConversationDelete && module.sendConversationDelete.length == 2) ? module : null },
                 { id: "Conn", conditions: (module) => (module.default && module.default.ref && module.default.refTTL) ? module.default : null },
+                { id: "WidFactory", conditions: (module) => (module.isWidlike && module.createWid && module.createWidFromWidLike) ? module : null },
+                { id: "addAndSendMsgToChat", conditions: (module) => (module.addAndSendMsgToChat) ? module.addAndSendMsgToChat : null },
                 { id: "WapQuery", conditions: (module) => (module.queryExist) ? module : ((module.default && module.default.queryExist) ? module.default : null) },
                 { id: "CryptoLib", conditions: (module) => (module.decryptE2EMedia) ? module : null },
                 { id: "OpenChat", conditions: (module) => (module.default && module.default.prototype && module.default.prototype.openChat) ? module.default : null },
@@ -687,53 +689,36 @@ window.WAPI.getMessageById = function (id, done) {
     }
 };

-window.WAPI.ReplyMessage = function (idMessage, message, done) {
-    var messageObject = window.Store.Msg.get(idMessage);
-    if (messageObject === undefined) {
-        if (done !== undefined) done(false);
-        return false;
-    }
-    messageObject = messageObject.value();
-
-    const chat = WAPI.getChat(messageObject.chat.id)
-    if (chat !== undefined) {
-        if (done !== undefined) {
-            chat.sendMessage(message, null, messageObject).then(function () {
-                function sleep(ms) {
-                    return new Promise(resolve => setTimeout(resolve, ms));
-                }
-
-                var trials = 0;
-
-                function check() {
-                    for (let i = chat.msgs.models.length - 1; i >= 0; i--) {
-                        let msg = chat.msgs.models[i];
-
-                        if (!msg.senderObj.isMe || msg.body != message) {
-                            continue;
-                        }
-                        done(WAPI._serializeMessageObj(msg));
-                        return True;
-                    }
-                    trials += 1;
-                    console.log(trials);
-                    if (trials > 30) {
-                        done(true);
-                        return;
-                    }
-                    sleep(500).then(check);
-                }
-                check();
-            });
-            return true;
-        } else {
-            chat.sendMessage(message, null, messageObject);
-            return true;
+window.WAPI.ReplyMessage = async function (chatId, body, quotedMsg) {
+    if (typeof quotedMsg !== "object") quotedMsg = Store.Msg.get(quotedMsg)
+    var chat = Store.Chat.get(chatId);
+    if(!chat) return false;
+        let extras = {};
+        if(quotedMsg) {
+            extras = {
+                quotedParticipant: quotedMsg.author || quotedMsg.from,
+                quotedStanzaID:quotedMsg.id.id
+            };
         }
-    } else {
-        if (done !== undefined) done(false);
-        return false;
-    }
+    var tempMsg = Object.create(Store.Msg.models.filter(msg => msg.__x_isSentByMe && !msg.quotedMsg)[0]);
+    var newId = window.WAPI.getNewMessageId(chatId);
+    var extend = {
+        ack: 0,
+        id: newId,
+        local: !0,
+        self: "out",
+        t: parseInt(new Date().getTime() / 1000),
+        to:  new Store.WidFactory.createWid(chatId),
+        isNewMsg: !0,
+        type: "chat",
+        quotedMsg,
+        body,
+        ...extras
+    };
+    Object.assign(tempMsg, extend);
+    const res = await Promise.all(await Store.addAndSendMsgToChat(chat, tempMsg));
+    if(res[1]!='success') return false;
+    return res[0].id._serialized
 };

 window.WAPI.sendMessageToID = function (id, message, done) {

I made the above changes and it is working now. Do notice that the function signature changes so you may need to change your parameters in your function call.

ghost commented 3 years ago

Hi, here my way to response a message or quote to reply : https://github.com/erzqy/WBOT/blob/57672767d86b45dabd502393036c484657653c5e/src/inject.js#L9

Here I've made modification the function as you explained above : https://github.com/erzqy/WBOT/blob/57672767d86b45dabd502393036c484657653c5e/src/WAPI.js#L748

It's working prefectly as i want, my webhook response just like :

{
    "type": "chat",
    "text": "Text response",
    "reply": "false_XXXX@c.us_YYYYYY"
}
ghost commented 3 years ago

Okay, it's fun but, we need to quote all of reply messages. Not only a text messages.

vasani-arpit commented 3 years ago

You can quote any message once you have an id of the message.