fix(whatsapp): fall back to default Twilio account when customer has no WhatsApp creds
Customers who haven't connected WhatsApp in the dashboard now automatically use the SquareMCP default number (+19547385805 via Twilio) instead of throwing 'WhatsApp not connected'. Routing flag usingDefault replaces the !customer check so OAuth sessions get the same Twilio path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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<WhatsAppCredentials>('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<string, unknown> = {
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user