@diegoaltoworks/talker 0.14.0 → 0.15.0

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.
@@ -10,15 +10,22 @@ import type { TwilioConfig } from "../types";
10
10
  * Returns the bare phone number (e.g., "+1234567890").
11
11
  */
12
12
  export declare function stripWhatsAppPrefix(phoneNumber: string): string;
13
+ /**
14
+ * Options for outbound message sending
15
+ */
16
+ export interface SendMessageOptions {
17
+ /** Status callback URL for delivery status updates */
18
+ statusCallback?: string;
19
+ }
13
20
  /**
14
21
  * Send an SMS via Twilio REST API
15
22
  */
16
- export declare function sendSMS(config: TwilioConfig, to: string, message: string): Promise<boolean>;
23
+ export declare function sendSMS(config: TwilioConfig, to: string, message: string, options?: SendMessageOptions): Promise<boolean>;
17
24
  /**
18
25
  * Send a WhatsApp message via Twilio REST API.
19
26
  *
20
27
  * Twilio's WhatsApp API uses the same Messages endpoint as SMS but
21
28
  * requires `whatsapp:` prefixed From/To numbers.
22
29
  */
23
- export declare function sendWhatsApp(config: TwilioConfig, to: string, message: string): Promise<boolean>;
30
+ export declare function sendWhatsApp(config: TwilioConfig, to: string, message: string, options?: SendMessageOptions): Promise<boolean>;
24
31
  //# sourceMappingURL=twilio.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"twilio.d.ts","sourceRoot":"","sources":["../../src/adapters/twilio.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAyCjG;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC,CA6ClB"}
1
+ {"version":3,"file":"twilio.d.ts","sourceRoot":"","sources":["../../src/adapters/twilio.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA+BD;;GAEG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,OAAO,CAAC,CA0ClB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,OAAO,CAAC,CA8DlB"}
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmCH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBnD"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgDH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBnD"}
@@ -53,5 +53,21 @@ export declare function updateSessionIncremental(phoneNumber: string, channel: C
53
53
  content: string;
54
54
  timestamp: number;
55
55
  }>, conversationId?: string): Promise<boolean>;
56
+ /**
57
+ * Message delivery status record (from Twilio status callbacks)
58
+ */
59
+ export interface MessageStatusRecord {
60
+ messageSid: string;
61
+ channel: "sms" | "whatsapp";
62
+ from: string;
63
+ to: string;
64
+ status: string;
65
+ errorCode?: string;
66
+ errorMessage?: string;
67
+ }
68
+ /**
69
+ * Upsert a message delivery status (from Twilio status callback)
70
+ */
71
+ export declare function upsertMessageStatus(record: MessageStatusRecord): Promise<boolean>;
56
72
  export { generateId };
57
73
  //# sourceMappingURL=sessions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/db/sessions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,YAAY,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,iBAAS,UAAU,IAAI,MAAM,CAE5B;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGhF;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAiD5E;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAkB5E;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GAClF,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,EACnF,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAwClB;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/db/sessions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,YAAY,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,iBAAS,UAAU,IAAI,MAAM,CAE5B;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGhF;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAiD5E;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAkB5E;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GAClF,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,EACnF,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAwClB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,KAAK,GAAG,UAAU,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0CvF;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -39,7 +39,7 @@
39
39
  export { createTelephonyRoutes } from "./plugin";
40
40
  export { createStandaloneServer } from "./standalone";
41
41
  export type { StandaloneConfig } from "./standalone";
42
- export type { TalkerConfig, TalkerDependencies, TelephonyFeatureFlags, TwilioConfig, ChatbotConfig, ProcessingConfig, Channel, VoiceConfig, IncomingResult, TelephonyContext, Phrases, } from "./types";
42
+ export type { TalkerConfig, TalkerDependencies, TelephonyFeatureFlags, TwilioConfig, ChatbotConfig, ProcessingConfig, Channel, VoiceConfig, IncomingResult, TelephonyContext, Phrases, MessageStatusEvent, } from "./types";
43
43
  export type { FlowDefinition, FlowSchema, FlowSchemaProperty, FlowState, FlowHandler, FlowHandlerResult, FlowHandlerContext, FlowPrefill, FlowExtractionResult, FlowResult, IntentDetection, LoadedFlow, } from "./types";
44
44
  export { processIncoming, processOutgoing } from "./core/processing";
45
45
  export { getVoiceConfig, getDefaultVoices } from "./core/voice";
@@ -52,14 +52,18 @@ export { processFlow, shouldExitFlow } from "./flows/manager";
52
52
  export { loadFlowsFromDirectory } from "./flows/loader";
53
53
  export { getExitMessage } from "./flows/utils";
54
54
  export { sendSMS, sendWhatsApp, stripWhatsAppPrefix } from "./adapters/twilio";
55
+ export type { SendMessageOptions } from "./adapters/twilio";
55
56
  export { initDbClient, getDbClient, closeDbClient } from "./db/client";
56
57
  export { runMigrations } from "./db/migrate";
57
58
  export { persistFinalSession, persistSession } from "./db/persist";
58
- export type { SessionRecord, MessageRecord } from "./db/sessions";
59
+ export type { SessionRecord, MessageRecord, MessageStatusRecord } from "./db/sessions";
60
+ export { upsertMessageStatus } from "./db/sessions";
59
61
  export { callRoutes } from "./routes/call";
60
62
  export { smsRoutes } from "./routes/sms";
61
63
  export { whatsappRoutes } from "./routes/whatsapp";
62
64
  export { logger, redactPhone } from "./core/logger";
65
+ export { handleStatusCallback } from "./routes/shared/handle-status-callback";
66
+ export { handleFallback } from "./routes/shared/handle-fallback";
63
67
  export { twilioSignatureMiddleware, validateTwilioSignature } from "./middleware/twilio-signature";
64
68
  export { rateLimitMiddleware } from "./middleware/rate-limit";
65
69
  export { inputSanitizeMiddleware } from "./middleware/input-sanitize";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,OAAO,GACR,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,UAAU,GACX,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,YAAY,GACb,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG/E,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGlE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -85,6 +85,8 @@ __export(index_exports, {
85
85
  getSmsPhrase: () => getSmsPhrase,
86
86
  getVoiceConfig: () => getVoiceConfig,
87
87
  getWhatsAppPhrase: () => getWhatsAppPhrase,
88
+ handleFallback: () => handleFallback,
89
+ handleStatusCallback: () => handleStatusCallback,
88
90
  incrementNoSpeechRetries: () => incrementNoSpeechRetries,
89
91
  initDbClient: () => initDbClient,
90
92
  inputSanitizeMiddleware: () => inputSanitizeMiddleware,
@@ -115,6 +117,7 @@ __export(index_exports, {
115
117
  transferTwiml: () => transferTwiml,
116
118
  twilioSignatureMiddleware: () => twilioSignatureMiddleware,
117
119
  updateFlowParams: () => updateFlowParams,
120
+ upsertMessageStatus: () => upsertMessageStatus,
118
121
  validateTwilioSignature: () => validateTwilioSignature,
119
122
  whatsappRoutes: () => whatsappRoutes
120
123
  });
@@ -314,7 +317,7 @@ var SCHEMA_STATEMENTS = [
314
317
  `CREATE TABLE IF NOT EXISTS talker_sessions (
315
318
  id TEXT PRIMARY KEY,
316
319
  phone_number TEXT NOT NULL,
317
- channel TEXT NOT NULL CHECK(channel IN ('call', 'sms')),
320
+ channel TEXT NOT NULL CHECK(channel IN ('call', 'sms', 'whatsapp')),
318
321
  reason TEXT NOT NULL CHECK(reason IN ('ended', 'redirected')),
319
322
  language TEXT NOT NULL,
320
323
  started_at INTEGER NOT NULL,
@@ -334,10 +337,23 @@ var SCHEMA_STATEMENTS = [
334
337
  created_at INTEGER NOT NULL DEFAULT (unixepoch()),
335
338
  FOREIGN KEY (session_id) REFERENCES talker_sessions(id) ON DELETE CASCADE
336
339
  )`,
340
+ `CREATE TABLE IF NOT EXISTS talker_message_status (
341
+ message_sid TEXT PRIMARY KEY,
342
+ channel TEXT NOT NULL CHECK(channel IN ('sms', 'whatsapp')),
343
+ phone_from TEXT NOT NULL,
344
+ phone_to TEXT NOT NULL,
345
+ status TEXT NOT NULL,
346
+ error_code TEXT,
347
+ error_message TEXT,
348
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
349
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
350
+ )`,
337
351
  "CREATE INDEX IF NOT EXISTS idx_talker_sessions_phone ON talker_sessions(phone_number)",
338
352
  "CREATE INDEX IF NOT EXISTS idx_talker_sessions_created ON talker_sessions(created_at DESC)",
339
353
  "CREATE INDEX IF NOT EXISTS idx_talker_messages_session ON talker_messages(session_id)",
340
- "CREATE INDEX IF NOT EXISTS idx_talker_messages_ts ON talker_messages(timestamp)"
354
+ "CREATE INDEX IF NOT EXISTS idx_talker_messages_ts ON talker_messages(timestamp)",
355
+ "CREATE INDEX IF NOT EXISTS idx_talker_message_status_phone ON talker_message_status(phone_to)",
356
+ "CREATE INDEX IF NOT EXISTS idx_talker_message_status_created ON talker_message_status(created_at DESC)"
341
357
  ];
342
358
  async function runMigrations() {
343
359
  const client2 = getDbClient();
@@ -1088,6 +1104,47 @@ async function insertMessage(message) {
1088
1104
  return false;
1089
1105
  }
1090
1106
  }
1107
+ async function upsertMessageStatus(record) {
1108
+ const client2 = getDbClient();
1109
+ if (!client2) return false;
1110
+ try {
1111
+ await client2.execute({
1112
+ sql: `
1113
+ INSERT INTO talker_message_status (
1114
+ message_sid, channel, phone_from, phone_to, status,
1115
+ error_code, error_message, updated_at
1116
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
1117
+ ON CONFLICT(message_sid) DO UPDATE SET
1118
+ status = excluded.status,
1119
+ error_code = excluded.error_code,
1120
+ error_message = excluded.error_message,
1121
+ updated_at = excluded.updated_at
1122
+ `,
1123
+ args: [
1124
+ record.messageSid,
1125
+ record.channel,
1126
+ record.from,
1127
+ record.to,
1128
+ record.status,
1129
+ record.errorCode || null,
1130
+ record.errorMessage || null,
1131
+ Date.now()
1132
+ ]
1133
+ });
1134
+ logger.info("message status upserted", {
1135
+ messageSid: record.messageSid,
1136
+ channel: record.channel,
1137
+ status: record.status
1138
+ });
1139
+ return true;
1140
+ } catch (error) {
1141
+ logger.error("failed to upsert message status", {
1142
+ messageSid: record.messageSid,
1143
+ error: error instanceof Error ? error.message : "Unknown"
1144
+ });
1145
+ return false;
1146
+ }
1147
+ }
1091
1148
 
1092
1149
  // src/db/persist.ts
1093
1150
  function persistSession(phoneNumber, channel, conversationId) {
@@ -1921,6 +1978,194 @@ function callRoutes(deps, registry) {
1921
1978
  // src/routes/sms/index.ts
1922
1979
  var import_hono2 = require("hono");
1923
1980
 
1981
+ // src/adapters/twilio.ts
1982
+ function stripWhatsAppPrefix(phoneNumber) {
1983
+ return phoneNumber.replace(/^whatsapp:/, "");
1984
+ }
1985
+ function buildMessageParams(config, to, message, options) {
1986
+ const params = {
1987
+ To: to,
1988
+ Body: message
1989
+ };
1990
+ if (config.messagingServiceSid) {
1991
+ params.MessagingServiceSid = config.messagingServiceSid;
1992
+ } else if (config.phoneNumber) {
1993
+ params.From = config.phoneNumber;
1994
+ }
1995
+ if (options?.statusCallback) {
1996
+ params.StatusCallback = options.statusCallback;
1997
+ }
1998
+ return new URLSearchParams(params);
1999
+ }
2000
+ async function sendSMS(config, to, message, options) {
2001
+ if (!config.accountSid || !config.authToken) {
2002
+ logger.warn("Twilio credentials not configured, skipping SMS send", { to });
2003
+ return false;
2004
+ }
2005
+ if (!config.phoneNumber && !config.messagingServiceSid) {
2006
+ logger.warn("No phone number or messaging service configured, skipping SMS send", { to });
2007
+ return false;
2008
+ }
2009
+ try {
2010
+ const auth = Buffer.from(`${config.accountSid}:${config.authToken}`).toString("base64");
2011
+ const response = await fetch(
2012
+ `https://api.twilio.com/2010-04-01/Accounts/${config.accountSid}/Messages.json`,
2013
+ {
2014
+ method: "POST",
2015
+ headers: {
2016
+ Authorization: `Basic ${auth}`,
2017
+ "Content-Type": "application/x-www-form-urlencoded"
2018
+ },
2019
+ body: buildMessageParams(config, to, message, options)
2020
+ }
2021
+ );
2022
+ if (!response.ok) {
2023
+ const error = await response.text();
2024
+ logger.error("SMS send failed", { to, status: response.status, error });
2025
+ return false;
2026
+ }
2027
+ const data = await response.json();
2028
+ logger.info("SMS sent successfully", { to, messageSid: data.sid });
2029
+ return true;
2030
+ } catch (error) {
2031
+ logger.error("SMS send error", {
2032
+ to,
2033
+ error: error instanceof Error ? error.message : "Unknown"
2034
+ });
2035
+ return false;
2036
+ }
2037
+ }
2038
+ async function sendWhatsApp(config, to, message, options) {
2039
+ if (!config.accountSid || !config.authToken) {
2040
+ logger.warn("Twilio credentials not configured, skipping WhatsApp send", { to });
2041
+ return false;
2042
+ }
2043
+ if (!config.phoneNumber && !config.messagingServiceSid) {
2044
+ logger.warn("No phone number or messaging service configured, skipping WhatsApp send", { to });
2045
+ return false;
2046
+ }
2047
+ try {
2048
+ const auth = Buffer.from(`${config.accountSid}:${config.authToken}`).toString("base64");
2049
+ const whatsappTo = to.startsWith("whatsapp:") ? to : `whatsapp:${to}`;
2050
+ const params = {
2051
+ To: whatsappTo,
2052
+ Body: message
2053
+ };
2054
+ if (config.messagingServiceSid) {
2055
+ params.MessagingServiceSid = config.messagingServiceSid;
2056
+ } else if (config.phoneNumber) {
2057
+ const whatsappFrom = config.phoneNumber.startsWith("whatsapp:") ? config.phoneNumber : `whatsapp:${config.phoneNumber}`;
2058
+ params.From = whatsappFrom;
2059
+ }
2060
+ if (options?.statusCallback) {
2061
+ params.StatusCallback = options.statusCallback;
2062
+ }
2063
+ const response = await fetch(
2064
+ `https://api.twilio.com/2010-04-01/Accounts/${config.accountSid}/Messages.json`,
2065
+ {
2066
+ method: "POST",
2067
+ headers: {
2068
+ Authorization: `Basic ${auth}`,
2069
+ "Content-Type": "application/x-www-form-urlencoded"
2070
+ },
2071
+ body: new URLSearchParams(params)
2072
+ }
2073
+ );
2074
+ if (!response.ok) {
2075
+ const error = await response.text();
2076
+ logger.error("WhatsApp send failed", { to, status: response.status, error });
2077
+ return false;
2078
+ }
2079
+ const data = await response.json();
2080
+ logger.info("WhatsApp message sent successfully", { to, messageSid: data.sid });
2081
+ return true;
2082
+ } catch (error) {
2083
+ logger.error("WhatsApp send error", {
2084
+ to,
2085
+ error: error instanceof Error ? error.message : "Unknown"
2086
+ });
2087
+ return false;
2088
+ }
2089
+ }
2090
+
2091
+ // src/routes/shared/handle-fallback.ts
2092
+ async function handleFallback(c, deps, channel) {
2093
+ const body = await c.req.parseBody();
2094
+ const rawFrom = body.From || "unknown";
2095
+ const phoneNumber = channel === "whatsapp" ? stripWhatsAppPrefix(rawFrom) : rawFrom.trim();
2096
+ const messageBody = body.Body || "";
2097
+ const errorCode = body.ErrorCode;
2098
+ const errorUrl = body.ErrorUrl;
2099
+ logger.error("fallback webhook triggered", {
2100
+ channel,
2101
+ phoneNumber,
2102
+ messageBody: messageBody.substring(0, 100),
2103
+ errorCode,
2104
+ errorUrl
2105
+ });
2106
+ const errorMessage = channel === "whatsapp" ? getWhatsAppPhrase("en", "genericError", deps.config.languageDir) : getSmsPhrase("en", "genericError", deps.config.languageDir);
2107
+ return c.text(messageTwiml(errorMessage), 200, { "Content-Type": "text/xml" });
2108
+ }
2109
+
2110
+ // src/routes/shared/handle-status-callback.ts
2111
+ async function handleStatusCallback(c, deps, channel) {
2112
+ const body = await c.req.parseBody();
2113
+ const messageSid = body.MessageSid || "";
2114
+ const messageStatus = body.MessageStatus || "";
2115
+ const rawFrom = body.From || "";
2116
+ const rawTo = body.To || "";
2117
+ const errorCode = body.ErrorCode;
2118
+ const errorMessage = body.ErrorMessage;
2119
+ const from = channel === "whatsapp" ? stripWhatsAppPrefix(rawFrom) : rawFrom;
2120
+ const to = channel === "whatsapp" ? stripWhatsAppPrefix(rawTo) : rawTo;
2121
+ logger.info("message status callback", {
2122
+ channel,
2123
+ messageSid,
2124
+ messageStatus,
2125
+ from,
2126
+ to,
2127
+ errorCode
2128
+ });
2129
+ if (!messageSid || !messageStatus) {
2130
+ logger.warn("status callback missing required fields", { channel, messageSid, messageStatus });
2131
+ return c.text("", 200);
2132
+ }
2133
+ upsertMessageStatus({
2134
+ messageSid,
2135
+ channel,
2136
+ from,
2137
+ to,
2138
+ status: messageStatus,
2139
+ errorCode,
2140
+ errorMessage
2141
+ }).catch((err) => {
2142
+ logger.error("failed to persist message status", {
2143
+ messageSid,
2144
+ error: getErrorMessage(err)
2145
+ });
2146
+ });
2147
+ if (deps.config.onMessageStatus) {
2148
+ const event = {
2149
+ messageSid,
2150
+ messageStatus,
2151
+ channel,
2152
+ from,
2153
+ to,
2154
+ errorCode,
2155
+ errorMessage
2156
+ };
2157
+ try {
2158
+ await Promise.resolve(deps.config.onMessageStatus(event));
2159
+ } catch (err) {
2160
+ logger.error("onMessageStatus callback error", {
2161
+ messageSid,
2162
+ error: getErrorMessage(err)
2163
+ });
2164
+ }
2165
+ }
2166
+ return c.text("", 200);
2167
+ }
2168
+
1924
2169
  // src/routes/sms/processor.ts
1925
2170
  async function processSms(deps, registry, phoneNumber, messageBody) {
1926
2171
  const incoming = await processIncoming(deps, phoneNumber, messageBody, "sms");
@@ -1985,7 +2230,13 @@ function smsRoutes(deps, registry) {
1985
2230
  app.post("/sms", twilioSignatureMiddleware(authToken, baseUrl));
1986
2231
  app.post("/sms", rateLimitMiddleware(deps.config.rateLimit));
1987
2232
  app.post("/sms", inputSanitizeMiddleware(deps.config.maxInputLength));
2233
+ app.post("/sms/fallback", twilioSignatureMiddleware(authToken, baseUrl));
2234
+ app.post("/sms/fallback", rateLimitMiddleware(deps.config.rateLimit));
2235
+ app.post("/sms/fallback", inputSanitizeMiddleware(deps.config.maxInputLength));
2236
+ app.post("/sms/status", twilioSignatureMiddleware(authToken, baseUrl));
1988
2237
  app.post("/sms", (c) => handleIncomingSMS(c, deps, registry));
2238
+ app.post("/sms/fallback", (c) => handleFallback(c, deps, "sms"));
2239
+ app.post("/sms/status", (c) => handleStatusCallback(c, deps, "sms"));
1989
2240
  app.get("/sms", (c) => c.text("SMS endpoint active"));
1990
2241
  return app;
1991
2242
  }
@@ -1993,89 +2244,6 @@ function smsRoutes(deps, registry) {
1993
2244
  // src/routes/whatsapp/index.ts
1994
2245
  var import_hono3 = require("hono");
1995
2246
 
1996
- // src/adapters/twilio.ts
1997
- function stripWhatsAppPrefix(phoneNumber) {
1998
- return phoneNumber.replace(/^whatsapp:/, "");
1999
- }
2000
- async function sendSMS(config, to, message) {
2001
- if (!config.accountSid || !config.authToken || !config.phoneNumber) {
2002
- logger.warn("Twilio credentials not configured, skipping SMS send", { to });
2003
- return false;
2004
- }
2005
- try {
2006
- const auth = Buffer.from(`${config.accountSid}:${config.authToken}`).toString("base64");
2007
- const response = await fetch(
2008
- `https://api.twilio.com/2010-04-01/Accounts/${config.accountSid}/Messages.json`,
2009
- {
2010
- method: "POST",
2011
- headers: {
2012
- Authorization: `Basic ${auth}`,
2013
- "Content-Type": "application/x-www-form-urlencoded"
2014
- },
2015
- body: new URLSearchParams({
2016
- From: config.phoneNumber,
2017
- To: to,
2018
- Body: message
2019
- })
2020
- }
2021
- );
2022
- if (!response.ok) {
2023
- const error = await response.text();
2024
- logger.error("SMS send failed", { to, status: response.status, error });
2025
- return false;
2026
- }
2027
- const data = await response.json();
2028
- logger.info("SMS sent successfully", { to, messageSid: data.sid });
2029
- return true;
2030
- } catch (error) {
2031
- logger.error("SMS send error", {
2032
- to,
2033
- error: error instanceof Error ? error.message : "Unknown"
2034
- });
2035
- return false;
2036
- }
2037
- }
2038
- async function sendWhatsApp(config, to, message) {
2039
- if (!config.accountSid || !config.authToken || !config.phoneNumber) {
2040
- logger.warn("Twilio credentials not configured, skipping WhatsApp send", { to });
2041
- return false;
2042
- }
2043
- try {
2044
- const auth = Buffer.from(`${config.accountSid}:${config.authToken}`).toString("base64");
2045
- const whatsappTo = to.startsWith("whatsapp:") ? to : `whatsapp:${to}`;
2046
- const whatsappFrom = config.phoneNumber.startsWith("whatsapp:") ? config.phoneNumber : `whatsapp:${config.phoneNumber}`;
2047
- const response = await fetch(
2048
- `https://api.twilio.com/2010-04-01/Accounts/${config.accountSid}/Messages.json`,
2049
- {
2050
- method: "POST",
2051
- headers: {
2052
- Authorization: `Basic ${auth}`,
2053
- "Content-Type": "application/x-www-form-urlencoded"
2054
- },
2055
- body: new URLSearchParams({
2056
- From: whatsappFrom,
2057
- To: whatsappTo,
2058
- Body: message
2059
- })
2060
- }
2061
- );
2062
- if (!response.ok) {
2063
- const error = await response.text();
2064
- logger.error("WhatsApp send failed", { to, status: response.status, error });
2065
- return false;
2066
- }
2067
- const data = await response.json();
2068
- logger.info("WhatsApp message sent successfully", { to, messageSid: data.sid });
2069
- return true;
2070
- } catch (error) {
2071
- logger.error("WhatsApp send error", {
2072
- to,
2073
- error: error instanceof Error ? error.message : "Unknown"
2074
- });
2075
- return false;
2076
- }
2077
- }
2078
-
2079
2247
  // src/routes/whatsapp/processor.ts
2080
2248
  async function processWhatsApp(deps, registry, phoneNumber, messageBody) {
2081
2249
  const incoming = await processIncoming(deps, phoneNumber, messageBody, "whatsapp");
@@ -2147,7 +2315,13 @@ function whatsappRoutes(deps, registry) {
2147
2315
  app.post("/whatsapp", twilioSignatureMiddleware(authToken, baseUrl));
2148
2316
  app.post("/whatsapp", rateLimitMiddleware(deps.config.rateLimit));
2149
2317
  app.post("/whatsapp", inputSanitizeMiddleware(deps.config.maxInputLength));
2318
+ app.post("/whatsapp/fallback", twilioSignatureMiddleware(authToken, baseUrl));
2319
+ app.post("/whatsapp/fallback", rateLimitMiddleware(deps.config.rateLimit));
2320
+ app.post("/whatsapp/fallback", inputSanitizeMiddleware(deps.config.maxInputLength));
2321
+ app.post("/whatsapp/status", twilioSignatureMiddleware(authToken, baseUrl));
2150
2322
  app.post("/whatsapp", (c) => handleIncomingWhatsApp(c, deps, registry));
2323
+ app.post("/whatsapp/fallback", (c) => handleFallback(c, deps, "whatsapp"));
2324
+ app.post("/whatsapp/status", (c) => handleStatusCallback(c, deps, "whatsapp"));
2151
2325
  app.get("/whatsapp", (c) => c.text("WhatsApp endpoint active"));
2152
2326
  return app;
2153
2327
  }
@@ -2274,6 +2448,8 @@ async function createStandaloneServer(config) {
2274
2448
  getSmsPhrase,
2275
2449
  getVoiceConfig,
2276
2450
  getWhatsAppPhrase,
2451
+ handleFallback,
2452
+ handleStatusCallback,
2277
2453
  incrementNoSpeechRetries,
2278
2454
  initDbClient,
2279
2455
  inputSanitizeMiddleware,
@@ -2304,6 +2480,7 @@ async function createStandaloneServer(config) {
2304
2480
  transferTwiml,
2305
2481
  twilioSignatureMiddleware,
2306
2482
  updateFlowParams,
2483
+ upsertMessageStatus,
2307
2484
  validateTwilioSignature,
2308
2485
  whatsappRoutes
2309
2486
  });
package/dist/index.mjs CHANGED
@@ -237,7 +237,7 @@ var SCHEMA_STATEMENTS = [
237
237
  `CREATE TABLE IF NOT EXISTS talker_sessions (
238
238
  id TEXT PRIMARY KEY,
239
239
  phone_number TEXT NOT NULL,
240
- channel TEXT NOT NULL CHECK(channel IN ('call', 'sms')),
240
+ channel TEXT NOT NULL CHECK(channel IN ('call', 'sms', 'whatsapp')),
241
241
  reason TEXT NOT NULL CHECK(reason IN ('ended', 'redirected')),
242
242
  language TEXT NOT NULL,
243
243
  started_at INTEGER NOT NULL,
@@ -257,10 +257,23 @@ var SCHEMA_STATEMENTS = [
257
257
  created_at INTEGER NOT NULL DEFAULT (unixepoch()),
258
258
  FOREIGN KEY (session_id) REFERENCES talker_sessions(id) ON DELETE CASCADE
259
259
  )`,
260
+ `CREATE TABLE IF NOT EXISTS talker_message_status (
261
+ message_sid TEXT PRIMARY KEY,
262
+ channel TEXT NOT NULL CHECK(channel IN ('sms', 'whatsapp')),
263
+ phone_from TEXT NOT NULL,
264
+ phone_to TEXT NOT NULL,
265
+ status TEXT NOT NULL,
266
+ error_code TEXT,
267
+ error_message TEXT,
268
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
269
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
270
+ )`,
260
271
  "CREATE INDEX IF NOT EXISTS idx_talker_sessions_phone ON talker_sessions(phone_number)",
261
272
  "CREATE INDEX IF NOT EXISTS idx_talker_sessions_created ON talker_sessions(created_at DESC)",
262
273
  "CREATE INDEX IF NOT EXISTS idx_talker_messages_session ON talker_messages(session_id)",
263
- "CREATE INDEX IF NOT EXISTS idx_talker_messages_ts ON talker_messages(timestamp)"
274
+ "CREATE INDEX IF NOT EXISTS idx_talker_messages_ts ON talker_messages(timestamp)",
275
+ "CREATE INDEX IF NOT EXISTS idx_talker_message_status_phone ON talker_message_status(phone_to)",
276
+ "CREATE INDEX IF NOT EXISTS idx_talker_message_status_created ON talker_message_status(created_at DESC)"
264
277
  ];
265
278
  async function runMigrations() {
266
279
  const client2 = getDbClient();
@@ -1011,6 +1024,47 @@ async function insertMessage(message) {
1011
1024
  return false;
1012
1025
  }
1013
1026
  }
1027
+ async function upsertMessageStatus(record) {
1028
+ const client2 = getDbClient();
1029
+ if (!client2) return false;
1030
+ try {
1031
+ await client2.execute({
1032
+ sql: `
1033
+ INSERT INTO talker_message_status (
1034
+ message_sid, channel, phone_from, phone_to, status,
1035
+ error_code, error_message, updated_at
1036
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
1037
+ ON CONFLICT(message_sid) DO UPDATE SET
1038
+ status = excluded.status,
1039
+ error_code = excluded.error_code,
1040
+ error_message = excluded.error_message,
1041
+ updated_at = excluded.updated_at
1042
+ `,
1043
+ args: [
1044
+ record.messageSid,
1045
+ record.channel,
1046
+ record.from,
1047
+ record.to,
1048
+ record.status,
1049
+ record.errorCode || null,
1050
+ record.errorMessage || null,
1051
+ Date.now()
1052
+ ]
1053
+ });
1054
+ logger.info("message status upserted", {
1055
+ messageSid: record.messageSid,
1056
+ channel: record.channel,
1057
+ status: record.status
1058
+ });
1059
+ return true;
1060
+ } catch (error) {
1061
+ logger.error("failed to upsert message status", {
1062
+ messageSid: record.messageSid,
1063
+ error: error instanceof Error ? error.message : "Unknown"
1064
+ });
1065
+ return false;
1066
+ }
1067
+ }
1014
1068
 
1015
1069
  // src/db/persist.ts
1016
1070
  function persistSession(phoneNumber, channel, conversationId) {
@@ -1844,6 +1898,194 @@ function callRoutes(deps, registry) {
1844
1898
  // src/routes/sms/index.ts
1845
1899
  import { Hono as Hono2 } from "hono";
1846
1900
 
1901
+ // src/adapters/twilio.ts
1902
+ function stripWhatsAppPrefix(phoneNumber) {
1903
+ return phoneNumber.replace(/^whatsapp:/, "");
1904
+ }
1905
+ function buildMessageParams(config, to, message, options) {
1906
+ const params = {
1907
+ To: to,
1908
+ Body: message
1909
+ };
1910
+ if (config.messagingServiceSid) {
1911
+ params.MessagingServiceSid = config.messagingServiceSid;
1912
+ } else if (config.phoneNumber) {
1913
+ params.From = config.phoneNumber;
1914
+ }
1915
+ if (options?.statusCallback) {
1916
+ params.StatusCallback = options.statusCallback;
1917
+ }
1918
+ return new URLSearchParams(params);
1919
+ }
1920
+ async function sendSMS(config, to, message, options) {
1921
+ if (!config.accountSid || !config.authToken) {
1922
+ logger.warn("Twilio credentials not configured, skipping SMS send", { to });
1923
+ return false;
1924
+ }
1925
+ if (!config.phoneNumber && !config.messagingServiceSid) {
1926
+ logger.warn("No phone number or messaging service configured, skipping SMS send", { to });
1927
+ return false;
1928
+ }
1929
+ try {
1930
+ const auth = Buffer.from(`${config.accountSid}:${config.authToken}`).toString("base64");
1931
+ const response = await fetch(
1932
+ `https://api.twilio.com/2010-04-01/Accounts/${config.accountSid}/Messages.json`,
1933
+ {
1934
+ method: "POST",
1935
+ headers: {
1936
+ Authorization: `Basic ${auth}`,
1937
+ "Content-Type": "application/x-www-form-urlencoded"
1938
+ },
1939
+ body: buildMessageParams(config, to, message, options)
1940
+ }
1941
+ );
1942
+ if (!response.ok) {
1943
+ const error = await response.text();
1944
+ logger.error("SMS send failed", { to, status: response.status, error });
1945
+ return false;
1946
+ }
1947
+ const data = await response.json();
1948
+ logger.info("SMS sent successfully", { to, messageSid: data.sid });
1949
+ return true;
1950
+ } catch (error) {
1951
+ logger.error("SMS send error", {
1952
+ to,
1953
+ error: error instanceof Error ? error.message : "Unknown"
1954
+ });
1955
+ return false;
1956
+ }
1957
+ }
1958
+ async function sendWhatsApp(config, to, message, options) {
1959
+ if (!config.accountSid || !config.authToken) {
1960
+ logger.warn("Twilio credentials not configured, skipping WhatsApp send", { to });
1961
+ return false;
1962
+ }
1963
+ if (!config.phoneNumber && !config.messagingServiceSid) {
1964
+ logger.warn("No phone number or messaging service configured, skipping WhatsApp send", { to });
1965
+ return false;
1966
+ }
1967
+ try {
1968
+ const auth = Buffer.from(`${config.accountSid}:${config.authToken}`).toString("base64");
1969
+ const whatsappTo = to.startsWith("whatsapp:") ? to : `whatsapp:${to}`;
1970
+ const params = {
1971
+ To: whatsappTo,
1972
+ Body: message
1973
+ };
1974
+ if (config.messagingServiceSid) {
1975
+ params.MessagingServiceSid = config.messagingServiceSid;
1976
+ } else if (config.phoneNumber) {
1977
+ const whatsappFrom = config.phoneNumber.startsWith("whatsapp:") ? config.phoneNumber : `whatsapp:${config.phoneNumber}`;
1978
+ params.From = whatsappFrom;
1979
+ }
1980
+ if (options?.statusCallback) {
1981
+ params.StatusCallback = options.statusCallback;
1982
+ }
1983
+ const response = await fetch(
1984
+ `https://api.twilio.com/2010-04-01/Accounts/${config.accountSid}/Messages.json`,
1985
+ {
1986
+ method: "POST",
1987
+ headers: {
1988
+ Authorization: `Basic ${auth}`,
1989
+ "Content-Type": "application/x-www-form-urlencoded"
1990
+ },
1991
+ body: new URLSearchParams(params)
1992
+ }
1993
+ );
1994
+ if (!response.ok) {
1995
+ const error = await response.text();
1996
+ logger.error("WhatsApp send failed", { to, status: response.status, error });
1997
+ return false;
1998
+ }
1999
+ const data = await response.json();
2000
+ logger.info("WhatsApp message sent successfully", { to, messageSid: data.sid });
2001
+ return true;
2002
+ } catch (error) {
2003
+ logger.error("WhatsApp send error", {
2004
+ to,
2005
+ error: error instanceof Error ? error.message : "Unknown"
2006
+ });
2007
+ return false;
2008
+ }
2009
+ }
2010
+
2011
+ // src/routes/shared/handle-fallback.ts
2012
+ async function handleFallback(c, deps, channel) {
2013
+ const body = await c.req.parseBody();
2014
+ const rawFrom = body.From || "unknown";
2015
+ const phoneNumber = channel === "whatsapp" ? stripWhatsAppPrefix(rawFrom) : rawFrom.trim();
2016
+ const messageBody = body.Body || "";
2017
+ const errorCode = body.ErrorCode;
2018
+ const errorUrl = body.ErrorUrl;
2019
+ logger.error("fallback webhook triggered", {
2020
+ channel,
2021
+ phoneNumber,
2022
+ messageBody: messageBody.substring(0, 100),
2023
+ errorCode,
2024
+ errorUrl
2025
+ });
2026
+ const errorMessage = channel === "whatsapp" ? getWhatsAppPhrase("en", "genericError", deps.config.languageDir) : getSmsPhrase("en", "genericError", deps.config.languageDir);
2027
+ return c.text(messageTwiml(errorMessage), 200, { "Content-Type": "text/xml" });
2028
+ }
2029
+
2030
+ // src/routes/shared/handle-status-callback.ts
2031
+ async function handleStatusCallback(c, deps, channel) {
2032
+ const body = await c.req.parseBody();
2033
+ const messageSid = body.MessageSid || "";
2034
+ const messageStatus = body.MessageStatus || "";
2035
+ const rawFrom = body.From || "";
2036
+ const rawTo = body.To || "";
2037
+ const errorCode = body.ErrorCode;
2038
+ const errorMessage = body.ErrorMessage;
2039
+ const from = channel === "whatsapp" ? stripWhatsAppPrefix(rawFrom) : rawFrom;
2040
+ const to = channel === "whatsapp" ? stripWhatsAppPrefix(rawTo) : rawTo;
2041
+ logger.info("message status callback", {
2042
+ channel,
2043
+ messageSid,
2044
+ messageStatus,
2045
+ from,
2046
+ to,
2047
+ errorCode
2048
+ });
2049
+ if (!messageSid || !messageStatus) {
2050
+ logger.warn("status callback missing required fields", { channel, messageSid, messageStatus });
2051
+ return c.text("", 200);
2052
+ }
2053
+ upsertMessageStatus({
2054
+ messageSid,
2055
+ channel,
2056
+ from,
2057
+ to,
2058
+ status: messageStatus,
2059
+ errorCode,
2060
+ errorMessage
2061
+ }).catch((err) => {
2062
+ logger.error("failed to persist message status", {
2063
+ messageSid,
2064
+ error: getErrorMessage(err)
2065
+ });
2066
+ });
2067
+ if (deps.config.onMessageStatus) {
2068
+ const event = {
2069
+ messageSid,
2070
+ messageStatus,
2071
+ channel,
2072
+ from,
2073
+ to,
2074
+ errorCode,
2075
+ errorMessage
2076
+ };
2077
+ try {
2078
+ await Promise.resolve(deps.config.onMessageStatus(event));
2079
+ } catch (err) {
2080
+ logger.error("onMessageStatus callback error", {
2081
+ messageSid,
2082
+ error: getErrorMessage(err)
2083
+ });
2084
+ }
2085
+ }
2086
+ return c.text("", 200);
2087
+ }
2088
+
1847
2089
  // src/routes/sms/processor.ts
1848
2090
  async function processSms(deps, registry, phoneNumber, messageBody) {
1849
2091
  const incoming = await processIncoming(deps, phoneNumber, messageBody, "sms");
@@ -1908,7 +2150,13 @@ function smsRoutes(deps, registry) {
1908
2150
  app.post("/sms", twilioSignatureMiddleware(authToken, baseUrl));
1909
2151
  app.post("/sms", rateLimitMiddleware(deps.config.rateLimit));
1910
2152
  app.post("/sms", inputSanitizeMiddleware(deps.config.maxInputLength));
2153
+ app.post("/sms/fallback", twilioSignatureMiddleware(authToken, baseUrl));
2154
+ app.post("/sms/fallback", rateLimitMiddleware(deps.config.rateLimit));
2155
+ app.post("/sms/fallback", inputSanitizeMiddleware(deps.config.maxInputLength));
2156
+ app.post("/sms/status", twilioSignatureMiddleware(authToken, baseUrl));
1911
2157
  app.post("/sms", (c) => handleIncomingSMS(c, deps, registry));
2158
+ app.post("/sms/fallback", (c) => handleFallback(c, deps, "sms"));
2159
+ app.post("/sms/status", (c) => handleStatusCallback(c, deps, "sms"));
1912
2160
  app.get("/sms", (c) => c.text("SMS endpoint active"));
1913
2161
  return app;
1914
2162
  }
@@ -1916,89 +2164,6 @@ function smsRoutes(deps, registry) {
1916
2164
  // src/routes/whatsapp/index.ts
1917
2165
  import { Hono as Hono3 } from "hono";
1918
2166
 
1919
- // src/adapters/twilio.ts
1920
- function stripWhatsAppPrefix(phoneNumber) {
1921
- return phoneNumber.replace(/^whatsapp:/, "");
1922
- }
1923
- async function sendSMS(config, to, message) {
1924
- if (!config.accountSid || !config.authToken || !config.phoneNumber) {
1925
- logger.warn("Twilio credentials not configured, skipping SMS send", { to });
1926
- return false;
1927
- }
1928
- try {
1929
- const auth = Buffer.from(`${config.accountSid}:${config.authToken}`).toString("base64");
1930
- const response = await fetch(
1931
- `https://api.twilio.com/2010-04-01/Accounts/${config.accountSid}/Messages.json`,
1932
- {
1933
- method: "POST",
1934
- headers: {
1935
- Authorization: `Basic ${auth}`,
1936
- "Content-Type": "application/x-www-form-urlencoded"
1937
- },
1938
- body: new URLSearchParams({
1939
- From: config.phoneNumber,
1940
- To: to,
1941
- Body: message
1942
- })
1943
- }
1944
- );
1945
- if (!response.ok) {
1946
- const error = await response.text();
1947
- logger.error("SMS send failed", { to, status: response.status, error });
1948
- return false;
1949
- }
1950
- const data = await response.json();
1951
- logger.info("SMS sent successfully", { to, messageSid: data.sid });
1952
- return true;
1953
- } catch (error) {
1954
- logger.error("SMS send error", {
1955
- to,
1956
- error: error instanceof Error ? error.message : "Unknown"
1957
- });
1958
- return false;
1959
- }
1960
- }
1961
- async function sendWhatsApp(config, to, message) {
1962
- if (!config.accountSid || !config.authToken || !config.phoneNumber) {
1963
- logger.warn("Twilio credentials not configured, skipping WhatsApp send", { to });
1964
- return false;
1965
- }
1966
- try {
1967
- const auth = Buffer.from(`${config.accountSid}:${config.authToken}`).toString("base64");
1968
- const whatsappTo = to.startsWith("whatsapp:") ? to : `whatsapp:${to}`;
1969
- const whatsappFrom = config.phoneNumber.startsWith("whatsapp:") ? config.phoneNumber : `whatsapp:${config.phoneNumber}`;
1970
- const response = await fetch(
1971
- `https://api.twilio.com/2010-04-01/Accounts/${config.accountSid}/Messages.json`,
1972
- {
1973
- method: "POST",
1974
- headers: {
1975
- Authorization: `Basic ${auth}`,
1976
- "Content-Type": "application/x-www-form-urlencoded"
1977
- },
1978
- body: new URLSearchParams({
1979
- From: whatsappFrom,
1980
- To: whatsappTo,
1981
- Body: message
1982
- })
1983
- }
1984
- );
1985
- if (!response.ok) {
1986
- const error = await response.text();
1987
- logger.error("WhatsApp send failed", { to, status: response.status, error });
1988
- return false;
1989
- }
1990
- const data = await response.json();
1991
- logger.info("WhatsApp message sent successfully", { to, messageSid: data.sid });
1992
- return true;
1993
- } catch (error) {
1994
- logger.error("WhatsApp send error", {
1995
- to,
1996
- error: error instanceof Error ? error.message : "Unknown"
1997
- });
1998
- return false;
1999
- }
2000
- }
2001
-
2002
2167
  // src/routes/whatsapp/processor.ts
2003
2168
  async function processWhatsApp(deps, registry, phoneNumber, messageBody) {
2004
2169
  const incoming = await processIncoming(deps, phoneNumber, messageBody, "whatsapp");
@@ -2070,7 +2235,13 @@ function whatsappRoutes(deps, registry) {
2070
2235
  app.post("/whatsapp", twilioSignatureMiddleware(authToken, baseUrl));
2071
2236
  app.post("/whatsapp", rateLimitMiddleware(deps.config.rateLimit));
2072
2237
  app.post("/whatsapp", inputSanitizeMiddleware(deps.config.maxInputLength));
2238
+ app.post("/whatsapp/fallback", twilioSignatureMiddleware(authToken, baseUrl));
2239
+ app.post("/whatsapp/fallback", rateLimitMiddleware(deps.config.rateLimit));
2240
+ app.post("/whatsapp/fallback", inputSanitizeMiddleware(deps.config.maxInputLength));
2241
+ app.post("/whatsapp/status", twilioSignatureMiddleware(authToken, baseUrl));
2073
2242
  app.post("/whatsapp", (c) => handleIncomingWhatsApp(c, deps, registry));
2243
+ app.post("/whatsapp/fallback", (c) => handleFallback(c, deps, "whatsapp"));
2244
+ app.post("/whatsapp/status", (c) => handleStatusCallback(c, deps, "whatsapp"));
2074
2245
  app.get("/whatsapp", (c) => c.text("WhatsApp endpoint active"));
2075
2246
  return app;
2076
2247
  }
@@ -2196,6 +2367,8 @@ export {
2196
2367
  getSmsPhrase,
2197
2368
  getVoiceConfig,
2198
2369
  getWhatsAppPhrase,
2370
+ handleFallback,
2371
+ handleStatusCallback,
2199
2372
  incrementNoSpeechRetries,
2200
2373
  initDbClient,
2201
2374
  inputSanitizeMiddleware,
@@ -2226,6 +2399,7 @@ export {
2226
2399
  transferTwiml,
2227
2400
  twilioSignatureMiddleware,
2228
2401
  updateFlowParams,
2402
+ upsertMessageStatus,
2229
2403
  validateTwilioSignature,
2230
2404
  whatsappRoutes
2231
2405
  };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared Fallback Handler
3
+ *
4
+ * Handles POST /sms/fallback and /whatsapp/fallback — called by Twilio
5
+ * when the primary incoming message webhook URL cannot be reached or
6
+ * throws a runtime exception.
7
+ *
8
+ * Twilio sends the same payload as the incoming message webhook.
9
+ * The fallback handler responds with a safe error message so the
10
+ * end user is not left without a response.
11
+ */
12
+ import type { Context } from "hono";
13
+ import type { TalkerDependencies } from "../../types";
14
+ /**
15
+ * Handle a fallback webhook from Twilio.
16
+ * Called when the primary incoming URL fails.
17
+ * Returns a safe error message TwiML to the user.
18
+ */
19
+ export declare function handleFallback(c: Context, deps: TalkerDependencies, channel: "sms" | "whatsapp"): Promise<Response>;
20
+ //# sourceMappingURL=handle-fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-fallback.d.ts","sourceRoot":"","sources":["../../../src/routes/shared/handle-fallback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAKpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,CAAC,EAAE,OAAO,EACV,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,KAAK,GAAG,UAAU,GAC1B,OAAO,CAAC,QAAQ,CAAC,CAwBnB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Fallback Handler Tests
3
+ *
4
+ * Tests for the shared fallback webhook handler.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=handle-fallback.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-fallback.test.d.ts","sourceRoot":"","sources":["../../../src/routes/shared/handle-fallback.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shared Message Status Callback Handler
3
+ *
4
+ * Handles POST /sms/status and /whatsapp/status — called by Twilio
5
+ * when a message delivery status changes (queued, sent, delivered,
6
+ * undelivered, failed, read).
7
+ *
8
+ * Twilio sends these fields (among others):
9
+ * - MessageSid: unique message identifier
10
+ * - MessageStatus: queued | sending | sent | delivered | undelivered | failed | read
11
+ * - From: sender phone number
12
+ * - To: recipient phone number
13
+ * - ErrorCode: Twilio error code (only on failure)
14
+ * - ErrorMessage: human-readable error (only on failure)
15
+ */
16
+ import type { Context } from "hono";
17
+ import type { TalkerDependencies } from "../../types";
18
+ /**
19
+ * Handle a message status callback from Twilio.
20
+ * Shared by both SMS and WhatsApp status endpoints.
21
+ */
22
+ export declare function handleStatusCallback(c: Context, deps: TalkerDependencies, channel: "sms" | "whatsapp"): Promise<Response>;
23
+ //# sourceMappingURL=handle-status-callback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-status-callback.d.ts","sourceRoot":"","sources":["../../../src/routes/shared/handle-status-callback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAKpC,OAAO,KAAK,EAA+B,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEnF;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,CAAC,EAAE,OAAO,EACV,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,KAAK,GAAG,UAAU,GAC1B,OAAO,CAAC,QAAQ,CAAC,CAoEnB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Status Callback Handler Tests
3
+ *
4
+ * Tests for the shared message status callback handler.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=handle-status-callback.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-status-callback.test.d.ts","sourceRoot":"","sources":["../../../src/routes/shared/handle-status-callback.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shared Route Handlers
3
+ *
4
+ * Handlers shared across SMS and WhatsApp channels.
5
+ */
6
+ export { handleStatusCallback } from "./handle-status-callback";
7
+ export { handleFallback } from "./handle-fallback";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/shared/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
@@ -2,6 +2,12 @@
2
2
  * SMS Routes
3
3
  *
4
4
  * Hono route factory for SMS webhooks.
5
+ *
6
+ * Endpoints:
7
+ * - POST /sms — Incoming message webhook
8
+ * - POST /sms/fallback — Fallback when incoming URL fails
9
+ * - POST /sms/status — Message delivery status callback
10
+ * - GET /sms — Health check
5
11
  */
6
12
  import { Hono } from "hono";
7
13
  import type { FlowRegistry } from "../../flows/registry";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/sms/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtD;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,YAAY,8EAczE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/sms/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAKtD;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,YAAY,8EA6BzE"}
@@ -3,6 +3,12 @@
3
3
  *
4
4
  * Hono route factory for WhatsApp webhooks.
5
5
  * Twilio uses the same TwiML response format for WhatsApp as it does for SMS.
6
+ *
7
+ * Endpoints:
8
+ * - POST /whatsapp — Incoming message webhook
9
+ * - POST /whatsapp/fallback — Fallback when incoming URL fails
10
+ * - POST /whatsapp/status — Message delivery status callback
11
+ * - GET /whatsapp — Health check
6
12
  */
7
13
  import { Hono } from "hono";
8
14
  import type { FlowRegistry } from "../../flows/registry";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/whatsapp/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,YAAY,8EAc9E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/whatsapp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAKtD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,YAAY,8EA6B9E"}
package/dist/types.d.ts CHANGED
@@ -26,8 +26,34 @@ export interface TwilioConfig {
26
26
  accountSid?: string;
27
27
  /** Twilio auth token */
28
28
  authToken?: string;
29
- /** Twilio phone number for outbound SMS */
29
+ /** Twilio phone number for outbound SMS/WhatsApp */
30
30
  phoneNumber?: string;
31
+ /**
32
+ * Twilio Messaging Service SID.
33
+ * When set, outbound messages use MessagingServiceSid instead of From.
34
+ * This enables features like sender pool, sticky sender, and compliance.
35
+ */
36
+ messagingServiceSid?: string;
37
+ }
38
+ /**
39
+ * Status callback event from Twilio.
40
+ * Received at /sms/status and /whatsapp/status endpoints.
41
+ */
42
+ export interface MessageStatusEvent {
43
+ /** Twilio message SID */
44
+ messageSid: string;
45
+ /** Message status: queued, sent, delivered, undelivered, failed, read */
46
+ messageStatus: string;
47
+ /** Channel the message was sent on */
48
+ channel: "sms" | "whatsapp";
49
+ /** Sender phone number */
50
+ from: string;
51
+ /** Recipient phone number */
52
+ to: string;
53
+ /** Twilio error code (if failed/undelivered) */
54
+ errorCode?: string;
55
+ /** Twilio error message (if failed/undelivered) */
56
+ errorMessage?: string;
31
57
  }
32
58
  /**
33
59
  * Remote chatbot API configuration (standalone mode)
@@ -116,6 +142,11 @@ export interface TalkerConfig {
116
142
  maxInputLength?: number;
117
143
  /** Chat function override. By default, talker queries chatter's RAG pipeline directly */
118
144
  chatFn?: (phoneNumber: string, message: string) => Promise<string>;
145
+ /**
146
+ * Callback invoked when a message delivery status update is received.
147
+ * Called for both SMS and WhatsApp status callbacks.
148
+ */
149
+ onMessageStatus?: (event: MessageStatusEvent) => void | Promise<void>;
119
150
  }
120
151
  /**
121
152
  * Dependencies available to talker routes and handlers
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diegoaltoworks/talker",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Telephony plugin for Chatter — adds voice call and SMS support via Twilio",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",