@daolmedo/openclaw-twilio-whatsapp 1.1.26 → 1.1.28
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.
- package/dist/index.js +55 -3
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// index.ts
|
|
2
2
|
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
|
3
3
|
|
|
4
|
+
// src/channel.ts
|
|
5
|
+
import {
|
|
6
|
+
buildChannelOutboundSessionRoute
|
|
7
|
+
} from "openclaw/plugin-sdk/channel-core";
|
|
8
|
+
|
|
4
9
|
// src/accounts.ts
|
|
5
10
|
var getTwilioChannelConfig = (cfg) => cfg.channels && cfg.channels["twilio-whatsapp"] ? cfg.channels["twilio-whatsapp"] : void 0;
|
|
6
11
|
function listTwilioAccountIds(cfg) {
|
|
@@ -35,7 +40,10 @@ function findTwilioAccountByPhoneNumber(cfg, phoneNumber) {
|
|
|
35
40
|
return void 0;
|
|
36
41
|
}
|
|
37
42
|
function normalizePhoneNumber(phone) {
|
|
38
|
-
return phone.replace(/^whatsapp
|
|
43
|
+
return phone.trim().replace(/^(?:(?:twilio-whatsapp|whatsapp):)+/i, "").replace(/\s+/g, "");
|
|
44
|
+
}
|
|
45
|
+
function looksLikePhoneNumber(phone) {
|
|
46
|
+
return /^\+[1-9]\d{6,14}$/.test(normalizePhoneNumber(phone));
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
// src/outbound-adapter.ts
|
|
@@ -163,6 +171,21 @@ function getRuntimeForPhoneNumber(phoneNumber) {
|
|
|
163
171
|
}
|
|
164
172
|
|
|
165
173
|
// src/channel.ts
|
|
174
|
+
function resolveTwilioWhatsappOutboundSessionRoute(params) {
|
|
175
|
+
const to = normalizePhoneNumber(params.resolvedTarget?.to ?? params.target);
|
|
176
|
+
if (!looksLikePhoneNumber(to)) return null;
|
|
177
|
+
return buildChannelOutboundSessionRoute({
|
|
178
|
+
cfg: params.cfg,
|
|
179
|
+
agentId: params.agentId,
|
|
180
|
+
channel: "twilio-whatsapp",
|
|
181
|
+
accountId: params.accountId,
|
|
182
|
+
recipientSessionExact: true,
|
|
183
|
+
peer: { kind: "direct", id: to },
|
|
184
|
+
chatType: "direct",
|
|
185
|
+
from: `whatsapp:${to}`,
|
|
186
|
+
to: `whatsapp:${to}`
|
|
187
|
+
});
|
|
188
|
+
}
|
|
166
189
|
var twilioWhatsappPlugin = {
|
|
167
190
|
id: "twilio-whatsapp",
|
|
168
191
|
meta: {
|
|
@@ -196,6 +219,15 @@ var twilioWhatsappPlugin = {
|
|
|
196
219
|
return listTwilioAccountIds(cfg).length > 0;
|
|
197
220
|
}
|
|
198
221
|
},
|
|
222
|
+
messaging: {
|
|
223
|
+
targetPrefixes: ["whatsapp"],
|
|
224
|
+
normalizeTarget: normalizePhoneNumber,
|
|
225
|
+
resolveOutboundSessionRoute: resolveTwilioWhatsappOutboundSessionRoute,
|
|
226
|
+
targetResolver: {
|
|
227
|
+
looksLikeId: (raw, normalized) => looksLikePhoneNumber(normalized ?? raw),
|
|
228
|
+
hint: "<+15551234567>"
|
|
229
|
+
}
|
|
230
|
+
},
|
|
199
231
|
outbound: twilioWhatsappOutbound,
|
|
200
232
|
message: twilioWhatsappMessageAdapter,
|
|
201
233
|
gateway: {
|
|
@@ -405,6 +437,22 @@ function resolveMediaBatchFlushMs() {
|
|
|
405
437
|
if (Number.isFinite(raw) && raw >= 0) return Math.min(raw, 6e4);
|
|
406
438
|
return 3e3;
|
|
407
439
|
}
|
|
440
|
+
function resolveMediaBatchInitialWaitMs() {
|
|
441
|
+
const rawValue = process.env.TWILIO_WHATSAPP_MEDIA_BATCH_INITIAL_WAIT_MS;
|
|
442
|
+
const raw = Number(rawValue);
|
|
443
|
+
if (rawValue !== void 0 && Number.isFinite(raw) && raw >= 0) {
|
|
444
|
+
return Math.min(raw, 6e4);
|
|
445
|
+
}
|
|
446
|
+
if (process.env.TWILIO_WHATSAPP_MEDIA_BATCH_FLUSH_MS !== void 0) {
|
|
447
|
+
return resolveMediaBatchFlushMs();
|
|
448
|
+
}
|
|
449
|
+
return 15e3;
|
|
450
|
+
}
|
|
451
|
+
function resolveMediaBatchMaxWaitMs() {
|
|
452
|
+
const raw = Number(process.env.TWILIO_WHATSAPP_MEDIA_BATCH_MAX_WAIT_MS);
|
|
453
|
+
if (Number.isFinite(raw) && raw >= 0) return Math.min(raw, 6e4);
|
|
454
|
+
return Math.min(resolveMediaBatchInitialWaitMs() + resolveMediaBatchFlushMs(), 6e4);
|
|
455
|
+
}
|
|
408
456
|
function resolveMediaBatchMaxItems() {
|
|
409
457
|
const raw = Number(process.env.TWILIO_WHATSAPP_MEDIA_BATCH_MAX_ITEMS);
|
|
410
458
|
if (Number.isFinite(raw) && raw > 0) return Math.floor(Math.min(raw, 50));
|
|
@@ -469,9 +517,13 @@ function stopBatchTimer(batch) {
|
|
|
469
517
|
}
|
|
470
518
|
function armBatchTimer(api, dispatchInbound, key, batch) {
|
|
471
519
|
stopBatchTimer(batch);
|
|
520
|
+
const batchAgeMs = Math.max(0, Date.now() - batch.firstReceivedAt);
|
|
521
|
+
const desiredWaitMs = batch.items.length === 1 ? resolveMediaBatchInitialWaitMs() : resolveMediaBatchFlushMs();
|
|
522
|
+
const remainingMaxWaitMs = Math.max(0, resolveMediaBatchMaxWaitMs() - batchAgeMs);
|
|
523
|
+
const waitMs = Math.min(desiredWaitMs, remainingMaxWaitMs);
|
|
472
524
|
batch.timer = setTimeout(() => {
|
|
473
525
|
void flushPendingMediaBatch(api, dispatchInbound, key, "timer");
|
|
474
|
-
},
|
|
526
|
+
}, waitMs);
|
|
475
527
|
batch.timer.unref?.();
|
|
476
528
|
}
|
|
477
529
|
async function flushPendingMediaBatch(api, dispatchInbound, key, reason) {
|
|
@@ -511,7 +563,7 @@ function queueMediaBatch(api, dispatchInbound, key, item) {
|
|
|
511
563
|
return new Promise((resolve, reject) => {
|
|
512
564
|
let batch = pendingMediaByConversation.get(key);
|
|
513
565
|
if (!batch) {
|
|
514
|
-
batch = { items: [] };
|
|
566
|
+
batch = { items: [], firstReceivedAt: item.receivedAt };
|
|
515
567
|
pendingMediaByConversation.set(key, batch);
|
|
516
568
|
}
|
|
517
569
|
batch.items.push({ ...item, resolve, reject });
|
package/openclaw.plugin.json
CHANGED