Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement observer for whatsApp webhook, also potentially for other modules #61

Open
alberto56 opened this issue Nov 21, 2024 · 1 comment

Comments

@alberto56
Copy link
Contributor

No description provided.

@alberto56 alberto56 changed the title Implement listener for WhatsApp receiver Implement observer Nov 21, 2024
@alberto56
Copy link
Contributor Author

alberto56 commented Nov 21, 2024

Currently we have ./app/code/webhookWhatsApp/index.js which has a run() method which defines the following response to a whatsapp message:

await this.storeInMessageDetail(messageObject);
// Send Confirmation message.
await app.c('whatsAppSend').parsepropertySendMessage('{"message": "!!! Well received !!!", "sendTo":"' + req.body.WaId + '"}');

Your task

Implement the Observer pattern, defined in https://en.wikipedia.org/wiki/Observer_pattern, to do the following:

  • by default webhookWhatsApp should do nothing when receiving a message in WhatsApp.

  • in order to get webhookWhatsApp to do something, we will need to add an observer, like this:

    app.c('observers').addObserver({
    "module": "webhookWhatsApp",
    "verb": "receiveMessage",
    "applyTo": "*", // * for all phone numbers, or else specify a phone number.
    "callback": async function(details) {
    await this.storeInMessageDetail(details.messageObject);
    // Send Confirmation message.
    await app.c('whatsAppSend').parsepropertySendMessage('{"message": "!!! Well received !!!", "sendTo":"' + details.number + '"}');
    },
    "expire": "+1 hour", // or never, or a date...
    });

// returns a uuid of this observer.

Now when webhookWhatsApp receives a message from, say, +15551234567, instead of replying "!!! Well received !!!", we want to do something like this:

// const fromNumber = "+15551234567";

const observers = this.app.c('observers').observers({
  "module": "webhookWhatsApp", // only return observers for this module.
  "verb": "receiveMessage", // only return observers for this verb
  "applyTo": fromNumber // see of "*" matches +15551234567 and returns observers which do.
});

observers.forEach((o) => {
  o.callback(...); // See below for actual example
});

If you want to get all observers, you can do:

const observers = this.app.c('observers').observers();

// This will return all observers as an array, and each observer will have its UUID in a uuid key. It might return somethng like this:

[{
   "module": "webhookWhatsApp",
   "verb": "receiveMessage",
   "applyTo": "*", // * for all phone numbers, or else specify a phone number.
   "callback": async function(details) {
      await this.storeInMessageDetail(details.messageObject);
      // Send Confirmation message.
      await app.c('whatsAppSend').parsepropertySendMessage('{"message": "!!! Well received !!!", "sendTo":"' + details.number + '"}');
   },
   "expire": "+1 hour", // or never, or a date...
   "uuid": "THIS_IS_A_UUID_FOR_THIS_OBSERVER"
}]

If you want to remove an observer, you can either set it to expire using expire key, or you can remove it using the UUID like this:

this.app.c('observers').delete(uuid);

So to delete our observer you would run:

this.app.c('observers').delete('THIS_IS_A_UUID_FOR_THIS_OBSERVER');

For now we'll use it only for WhatsApp webhook, but we want the solution to be generic enough to be used by any module which wants to implement the observer pattern.

Concretely, all the heavy lifting will be done in the "observers" module, and the webhookWhatsApp will only have this small change. Instead of:

...
if (this.validateAuthenticatedMessage(messageObject)) {
  await this.storeInMessageDetail(messageObject);
  // Send Confirmation message.
  await app.c('whatsAppSend').parsepropertySendMessage('{"message": "!!! Well received !!!", "sendTo":"' + req.body.WaId + '"}');
  // https://stackoverflow.com/questions/68508372
  const resp = '<?xml version="1.0" encoding="UTF-8"?><Response>' + jsonMessage + '</Response>';
  res.status(200).send(resp);
}
...

we will have:

...
if (this.validateAuthenticatedMessage(messageObject)) {
  this.app.c('observers').observers({
    "module": "webhookWhatsApp", // only return observers for this module.
    "verb": "receiveMessage", // only return observers for this verb
    "applyTo": fromNumber // see of "*" matches +15551234567 and returns observers which do.
  }).forEach((o) => {
    o.callback({"messageObject": messageObject, "number": req.bodyWaId });
  });
  // https://stackoverflow.com/questions/68508372
  const resp = '<?xml version="1.0" encoding="UTF-8"?><Response>' + jsonMessage + '</Response>';
  res.status(200).send(resp);
}
...

@alberto56 alberto56 changed the title Implement observer Implement observer for whatsApp webhook, also potentially for other modules Nov 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant