Skip to content

Commit 89d3885

Browse files
committed
test(sendblue): add webhook handler tests; trim group_id and normalize empty group_id to null
1 parent 116a0bb commit 89d3885

3 files changed

Lines changed: 117 additions & 2 deletions

File tree

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* @vitest-environment node
3+
*/
4+
import { describe, expect, it } from 'vitest'
5+
import { sendblueHandler } from '@/lib/webhooks/providers/sendblue'
6+
7+
const inboundBody = {
8+
accountEmail: 'me@example.com',
9+
content: 'hello',
10+
media_url: '',
11+
is_outbound: false,
12+
status: 'RECEIVED',
13+
message_handle: 'handle-123',
14+
from_number: '+19998887777',
15+
number: '+18887776666',
16+
group_id: '',
17+
}
18+
19+
const outboundBody = {
20+
...inboundBody,
21+
is_outbound: true,
22+
status: 'SENT',
23+
}
24+
25+
describe('sendblueHandler', () => {
26+
describe('matchEvent', () => {
27+
it('matches an inbound message for the message_received trigger', () => {
28+
expect(
29+
sendblueHandler.matchEvent!({
30+
body: inboundBody,
31+
webhook: { providerConfig: { triggerId: 'sendblue_message_received' } },
32+
requestId: 'r1',
33+
} as any)
34+
).toBe(true)
35+
})
36+
37+
it('rejects an outbound event for the message_received trigger', () => {
38+
expect(
39+
sendblueHandler.matchEvent!({
40+
body: outboundBody,
41+
webhook: { providerConfig: { triggerId: 'sendblue_message_received' } },
42+
requestId: 'r1',
43+
} as any)
44+
).toBe(false)
45+
})
46+
47+
it('matches an outbound status update for the message_status_updated trigger', () => {
48+
expect(
49+
sendblueHandler.matchEvent!({
50+
body: outboundBody,
51+
webhook: { providerConfig: { triggerId: 'sendblue_message_status_updated' } },
52+
requestId: 'r1',
53+
} as any)
54+
).toBe(true)
55+
})
56+
57+
it('passes through when the triggerId is unknown or unset', () => {
58+
expect(
59+
sendblueHandler.matchEvent!({
60+
body: inboundBody,
61+
webhook: {},
62+
requestId: 'r1',
63+
} as any)
64+
).toBe(true)
65+
})
66+
67+
it('rejects a non-object payload for a known trigger', () => {
68+
expect(
69+
sendblueHandler.matchEvent!({
70+
body: 'not-an-object',
71+
webhook: { providerConfig: { triggerId: 'sendblue_message_received' } },
72+
requestId: 'r1',
73+
} as any)
74+
).toBe(false)
75+
})
76+
})
77+
78+
describe('extractIdempotencyId', () => {
79+
it('uses the message handle alone when no status is present', () => {
80+
expect(sendblueHandler.extractIdempotencyId!({ message_handle: 'handle-123' })).toBe(
81+
'handle-123'
82+
)
83+
})
84+
85+
it('suffixes the status so SENT and DELIVERED on one handle stay distinct', () => {
86+
expect(
87+
sendblueHandler.extractIdempotencyId!({ message_handle: 'handle-123', status: 'DELIVERED' })
88+
).toBe('handle-123:DELIVERED')
89+
})
90+
91+
it('returns null when no message handle is present', () => {
92+
expect(sendblueHandler.extractIdempotencyId!({})).toBeNull()
93+
expect(sendblueHandler.extractIdempotencyId!('nope')).toBeNull()
94+
})
95+
})
96+
97+
describe('formatInput', () => {
98+
it('returns the payload under input with empty strings normalized to null', async () => {
99+
const result = await sendblueHandler.formatInput!({ body: inboundBody } as any)
100+
expect(result.input.account_email).toBe('me@example.com')
101+
expect(result.input.media_url).toBeNull()
102+
expect(result.input.group_id).toBeNull()
103+
expect(result.input.is_outbound).toBe(false)
104+
expect(result.input.participants).toEqual([])
105+
expect(result.input.raw).toBe(JSON.stringify(inboundBody))
106+
})
107+
108+
it('defaults missing fields to null and tolerates a non-object body', async () => {
109+
const result = await sendblueHandler.formatInput!({ body: undefined } as any)
110+
expect(result.input.message_handle).toBeNull()
111+
expect(result.input.content).toBeNull()
112+
expect(result.input.participants).toEqual([])
113+
})
114+
})
115+
})

apps/sim/lib/webhooks/providers/sendblue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export const sendblueHandler: WebhookProviderHandler = {
8888
was_downgraded: b.was_downgraded ?? null,
8989
plan: b.plan ?? null,
9090
message_type: b.message_type ?? null,
91-
group_id: b.group_id ?? null,
91+
group_id: (typeof b.group_id === 'string' && b.group_id) || null,
9292
participants: b.participants ?? [],
9393
send_style: b.send_style ?? null,
9494
opted_out: b.opted_out ?? null,

apps/sim/tools/sendblue/send_group_message.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export const sendblueSendGroupMessageTool: ToolConfig<
9595
media_url: params.media_url,
9696
send_style: params.send_style,
9797
seat_id: params.seat_id,
98-
group_id: params.group_id,
98+
group_id: hasGroupId ? params.group_id?.trim() : undefined,
9999
status_callback: params.status_callback,
100100
})
101101
},

0 commit comments

Comments
 (0)