From f8adace06d9d97c017c53a054555669df38b7305 Mon Sep 17 00:00:00 2001 From: quu-ack Date: Tue, 25 Nov 2025 15:20:58 -0500 Subject: [PATCH 1/2] feat(integration/whatsapp): allows image caption retrieval --- integrations/whatsapp/integration.definition.ts | 7 ++++++- .../whatsapp/src/channels/message-types/image.ts | 3 ++- integrations/whatsapp/src/webhook/handlers/messages.ts | 9 ++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/integrations/whatsapp/integration.definition.ts b/integrations/whatsapp/integration.definition.ts index 8716cdc9bcf..a7235cc38ca 100644 --- a/integrations/whatsapp/integration.definition.ts +++ b/integrations/whatsapp/integration.definition.ts @@ -95,7 +95,7 @@ const defaultBotPhoneNumberId = { export const INTEGRATION_NAME = 'whatsapp' export default new IntegrationDefinition({ name: INTEGRATION_NAME, - version: '4.5.16', + version: '4.5.17', title: 'WhatsApp', description: 'Send and receive messages through WhatsApp.', icon: 'icon.svg', @@ -190,6 +190,11 @@ export default new IntegrationDefinition({ filename: z.string().optional(), }), }, + image: { + schema: messages.defaults.image.schema.extend({ + caption: z.string().optional(), + }), + }, bloc: { schema: z.object({ items: z.array( diff --git a/integrations/whatsapp/src/channels/message-types/image.ts b/integrations/whatsapp/src/channels/message-types/image.ts index f9af020fe0d..9227c00eff4 100644 --- a/integrations/whatsapp/src/channels/message-types/image.ts +++ b/integrations/whatsapp/src/channels/message-types/image.ts @@ -73,7 +73,8 @@ export async function generateOutgoingMessage({ function _generateImage(payload: Image, logger: bp.Logger): WhatsappMessages.Image | undefined { logger.forBot().debug('Sending WhatsApp Image') const url = payload.imageUrl.trim() - return new WhatsappMessages.Image(url, false) + const caption = payload.caption + return new WhatsappMessages.Image(url, false, caption) } async function _generateSticker(payload: Image, logger: bp.Logger): Promise { diff --git a/integrations/whatsapp/src/webhook/handlers/messages.ts b/integrations/whatsapp/src/webhook/handlers/messages.ts index 4fcfa63b308..955053a9688 100644 --- a/integrations/whatsapp/src/webhook/handlers/messages.ts +++ b/integrations/whatsapp/src/webhook/handlers/messages.ts @@ -134,7 +134,14 @@ async function _handleIncomingMessage( }) } else if (type === 'image') { const imageUrl = await _getOrDownloadWhatsappMedia(message.image.id, client, ctx) - await createMessage({ type, payload: { imageUrl }, replyTo }) + await createMessage({ + type, + payload: { + imageUrl, + ...(message.image.caption && { caption: message.image.caption }), + }, + replyTo, + }) } else if (type === 'sticker') { const stickerUrl = await _getOrDownloadWhatsappMedia(message.sticker.id, client, ctx) await createMessage({ type: 'image', payload: { imageUrl: stickerUrl }, replyTo }) From 9c5b1209ea497caf7c87ebf61cdb5a22ef08ed2c Mon Sep 17 00:00:00 2001 From: quu-ack Date: Tue, 25 Nov 2025 16:20:16 -0500 Subject: [PATCH 2/2] fix(integration/gmail): fix phrasing for actions + remove console logs --- .../gmail/definitions/configuration.ts | 6 ++++-- integrations/gmail/integration.definition.ts | 2 +- integrations/gmail/src/channels/channels.ts | 11 +++++----- .../gmail/src/webhook-events/handler.ts | 2 -- .../gmail/src/webhook-events/new-mail.ts | 20 +------------------ .../src/webhook-events/oauth-callback.ts | 4 ---- 6 files changed, 11 insertions(+), 34 deletions(-) diff --git a/integrations/gmail/definitions/configuration.ts b/integrations/gmail/definitions/configuration.ts index 2b12daeeb51..155381b45b7 100644 --- a/integrations/gmail/definitions/configuration.ts +++ b/integrations/gmail/definitions/configuration.ts @@ -40,12 +40,14 @@ export const configurations = { .string() .min(1) .title('Pub/Sub Webhook Shared Secret') - .describe('Must be set in GCC under Pub/Sub > Subscriptions'), + .describe( + 'Must be set in GCC under Pub/Sub > Subscriptions > Details > Push endpoint (in the URL is the shared secret)' + ), pubsubWebhookServiceAccount: z .string() .min(1) .title('Pub/Sub Webhook Service Account') - .describe('Must be set in GCC under Pub/Sub > Subscriptions'), + .describe('Must be set in GCC under Pub/Sub > Subscriptions > Details > Service account'), }), }, } as const satisfies sdk.IntegrationDefinitionProps['configurations'] diff --git a/integrations/gmail/integration.definition.ts b/integrations/gmail/integration.definition.ts index da6edfb6bc5..026f83ecfef 100644 --- a/integrations/gmail/integration.definition.ts +++ b/integrations/gmail/integration.definition.ts @@ -13,7 +13,7 @@ import { export default new sdk.IntegrationDefinition({ name: 'gmail', - version: '0.6.2', + version: '0.6.3', title: 'Gmail', description: "Send, receive, and manage emails directly within your bot's workflow.", icon: 'icon.svg', diff --git a/integrations/gmail/src/channels/channels.ts b/integrations/gmail/src/channels/channels.ts index cba65d5d099..ee8dee2e4d7 100644 --- a/integrations/gmail/src/channels/channels.ts +++ b/integrations/gmail/src/channels/channels.ts @@ -144,20 +144,21 @@ export const channels = { const _sendEmailReply = async ({ conversation, + logger, ack, textContent, htmlContent, inReplyTo, googleClient, }: bp.AnyMessageProps & { + logger: bp.Logger textContent: string htmlContent?: string inReplyTo: string googleClient: GoogleClient }) => { - const { threadId, email, subject, references, cc } = _getConversationInfo(conversation) + const { threadId, email, subject, references, cc } = _getConversationInfo(conversation, logger) - console.info('Creating mail') const raw = await composeRawEmail({ to: email, subject, @@ -168,20 +169,18 @@ const _sendEmailReply = async ({ references: references ?? inReplyTo, cc, }) - console.info('Sending mail', raw) const res = await googleClient.sendRawEmail(raw, threadId) - console.info('Response', res) await ack({ tags: { id: `${res.id}` } }) } -const _getConversationInfo = (conversation: bp.AnyMessageProps['conversation']) => { +const _getConversationInfo = (conversation: bp.AnyMessageProps['conversation'], logger: bp.Logger) => { const { id, tags } = conversation const { id: threadId, subject, email, references, cc } = tags if (!(threadId && subject && email)) { - console.info(`No valid information found for conversation ${id}`) + logger.forBot().error(`No valid information found for conversation ${id}`) throw new Error(`No valid information found for conversation ${id}`) } diff --git a/integrations/gmail/src/webhook-events/handler.ts b/integrations/gmail/src/webhook-events/handler.ts index 07197901527..432ce2b9fd1 100644 --- a/integrations/gmail/src/webhook-events/handler.ts +++ b/integrations/gmail/src/webhook-events/handler.ts @@ -5,8 +5,6 @@ import { handleOAuthCallback } from './oauth-callback' import * as bp from '.botpress' export const handler = async (props: bp.HandlerProps) => { - console.info('handler received a request') - if (props.req.path.startsWith('/oauth')) { return handleOAuthCallback(props) } diff --git a/integrations/gmail/src/webhook-events/new-mail.ts b/integrations/gmail/src/webhook-events/new-mail.ts index 68022d9c894..a4bf1c5851d 100644 --- a/integrations/gmail/src/webhook-events/new-mail.ts +++ b/integrations/gmail/src/webhook-events/new-mail.ts @@ -10,7 +10,6 @@ export const handleIncomingEmail = async (props: bp.HandlerProps) => { const bodyContent = JSON.parse(req.body || '{}') const data = bodyContent.message?.data - console.info('data', data) if (!data) { console.warn('Handler received an invalid body (no data)') @@ -18,11 +17,9 @@ export const handleIncomingEmail = async (props: bp.HandlerProps) => { } const messageData = JSON.parse(decodeBase64URL(data)) - console.info('messageData', messageData) const { historyId: historyIdNumber, emailAddress } = messageData const historyId = `${historyIdNumber}` - console.info('historyId', historyId) if (!historyId) { console.warn('Handler received an invalid body (no historyId)') @@ -30,7 +27,6 @@ export const handleIncomingEmail = async (props: bp.HandlerProps) => { } // Only proceed if the incoming historyId is greater that the latest processed historyId - console.info('creating gmail client') const googleClient = await GoogleClient.create({ client, ctx }) const { @@ -57,8 +53,6 @@ export const handleIncomingEmail = async (props: bp.HandlerProps) => { const history = await googleClient.getMyHistory(lastHistoryId) - console.info(JSON.stringify(history, null, 2)) - const messageIds = history.history?.reduce((acc, h) => { h.messagesAdded?.forEach((m) => { if (m.message?.id) { @@ -95,12 +89,8 @@ const _processMessage = async ( googleClient: GoogleClient, emailAddress: string ) => { - console.info('getting history') const gmailMessage = await googleClient.getMessageById(messageId) - const message = parseMessage(gmailMessage) - console.info('message', message) - const threadId = message.threadId if (!threadId) { @@ -112,13 +102,11 @@ const _processMessage = async ( const inReplyTo = message.headers['message-id'] const from = message.headers['from'] const { name: senderName, email: userEmail } = _extractNameAndEmailFromSender(replyTo ?? from) - console.info('userEmail', userEmail) if (userEmail === emailAddress) { return } - console.info('threadId', threadId) const { conversation } = await client.getOrCreateConversation({ channel: 'channel', tags: { @@ -126,9 +114,7 @@ const _processMessage = async ( }, }) - console.info('conversation', conversation) - - const { conversation: updatedConversation } = await client.updateConversation({ + await client.updateConversation({ id: conversation.id, tags: { subject: message.headers['subject'], @@ -138,13 +124,10 @@ const _processMessage = async ( }, }) - console.info('updatedConversation', updatedConversation) - if (!userEmail) { throw new Error('Handler received an empty from id') } - console.info('userEmail', userEmail) const { user } = await client.getOrCreateUser({ tags: { id: `${userEmail}`, @@ -171,7 +154,6 @@ const _processMessage = async ( } } - console.info('getOrCreateMessage', { threadId, userEmail, content, inReplyTo }) await client.getOrCreateMessage({ tags: { id: messageId }, type: 'text', diff --git a/integrations/gmail/src/webhook-events/oauth-callback.ts b/integrations/gmail/src/webhook-events/oauth-callback.ts index c2bb9404eda..53f2303b21a 100644 --- a/integrations/gmail/src/webhook-events/oauth-callback.ts +++ b/integrations/gmail/src/webhook-events/oauth-callback.ts @@ -10,8 +10,6 @@ export const handleOAuthCallback = async ({ req, client, ctx }: bp.HandlerProps) return } - console.info('code', authorizationCode) - const googleClient = await GoogleClient.createFromAuthorizationCode({ client, ctx, @@ -19,14 +17,12 @@ export const handleOAuthCallback = async ({ req, client, ctx }: bp.HandlerProps) }) const userEmail = await googleClient.getMyEmail() - console.info('userEmail', userEmail) if (!userEmail) { console.error('Error extracting email from profile') return } - console.info('configureIntegration') await client.configureIntegration({ identifier: userEmail, })