feat(webhook): added whatsapp block/tool, added scaffolding for webhooks with modal, added webhooks table and ran migrations

This commit is contained in:
Waleed Latif
2025-03-07 13:22:12 -08:00
parent c2406c4eb6
commit cee341ff80
20 changed files with 1881 additions and 11 deletions

View File

@@ -36,6 +36,7 @@ import { extractTool as tavilyExtract } from './tavily/extract'
import { searchTool as tavilySearch } from './tavily/search'
import { ToolConfig, ToolResponse } from './types'
import { executeRequest, formatRequestParams, validateToolRequest } from './utils'
import { WhatsAppTool } from './whatsapp'
import { readTool as xRead } from './x/read'
import { searchTool as xSearch } from './x/search'
import { userTool as xUser } from './x/user'
@@ -64,6 +65,7 @@ export const tools: Record<string, ToolConfig> = {
gmail_send: gmailSendTool,
gmail_read: gmailReadTool,
gmail_search: gmailSearchTool,
whatsapp: WhatsAppTool,
x_write: xWrite,
x_read: xRead,
x_search: xSearch,

78
tools/whatsapp/index.ts Normal file
View File

@@ -0,0 +1,78 @@
import { ToolConfig } from '../types'
import { WhatsAppToolResponse } from './types'
export const WhatsAppTool: ToolConfig<any, WhatsAppToolResponse> = {
id: 'whatsapp',
name: 'WhatsApp',
description: 'Send WhatsApp messages',
version: '1.0.0',
params: {
phoneNumber: {
type: 'string',
required: true,
description: 'Recipient phone number with country code',
},
message: {
type: 'string',
required: true,
description: 'Message content to send',
},
phoneNumberId: {
type: 'string',
required: true,
description: 'WhatsApp Business Phone Number ID',
},
accessToken: {
type: 'string',
required: true,
description: 'WhatsApp Business API Access Token',
},
},
request: {
url: (params) => `https://graph.facebook.com/v18.0/${params.phoneNumberId}/messages`,
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
}),
body: (params) => {
// Format the phone number (remove + if present)
const formattedPhoneNumber = params.phoneNumber.startsWith('+')
? params.phoneNumber.substring(1)
: params.phoneNumber
return {
messaging_product: 'whatsapp',
recipient_type: 'individual',
to: formattedPhoneNumber,
type: 'text',
text: {
body: params.message,
},
}
},
},
transformResponse: async (response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error?.message || 'Failed to send WhatsApp message')
}
return {
success: true,
output: {
success: true,
messageId: data.messages?.[0]?.id,
},
error: undefined,
}
},
transformError: (error) => {
return error.message || 'Unknown error occurred'
},
}

9
tools/whatsapp/types.ts Normal file
View File

@@ -0,0 +1,9 @@
import { ToolResponse } from '../types'
export interface WhatsAppToolResponse extends ToolResponse {
output: {
success: boolean
messageId?: string
error?: string
}
}