Tighten types for Twilio requests and sender lookup

This commit is contained in:
Peter Steinberger
2025-11-24 12:53:09 +01:00
parent eb1c4ae7cf
commit 3775caa72d

View File

@@ -38,6 +38,25 @@ type AuthMode =
| { accountSid: string; authToken: string } | { accountSid: string; authToken: string }
| { accountSid: string; apiKey: string; apiSecret: string }; | { accountSid: string; apiKey: string; apiSecret: string };
type TwilioRequestOptions = {
method: 'get' | 'post';
uri: string;
params?: Record<string, string | number>;
form?: Record<string, string>;
};
type TwilioSender = { sid: string; sender_id: string };
type TwilioRequestResponse = {
data?: {
senders?: TwilioSender[];
};
};
type TwilioRequester = {
request: (options: TwilioRequestOptions) => Promise<TwilioRequestResponse>;
};
type GlobalOptions = { type GlobalOptions = {
verbose: boolean; verbose: boolean;
yes?: boolean; yes?: boolean;
@@ -449,26 +468,18 @@ async function ensureFunnel(port: number) {
async function findWhatsappSenderSid(client: ReturnType<typeof createClient>, from: string) { async function findWhatsappSenderSid(client: ReturnType<typeof createClient>, from: string) {
// Fetch sender SID that matches configured WhatsApp from number. // Fetch sender SID that matches configured WhatsApp from number.
try { try {
const resp = await (client as unknown as { const resp = await (client as unknown as TwilioRequester).request({
request: (options: Record<string, unknown>) => Promise<{ data?: unknown }>
}).request({
method: 'get', method: 'get',
uri: 'https://messaging.twilio.com/v2/Channels/Senders', uri: 'https://messaging.twilio.com/v2/Channels/Senders',
params: { Channel: 'whatsapp', PageSize: 50 } params: { Channel: 'whatsapp', PageSize: 50 }
}); });
const data = resp?.data as Record<string, unknown> | undefined; const senders = resp.data?.senders;
const senders = Array.isArray((data as Record<string, unknown> | undefined)?.senders)
? (data as { senders: unknown[] }).senders
: undefined;
if (!senders) { if (!senders) {
throw new Error('List senders response missing "senders" array'); throw new Error('List senders response missing "senders" array');
} }
const match = senders.find( const match = senders.find(
(s) => (s) => typeof s?.sender_id === 'string' && s.sender_id === withWhatsAppPrefix(from)
typeof s === 'object' && );
s !== null &&
(s as Record<string, unknown>).sender_id === withWhatsAppPrefix(from)
) as { sid?: string } | undefined;
if (!match || typeof match.sid !== 'string') { if (!match || typeof match.sid !== 'string') {
throw new Error(`Could not find sender ${withWhatsAppPrefix(from)} in Twilio account`); throw new Error(`Could not find sender ${withWhatsAppPrefix(from)} in Twilio account`);
} }
@@ -492,7 +503,7 @@ async function updateWebhook(
method: 'POST' | 'GET' = 'POST' method: 'POST' | 'GET' = 'POST'
) { ) {
// Point Twilio sender webhook at the provided URL. // Point Twilio sender webhook at the provided URL.
await (client as unknown as { request: (options: Record<string, unknown>) => Promise<unknown> }) await (client as unknown as TwilioRequester)
.request({ .request({
method: 'post', method: 'post',
uri: `https://messaging.twilio.com/v2/Channels/Senders/${senderSid}`, uri: `https://messaging.twilio.com/v2/Channels/Senders/${senderSid}`,