Closed RyzorBent closed 1 year ago
Not sure I fully understand your question, but the following comes to mind:
// file 1: for the server
import express from 'express';
const app = express();
app.listen(3000, () => console.log('Running...'));
export { app };
// file 2: for the connections
import { createBot } from 'whatsapp-cloud-api';
import { app } from './file1';
const bot1 = createBot('PHONE_NUMBER_ID_1', 'TOKEN_1');
await bot1.startExpressServer({
app,
webhookVerifyToken: 'VERIFY_TOKEN_1',
webhookPath: '/webhook/bot/1',
});
bot1.on('message', (msg) => {
console.log(msg);
});
const bot2 = createBot('PHONE_NUMBER_ID_2', 'TOKEN_2');
await bot2.startExpressServer({
app,
webhookVerifyToken: 'VERIFY_TOKEN_2',
webhookPath: '/webhook/bot/2',
});
bot2.on('message', (msg) => {
console.log(msg);
});
Thoughts?
This is getting me closer to the desired solution, Let me test out this approach, will feedback. Thank you for this.
Marking this as completed. @RyzorBent, feel free to reopen if need be 😊
Not sure I fully understand your question, but the following comes to mind:
// file 1: for the server import express from 'express'; const app = express(); app.listen(3000, () => console.log('Running...')); export { app }; // file 2: for the connections import { createBot } from 'whatsapp-cloud-api'; import { app } from './file1'; const bot1 = createBot('PHONE_NUMBER_ID_1', 'TOKEN_1'); await bot1.startExpressServer({ app, webhookVerifyToken: 'VERIFY_TOKEN_1', webhookPath: '/webhook/bot/1', }); bot1.on('message', (msg) => { console.log(msg); }); const bot2 = createBot('PHONE_NUMBER_ID_2', 'TOKEN_2'); await bot2.startExpressServer({ app, webhookVerifyToken: 'VERIFY_TOKEN_2', webhookPath: '/webhook/bot/2', }); bot2.on('message', (msg) => { console.log(msg); });
Thoughts?
This solution works fine except handling one use case. If in multi-tenant system, I need to store these webhook messages. I don't have any reference of bot properties such as PHONE_NUMBER_ID or at least webhook url path.
Here is the code.
var bots = {};
// Init
for(var botSettings in allBots) {
const bot = createBot(botSettings['PHONE_ID'], botSettings['TOKEN']);
await bot.startExpressServer({
app,
webhookVerifyToken: botSettings['VERIFY_TOKEN'],
webhookPath: /webhook/bot/${botSettings['PHONE_ID']},
});
bot.on('message', (msg) => {
console.log(msg);
// Save these messages against botSettings['PHONE_ID']
});
bots[botSettings['PHONE_ID']] = bot;
}
Let me know if there is any possible solution
@tawn33y Please check this
Marking this as completed. @RyzorBent, feel free to reopen if need be 😊
The solution is having some problems.. as it instantiate multiple listeners and multiple on event getting triggered due to multi tenant system.
Any news on this? All bots are listening on the bot.on("message")
event
Very sorry @amit-onappr, I didn't see your messages.
@amit-onappr, @techpet:
I see the problem: currently, the on
event subscribes to all bots instead of a specific bot. When I first created this, I added this line in the README in anticipation of this problem.
Opening a PR to address this problem
You can now use the following functionality to remove a listener for a specific bot:
(async () => {
const bot = createBot('from', 'token');
await bot.startExpressServer({ webhookVerifyToken: 'xx' });
const subscriptionToken = bot.on('message', async (msg) => {
console.log(msg);
});
// to unsubscribe:
bot.unsubscribe(subscriptionToken);
})();
Hi @tawn33y, does this mean now the on
event for each bot is now for each subscriptionToken { meaning one can run multiple bots for different subscriptionTokens }, ... as you are now able to bot.unsubscribe(subscriptionToken);
?
Yes, Each on
event is for a specific bot.
// file 1: for the server
import express from 'express';
const app = express();
app.listen(3000, () => console.log('Running...'));
export { app };
// file 2: for the connections
import { createBot } from 'whatsapp-cloud-api';
import { app } from './file1';
(async () => {
// bot 1
const bot1 = createBot('PHONE_NUMBER_ID_1', 'TOKEN_1');
await bot1.startExpressServer({
app,
webhookVerifyToken: 'VERIFY_TOKEN_1',
webhookPath: '/webhook/bot/1',
});
const subscriptionToken1 = bot1.on('message', async (msg) => {
console.log(msg);
});
bot1.unsubscribe(subscriptionToken1);
// bot 2
const bot2 = createBot('PHONE_NUMBER_ID_2', 'TOKEN_2');
await bot2.startExpressServer({
app,
webhookVerifyToken: 'VERIFY_TOKEN_2',
webhookPath: '/webhook/bot/2',
});
const subscriptionToken2 = bot2.on('message', async (msg) => {
console.log(msg);
});
bot2.unsubscribe(subscriptionToken2);
})();
// file 1: for the server
import express from 'express';
const app = express();
app.listen(3000, () => console.log('Running...'));
export { app };
// file 2: configs
type BotConfig = {
phoneNumberId: string;
token: string;
webhookVerifyToken: string;
webhookPath: string;
}
export const botConfigs: BotConfig[] = [
{ phoneNumberId: 'xx', token: 'xx', webhookVerifyToken: 'xx', webhookPath: 'xx' },
{ phoneNumberId: 'yy', token: 'yy', webhookVerifyToken: 'yy', webhookPath: 'yy' },
];
// file 2: for the connections
import { createBot, type Bot } from 'whatsapp-cloud-api';
import { app } from './file1';
import { botConfigs } from './file2';
type BotStorage = {
[phoneNumberId: string]: {
bot: Bot;
subscriptionTokens: {
[event: string]: string;
};
};
}
let botsStorage: BotStorage = {};
(async () => {
for (let i = 0; i < botConfigs.length; i += 1) {
const { phoneNumberId, token, webhookVerifyToken, webhookPath } = botConfigs[i];
const bot = createBot(phoneNumberId, token);
await bot.startExpressServer({
app,
webhookVerifyToken,
webhookPath,
});
const subscriptionTokenForMessages = bot.on('message', async (msg) => {
console.log(msg);
});
const subscriptionTokenForImages = bot.on('image', async (msg) => {
console.log(msg);
});
// store these values
botsStorage = {
[phoneNumberId]: {
bot,
subscriptionTokens: {
'message': subscriptionTokenForMessages,
'image': subscriptionTokenForImages,
},
}
};
}
// later, later on
// remove 'message' subscription listener for 'xx'
const botXX = botsStorage['xx'];
botXX.bot.unsubscribe(botXX.subscriptionTokens['message']);
// remove 'image' subscription listener for 'yy'
const botYY = botsStorage['yy'];
botYY.bot.unsubscribe(botYY.subscriptionTokens['image']);
})()
I haven't tried these out, but I believe they should work :)
Greetings,
My MERN SAAS app where I'm using this module on the backend nodejs is getting completed. But now I'm not sure on how the backend nodejs is going to handle multiple users with different [ phone numbers, WhatsApp API tokens, etc. ]. are going to use the SAAS platform, Because the module needs the tokens at start-up time and keeps them in memory throughout.
What architecture approach do you suggest that I can use to easily handle this situation? any suggestions will be highly appreciated.