adaptive-memory-multi-model-router 1.9.2 โ 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -24,6 +24,7 @@ const GmailIntegration = require('./gmail.js').GmailIntegration;
|
|
|
24
24
|
const DiscordIntegration = require('./discord.js').DiscordIntegration;
|
|
25
25
|
const AirtableIntegration = require('./airtable.js').AirtableIntegration;
|
|
26
26
|
const GoogleCalendarIntegration = require('./google-calendar.js').GoogleCalendarIntegration;
|
|
27
|
+
const WhatsAppIntegration = require('./whatsapp.js').WhatsAppIntegration;
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Factory to create integrations
|
|
@@ -40,6 +41,7 @@ function createIntegration(type, config) {
|
|
|
40
41
|
case 'discord': return new DiscordIntegration(config.webhookUrl);
|
|
41
42
|
case 'airtable': return new AirtableIntegration(config.apiKey, config.baseId);
|
|
42
43
|
case 'google-calendar': return new GoogleCalendarIntegration(config.credentials);
|
|
44
|
+
case 'whatsapp': return new WhatsAppIntegration(config.phoneNumberId, config.accessToken);
|
|
43
45
|
default: throw new Error(`Unknown integration type: ${type}`);
|
|
44
46
|
}
|
|
45
47
|
}
|
|
@@ -56,6 +58,7 @@ module.exports = {
|
|
|
56
58
|
DiscordIntegration,
|
|
57
59
|
AirtableIntegration,
|
|
58
60
|
GoogleCalendarIntegration,
|
|
61
|
+
WhatsAppIntegration,
|
|
59
62
|
// Factory
|
|
60
63
|
createIntegration
|
|
61
64
|
};
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WhatsApp โ Telegram Bridge Demo
|
|
4
|
+
*
|
|
5
|
+
* This demo shows how the bridge works without requiring real credentials.
|
|
6
|
+
* It uses mock implementations to demonstrate the flow.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Mock implementations for demo
|
|
10
|
+
class MockWhatsAppIntegration {
|
|
11
|
+
constructor(phoneNumberId, accessToken) {
|
|
12
|
+
this.phoneNumberId = phoneNumberId;
|
|
13
|
+
this.accessToken = accessToken;
|
|
14
|
+
console.log(`๐ฑ WhatsApp Integration initialized (Phone: ${phoneNumberId})`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async sendMessage(to, body) {
|
|
18
|
+
console.log(` ๐ค WhatsApp โ ${to}: "${body.substring(0, 50)}..."`);
|
|
19
|
+
return {
|
|
20
|
+
messaging_product: 'whatsapp',
|
|
21
|
+
contacts: [{ input: to, wa_id: to }],
|
|
22
|
+
messages: [{ id: `wamid.${Date.now()}` }]
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async getMessages() {
|
|
27
|
+
return { messages: [] };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
class MockTelegramIntegration {
|
|
32
|
+
constructor(botToken) {
|
|
33
|
+
this.botToken = botToken;
|
|
34
|
+
this.messageId = 1000;
|
|
35
|
+
console.log(`๐ฌ Telegram Integration initialized (Bot: ${botToken.substring(0, 10)}...)`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async sendMessage(chatId, text) {
|
|
39
|
+
this.messageId++;
|
|
40
|
+
console.log(` ๐ค Telegram โ Chat ${chatId}:`);
|
|
41
|
+
console.log(` ${text.substring(0, 100)}...`);
|
|
42
|
+
return {
|
|
43
|
+
message_id: this.messageId,
|
|
44
|
+
chat: { id: chatId },
|
|
45
|
+
text: text
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async getUpdates() {
|
|
50
|
+
return { result: [] };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Import A3M Router
|
|
55
|
+
const { createA3MRouter } = require('../dist/index.js');
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* WhatsApp โ Telegram Bridge Demo
|
|
59
|
+
*/
|
|
60
|
+
class WhatsAppTelegramBridgeDemo {
|
|
61
|
+
constructor() {
|
|
62
|
+
this.whatsapp = new MockWhatsAppIntegration('1234567890', 'mock_token');
|
|
63
|
+
this.telegram = new MockTelegramIntegration('mock_bot_token_12345');
|
|
64
|
+
this.telegramChatId = '987654321';
|
|
65
|
+
|
|
66
|
+
// A3M Router for intelligent routing
|
|
67
|
+
this.router = createA3MRouter();
|
|
68
|
+
|
|
69
|
+
// Message tracking
|
|
70
|
+
this.pendingReplies = new Map();
|
|
71
|
+
this.demoMode = true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async handleWhatsAppMessage(whatsappMessage) {
|
|
75
|
+
console.log('\n๐ฉ STEP 1: Received WhatsApp Message');
|
|
76
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
77
|
+
|
|
78
|
+
const entry = whatsappMessage.entry?.[0];
|
|
79
|
+
const change = entry?.changes?.[0];
|
|
80
|
+
const value = change?.value;
|
|
81
|
+
const message = value?.messages?.[0];
|
|
82
|
+
|
|
83
|
+
if (!message) {
|
|
84
|
+
console.log('โ No message in payload');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const from = message.from;
|
|
89
|
+
const text = message.text?.body || '';
|
|
90
|
+
const messageId = message.id;
|
|
91
|
+
|
|
92
|
+
console.log(` From: ${from}`);
|
|
93
|
+
console.log(` Text: "${text}"`);
|
|
94
|
+
console.log(` Message ID: ${messageId}`);
|
|
95
|
+
|
|
96
|
+
// Route the message
|
|
97
|
+
console.log('\n๐ STEP 2: Route Message via A3M Router');
|
|
98
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
99
|
+
|
|
100
|
+
const route = this.router.route(text);
|
|
101
|
+
console.log(` Primary Model: ${route.primary_model}`);
|
|
102
|
+
console.log(` Fallbacks: ${route.fallback_models.slice(0, 2).join(', ')}`);
|
|
103
|
+
console.log(` Estimated Cost: $${route.estimated_cost.toFixed(6)}`);
|
|
104
|
+
console.log(` Reasoning: ${route.reasoning}`);
|
|
105
|
+
|
|
106
|
+
// Forward to Telegram
|
|
107
|
+
console.log('\n๐ค STEP 3: Forward to Telegram Bot');
|
|
108
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
109
|
+
|
|
110
|
+
const telegramResult = await this.forwardToTelegram(from, text, route);
|
|
111
|
+
|
|
112
|
+
this.pendingReplies.set(telegramResult.messageId, {
|
|
113
|
+
whatsappUser: from,
|
|
114
|
+
originalText: text,
|
|
115
|
+
timestamp: Date.now(),
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
console.log(` Telegram Message ID: ${telegramResult.messageId}`);
|
|
119
|
+
console.log(` Status: โ
Forwarded successfully`);
|
|
120
|
+
|
|
121
|
+
// Simulate Telegram bot reply
|
|
122
|
+
console.log('\n๐ฉ STEP 4: Telegram Bot Processes & Replies');
|
|
123
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
124
|
+
|
|
125
|
+
await this.simulateTelegramReply(telegramResult.messageId, text);
|
|
126
|
+
|
|
127
|
+
return telegramResult;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async forwardToTelegram(whatsappUser, text, route) {
|
|
131
|
+
const formattedMessage = `
|
|
132
|
+
๐ <b>WhatsApp Bridge</b>
|
|
133
|
+
๐ฑ <b>From:</b> ${whatsappUser}
|
|
134
|
+
๐ค <b>Route:</b> ${route.primary_model}
|
|
135
|
+
๐ฐ <b>Est. Cost:</b> $${route.estimated_cost.toFixed(6)}
|
|
136
|
+
|
|
137
|
+
๐ฌ <b>Message:</b>
|
|
138
|
+
${text}
|
|
139
|
+
|
|
140
|
+
<i>Reply to this message to respond back to WhatsApp user</i>
|
|
141
|
+
`.trim();
|
|
142
|
+
|
|
143
|
+
const result = await this.telegram.sendMessage(this.telegramChatId, formattedMessage);
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
messageId: result.message_id,
|
|
147
|
+
chatId: this.telegramChatId,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async simulateTelegramReply(originalMessageId, originalText) {
|
|
152
|
+
// Simulate bot processing time
|
|
153
|
+
console.log(' ๐ค Bot is processing...');
|
|
154
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
155
|
+
|
|
156
|
+
// Generate contextual reply
|
|
157
|
+
let reply;
|
|
158
|
+
if (originalText.toLowerCase().includes('order')) {
|
|
159
|
+
reply = `I've checked your order. It will be shipped tomorrow! ๐ฆ`;
|
|
160
|
+
} else if (originalText.toLowerCase().includes('help')) {
|
|
161
|
+
reply = `I'm here to help! What do you need assistance with? ๐ค`;
|
|
162
|
+
} else if (originalText.toLowerCase().includes('price')) {
|
|
163
|
+
reply = `Let me check the pricing for you. One moment please... ๐ฐ`;
|
|
164
|
+
} else {
|
|
165
|
+
reply = `Thanks for your message! Our team will get back to you shortly. โฐ`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log(` Bot Reply: "${reply}"`);
|
|
169
|
+
|
|
170
|
+
// Handle the reply
|
|
171
|
+
await this.handleTelegramReply({
|
|
172
|
+
message: {
|
|
173
|
+
message_id: Date.now(),
|
|
174
|
+
reply_to_message: { message_id: originalMessageId },
|
|
175
|
+
text: reply,
|
|
176
|
+
chat: { id: this.telegramChatId }
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async handleTelegramReply(telegramUpdate) {
|
|
182
|
+
console.log('\n๐ค STEP 5: Send Reply Back to WhatsApp');
|
|
183
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
184
|
+
|
|
185
|
+
const message = telegramUpdate.message;
|
|
186
|
+
const replyToMessage = message.reply_to_message;
|
|
187
|
+
const originalMessageId = replyToMessage.message_id;
|
|
188
|
+
|
|
189
|
+
const pending = this.pendingReplies.get(originalMessageId);
|
|
190
|
+
if (!pending) {
|
|
191
|
+
console.log('โ No pending reply found');
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const replyText = message.text;
|
|
196
|
+
console.log(` Original WhatsApp User: ${pending.whatsappUser}`);
|
|
197
|
+
console.log(` Reply Text: "${replyText}"`);
|
|
198
|
+
|
|
199
|
+
// Send back to WhatsApp
|
|
200
|
+
await this.whatsapp.sendMessage(pending.whatsappUser, replyText);
|
|
201
|
+
|
|
202
|
+
this.pendingReplies.delete(originalMessageId);
|
|
203
|
+
|
|
204
|
+
console.log(' Status: โ
Reply sent successfully');
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Demo scenarios
|
|
209
|
+
const DEMO_MESSAGES = [
|
|
210
|
+
{
|
|
211
|
+
description: 'Customer asking about order',
|
|
212
|
+
payload: {
|
|
213
|
+
entry: [{
|
|
214
|
+
changes: [{
|
|
215
|
+
value: {
|
|
216
|
+
messages: [{
|
|
217
|
+
from: '+1234567890',
|
|
218
|
+
id: 'wamid.demo1',
|
|
219
|
+
text: { body: 'Hello, I need help with my order #12345' },
|
|
220
|
+
timestamp: Date.now().toString(),
|
|
221
|
+
}],
|
|
222
|
+
},
|
|
223
|
+
}],
|
|
224
|
+
}],
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
description: 'Customer asking for pricing',
|
|
229
|
+
payload: {
|
|
230
|
+
entry: [{
|
|
231
|
+
changes: [{
|
|
232
|
+
value: {
|
|
233
|
+
messages: [{
|
|
234
|
+
from: '+9876543210',
|
|
235
|
+
id: 'wamid.demo2',
|
|
236
|
+
text: { body: 'What is the price for your premium plan?' },
|
|
237
|
+
timestamp: Date.now().toString(),
|
|
238
|
+
}],
|
|
239
|
+
},
|
|
240
|
+
}],
|
|
241
|
+
}],
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
description: 'General inquiry',
|
|
246
|
+
payload: {
|
|
247
|
+
entry: [{
|
|
248
|
+
changes: [{
|
|
249
|
+
value: {
|
|
250
|
+
messages: [{
|
|
251
|
+
from: '+5555555555',
|
|
252
|
+
id: 'wamid.demo3',
|
|
253
|
+
text: { body: 'Hi there, I have a question about your services' },
|
|
254
|
+
timestamp: Date.now().toString(),
|
|
255
|
+
}],
|
|
256
|
+
},
|
|
257
|
+
}],
|
|
258
|
+
}],
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
];
|
|
262
|
+
|
|
263
|
+
// Run demo
|
|
264
|
+
async function main() {
|
|
265
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
266
|
+
console.log('๐ฑ WhatsApp โ Telegram Bridge Demo');
|
|
267
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
268
|
+
console.log('');
|
|
269
|
+
console.log('This demo shows how to use a Telegram bot to process');
|
|
270
|
+
console.log('WhatsApp messages and send replies back.');
|
|
271
|
+
console.log('');
|
|
272
|
+
|
|
273
|
+
const bridge = new WhatsAppTelegramBridgeDemo();
|
|
274
|
+
|
|
275
|
+
for (const scenario of DEMO_MESSAGES) {
|
|
276
|
+
console.log('\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
277
|
+
console.log(`๐ Scenario: ${scenario.description}`);
|
|
278
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
279
|
+
|
|
280
|
+
await bridge.handleWhatsAppMessage(scenario.payload);
|
|
281
|
+
|
|
282
|
+
// Wait between scenarios
|
|
283
|
+
await new Promise(r => setTimeout(r, 1500));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
console.log('\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
287
|
+
console.log('โ
Demo Complete!');
|
|
288
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
289
|
+
console.log('');
|
|
290
|
+
console.log('To use in production:');
|
|
291
|
+
console.log(' 1. Get WhatsApp Business API credentials');
|
|
292
|
+
console.log(' 2. Create Telegram bot via @BotFather');
|
|
293
|
+
console.log(' 3. Set up webhooks for both platforms');
|
|
294
|
+
console.log(' 4. Use whatsapp-telegram-bridge.js with real credentials');
|
|
295
|
+
console.log('');
|
|
296
|
+
console.log('Documentation:');
|
|
297
|
+
console.log(' - WhatsApp: https://business.whatsapp.com/products/business-platform');
|
|
298
|
+
console.log(' - Telegram: https://core.telegram.org/bots/api');
|
|
299
|
+
console.log('');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WhatsApp โ Telegram Bridge Example
|
|
4
|
+
*
|
|
5
|
+
* This example shows how to use a Telegram bot to process
|
|
6
|
+
* WhatsApp messages and send replies back.
|
|
7
|
+
*
|
|
8
|
+
* Prerequisites:
|
|
9
|
+
* 1. WhatsApp Business API credentials (phoneNumberId, accessToken)
|
|
10
|
+
* 2. Telegram Bot Token (from @BotFather)
|
|
11
|
+
* 3. Webhook endpoint to receive WhatsApp messages
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* node whatsapp-telegram-bridge.js
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
createIntegration,
|
|
19
|
+
WhatsAppIntegration,
|
|
20
|
+
TelegramIntegration,
|
|
21
|
+
createA3MRouter
|
|
22
|
+
} = require('../dist/index.js');
|
|
23
|
+
|
|
24
|
+
// Configuration
|
|
25
|
+
const CONFIG = {
|
|
26
|
+
whatsapp: {
|
|
27
|
+
phoneNumberId: process.env.WHATSAPP_PHONE_NUMBER_ID,
|
|
28
|
+
accessToken: process.env.WHATSAPP_ACCESS_TOKEN,
|
|
29
|
+
},
|
|
30
|
+
telegram: {
|
|
31
|
+
botToken: process.env.TELEGRAM_BOT_TOKEN,
|
|
32
|
+
// The chat ID where your bot will process messages
|
|
33
|
+
// This could be your personal chat with the bot
|
|
34
|
+
chatId: process.env.TELEGRAM_CHAT_ID,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Validate config
|
|
39
|
+
function validateConfig() {
|
|
40
|
+
const missing = [];
|
|
41
|
+
if (!CONFIG.whatsapp.phoneNumberId) missing.push('WHATSAPP_PHONE_NUMBER_ID');
|
|
42
|
+
if (!CONFIG.whatsapp.accessToken) missing.push('WHATSAPP_ACCESS_TOKEN');
|
|
43
|
+
if (!CONFIG.telegram.botToken) missing.push('TELEGRAM_BOT_TOKEN');
|
|
44
|
+
if (!CONFIG.telegram.chatId) missing.push('TELEGRAM_CHAT_ID');
|
|
45
|
+
|
|
46
|
+
if (missing.length > 0) {
|
|
47
|
+
console.error('โ Missing environment variables:');
|
|
48
|
+
missing.forEach(v => console.error(` - ${v}`));
|
|
49
|
+
console.error('\nSet these variables and try again.');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* WhatsApp โ Telegram Bridge
|
|
56
|
+
*
|
|
57
|
+
* Flow:
|
|
58
|
+
* 1. Receive message from WhatsApp (via webhook)
|
|
59
|
+
* 2. Forward message to Telegram bot
|
|
60
|
+
* 3. Get reply from Telegram (bot processes it)
|
|
61
|
+
* 4. Send reply back to WhatsApp user
|
|
62
|
+
*/
|
|
63
|
+
class WhatsAppTelegramBridge {
|
|
64
|
+
constructor(config) {
|
|
65
|
+
this.whatsapp = new WhatsAppIntegration(
|
|
66
|
+
config.whatsapp.phoneNumberId,
|
|
67
|
+
config.whatsapp.accessToken
|
|
68
|
+
);
|
|
69
|
+
this.telegram = new TelegramIntegration(config.telegram.botToken);
|
|
70
|
+
this.telegramChatId = config.telegram.chatId;
|
|
71
|
+
|
|
72
|
+
// A3M Router for intelligent routing
|
|
73
|
+
this.router = createA3MRouter();
|
|
74
|
+
|
|
75
|
+
// Message tracking
|
|
76
|
+
this.pendingReplies = new Map(); // messageId -> { whatsappUser, timestamp }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Handle incoming WhatsApp message
|
|
81
|
+
* @param {Object} whatsappMessage - WhatsApp webhook payload
|
|
82
|
+
*/
|
|
83
|
+
async handleWhatsAppMessage(whatsappMessage) {
|
|
84
|
+
try {
|
|
85
|
+
// Extract message details
|
|
86
|
+
const entry = whatsappMessage.entry?.[0];
|
|
87
|
+
const change = entry?.changes?.[0];
|
|
88
|
+
const value = change?.value;
|
|
89
|
+
const message = value?.messages?.[0];
|
|
90
|
+
|
|
91
|
+
if (!message) {
|
|
92
|
+
console.log('No message in webhook payload');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const from = message.from; // WhatsApp user phone number
|
|
97
|
+
const text = message.text?.body || '';
|
|
98
|
+
const messageId = message.id;
|
|
99
|
+
|
|
100
|
+
console.log(`๐ฉ WhatsApp message from ${from}: "${text.substring(0, 50)}..."`);
|
|
101
|
+
|
|
102
|
+
// Route the message to get best processing strategy
|
|
103
|
+
const route = this.router.route(text);
|
|
104
|
+
console.log(`๐ Routed to: ${route.primary_model} (${route.reasoning})`);
|
|
105
|
+
|
|
106
|
+
// Forward to Telegram bot with context
|
|
107
|
+
const telegramMessage = await this.forwardToTelegram(from, text, route);
|
|
108
|
+
|
|
109
|
+
// Track pending reply
|
|
110
|
+
this.pendingReplies.set(telegramMessage.messageId, {
|
|
111
|
+
whatsappUser: from,
|
|
112
|
+
originalText: text,
|
|
113
|
+
timestamp: Date.now(),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
console.log(`๐ค Forwarded to Telegram (message ID: ${telegramMessage.messageId})`);
|
|
117
|
+
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error('โ Error handling WhatsApp message:', error.message);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Forward WhatsApp message to Telegram
|
|
125
|
+
*/
|
|
126
|
+
async forwardToTelegram(whatsappUser, text, route) {
|
|
127
|
+
// Format message for Telegram bot
|
|
128
|
+
const formattedMessage = `
|
|
129
|
+
๐ <b>WhatsApp Bridge</b>
|
|
130
|
+
๐ฑ <b>From:</b> ${whatsappUser}
|
|
131
|
+
๐ค <b>Route:</b> ${route.primary_model}
|
|
132
|
+
|
|
133
|
+
๐ฌ <b>Message:</b>
|
|
134
|
+
${text}
|
|
135
|
+
|
|
136
|
+
<i>Reply to this message to respond back to WhatsApp user</i>
|
|
137
|
+
`.trim();
|
|
138
|
+
|
|
139
|
+
// Send to Telegram
|
|
140
|
+
const result = await this.telegram.sendMessage(
|
|
141
|
+
this.telegramChatId,
|
|
142
|
+
formattedMessage
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
messageId: result.message_id || `msg_${Date.now()}`,
|
|
147
|
+
chatId: this.telegramChatId,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Handle Telegram reply
|
|
153
|
+
* @param {Object} telegramUpdate - Telegram webhook/update payload
|
|
154
|
+
*/
|
|
155
|
+
async handleTelegramReply(telegramUpdate) {
|
|
156
|
+
try {
|
|
157
|
+
const message = telegramUpdate.message || telegramUpdate.callback_query?.message;
|
|
158
|
+
if (!message) return;
|
|
159
|
+
|
|
160
|
+
const replyToMessage = message.reply_to_message;
|
|
161
|
+
if (!replyToMessage) {
|
|
162
|
+
console.log('Not a reply message, ignoring');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Extract original message ID from reply
|
|
167
|
+
const originalMessageId = replyToMessage.message_id;
|
|
168
|
+
const pending = this.pendingReplies.get(originalMessageId);
|
|
169
|
+
|
|
170
|
+
if (!pending) {
|
|
171
|
+
console.log('No pending WhatsApp reply found for this message');
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const replyText = message.text || message.caption || '';
|
|
176
|
+
console.log(`๐ฉ Telegram reply: "${replyText.substring(0, 50)}..."`);
|
|
177
|
+
|
|
178
|
+
// Send reply back to WhatsApp
|
|
179
|
+
await this.sendWhatsAppReply(pending.whatsappUser, replyText);
|
|
180
|
+
|
|
181
|
+
// Clean up pending reply
|
|
182
|
+
this.pendingReplies.delete(originalMessageId);
|
|
183
|
+
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error('โ Error handling Telegram reply:', error.message);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Send reply back to WhatsApp user
|
|
191
|
+
*/
|
|
192
|
+
async sendWhatsAppReply(to, text) {
|
|
193
|
+
const result = await this.whatsapp.sendMessage(to, text);
|
|
194
|
+
console.log(`๐ค Sent WhatsApp reply to ${to}: "${text.substring(0, 50)}..."`);
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Clean up old pending replies (older than 1 hour)
|
|
200
|
+
*/
|
|
201
|
+
cleanupPendingReplies() {
|
|
202
|
+
const now = Date.now();
|
|
203
|
+
const oneHour = 60 * 60 * 1000;
|
|
204
|
+
|
|
205
|
+
for (const [messageId, pending] of this.pendingReplies) {
|
|
206
|
+
if (now - pending.timestamp > oneHour) {
|
|
207
|
+
this.pendingReplies.delete(messageId);
|
|
208
|
+
console.log(`๐งน Cleaned up expired pending reply: ${messageId}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Start cleanup interval
|
|
215
|
+
*/
|
|
216
|
+
startCleanup() {
|
|
217
|
+
setInterval(() => this.cleanupPendingReplies(), 5 * 60 * 1000); // Every 5 minutes
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Example usage
|
|
222
|
+
async function main() {
|
|
223
|
+
validateConfig();
|
|
224
|
+
|
|
225
|
+
console.log('๐ Starting WhatsApp โ Telegram Bridge\n');
|
|
226
|
+
|
|
227
|
+
const bridge = new WhatsAppTelegramBridge(CONFIG);
|
|
228
|
+
bridge.startCleanup();
|
|
229
|
+
|
|
230
|
+
console.log('โ
Bridge initialized');
|
|
231
|
+
console.log(` WhatsApp Phone Number ID: ${CONFIG.whatsapp.phoneNumberId}`);
|
|
232
|
+
console.log(` Telegram Chat ID: ${CONFIG.telegram.chatId}`);
|
|
233
|
+
console.log('');
|
|
234
|
+
|
|
235
|
+
// Example: Simulate receiving a WhatsApp message
|
|
236
|
+
console.log('๐ Example: Simulating WhatsApp webhook payload\n');
|
|
237
|
+
|
|
238
|
+
const exampleWhatsAppMessage = {
|
|
239
|
+
entry: [{
|
|
240
|
+
changes: [{
|
|
241
|
+
value: {
|
|
242
|
+
messages: [{
|
|
243
|
+
from: '1234567890',
|
|
244
|
+
id: 'wamid.example123',
|
|
245
|
+
text: { body: 'Hello, I need help with my order #12345' },
|
|
246
|
+
timestamp: Date.now().toString(),
|
|
247
|
+
}],
|
|
248
|
+
},
|
|
249
|
+
}],
|
|
250
|
+
}],
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
await bridge.handleWhatsAppMessage(exampleWhatsAppMessage);
|
|
254
|
+
|
|
255
|
+
console.log('\n๐ To use this in production:');
|
|
256
|
+
console.log(' 1. Set up WhatsApp Business API webhook');
|
|
257
|
+
console.log(' 2. Set up Telegram bot webhook');
|
|
258
|
+
console.log(' 3. Route webhooks to handleWhatsAppMessage() and handleTelegramReply()');
|
|
259
|
+
console.log('');
|
|
260
|
+
console.log('๐ See: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/set-up-webhooks');
|
|
261
|
+
console.log('๐ See: https://core.telegram.org/bots/webhooks');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Run if executed directly
|
|
265
|
+
if (require.main === module) {
|
|
266
|
+
main().catch(console.error);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
module.exports = { WhatsAppTelegramBridge };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adaptive-memory-multi-model-router",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.4",
|
|
4
4
|
"shortName": "A3M Router",
|
|
5
5
|
"displayName": "A3M Router - Adaptive Memory Multi-Model Router",
|
|
6
6
|
"description": "A3M Router - Adaptive Memory Multi-Model Router with learned routing (RouteLLM), prefix caching (RadixAttention), speculative decoding (Medusa), TokenJuice-style compression. 14 LLM providers, 10 integrations, Python bindings. 20x more adaptable for ML/AI developers.",
|