diff --git a/hermes-k8s.yaml b/hermes-k8s.yaml index 1131c31..1c7ced5 100644 --- a/hermes-k8s.yaml +++ b/hermes-k8s.yaml @@ -22,7 +22,7 @@ spec: fsGroup: 1000 containers: - name: hermes-mcp - image: localhost:32000/hermes-mcp@sha256:6685df4c86cceeaeb645c9ccee32f9396915a7c30e57f685945056c92516723d + image: localhost:32000/hermes-mcp@sha256:0132eade2173eae3428a24757d2228253acf3f924f7a6c7a061f088e8d0dc891 imagePullPolicy: Always securityContext: allowPrivilegeEscalation: false diff --git a/src/clients/whatsapp.ts b/src/clients/whatsapp.ts index 36f5029..dd699aa 100644 --- a/src/clients/whatsapp.ts +++ b/src/clients/whatsapp.ts @@ -113,15 +113,19 @@ async function whatsappApiRequest( async function resolveWhatsAppCreds( args: { account?: string }, customer?: Customer -): Promise<{ phoneId: string; accessToken: string; businessAccountId: string }> { +): Promise<{ phoneId: string; accessToken: string; businessAccountId: string; usingDefault: boolean }> { if (customer) { const creds = await customer.getCredential('whatsapp'); - if (!creds) throw new Error('WhatsApp not connected for this account'); - return { - phoneId: creds.phoneNumberId, - accessToken: creds.accessToken, - businessAccountId: creds.businessAccountId, - }; + if (creds) { + return { + phoneId: creds.phoneNumberId, + accessToken: creds.accessToken, + businessAccountId: creds.businessAccountId, + usingDefault: false, + }; + } + // No WhatsApp connected — fall back to default env var account (Twilio-routed) + console.log(`[whatsapp] customer ${customer.id} has no WhatsApp creds, falling back to default`); } const account = args.account ?? 'default'; const phoneId = getPhoneNumberId(account); @@ -130,7 +134,7 @@ async function resolveWhatsAppCreds( if (!phoneId || !accessToken) { throw new Error('Missing WhatsApp credentials. Set WHATSAPP_{ACCOUNT}_PHONE_NUMBER_ID and WHATSAPP_{ACCOUNT}_ACCESS_TOKEN'); } - return { phoneId, accessToken, businessAccountId }; + return { phoneId, accessToken, businessAccountId, usingDefault: true }; } export async function sendMessage( @@ -140,7 +144,7 @@ export async function sendMessage( const audit = customer ? createToolAudit(customer.id, 'whatsapp:sendMessage') : null; const auditArgs = { to: args.to }; - const { phoneId, accessToken } = await resolveWhatsAppCreds(args, customer); + const { phoneId, accessToken, usingDefault } = await resolveWhatsAppCreds(args, customer); const body = { messaging_product: 'whatsapp', @@ -151,7 +155,7 @@ export async function sendMessage( try { let result: { success: boolean; message_id: string }; - if (!customer && isTwilioAccount(args.account ?? 'default')) { + if (usingDefault && isTwilioAccount('default')) { result = await twilioSend(args.to, args.message); } else { const data = await whatsappApiRequest(phoneId, accessToken, 'messages', 'POST', body); @@ -173,7 +177,7 @@ export async function sendTemplate( const audit = customer ? createToolAudit(customer.id, 'whatsapp:sendTemplate') : null; const auditArgs = { to: args.to, template_name: args.template_name }; - const { phoneId, accessToken, businessAccountId } = await resolveWhatsAppCreds(args, customer); + const { phoneId, accessToken, businessAccountId, usingDefault } = await resolveWhatsAppCreds(args, customer); const body: Record = { messaging_product: 'whatsapp', @@ -191,7 +195,7 @@ export async function sendTemplate( try { let result: { success: boolean; message_id: string }; - if (!customer && isTwilioAccount(args.account ?? 'default')) { + if (usingDefault && isTwilioAccount('default')) { const text = await resolveTemplateText( businessAccountId, accessToken,