Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion apps/sim/blocks/blocks/sendgrid.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { SendgridIcon } from '@/components/icons'
import type { BlockConfig, BlockMeta } from '@/blocks/types'
import { IntegrationType } from '@/blocks/types'
import { AuthMode, IntegrationType } from '@/blocks/types'
import { normalizeFileInput } from '@/blocks/utils'
import { toActiveFlag } from '@/tools/sendgrid/create_template_version'
import type { SendMailResult } from '@/tools/sendgrid/types'

export const SendGridBlock: BlockConfig<SendMailResult> = {
Expand All @@ -13,6 +14,7 @@ export const SendGridBlock: BlockConfig<SendMailResult> = {
docsLink: 'https://docs.sim.ai/integrations/sendgrid',
category: 'tools',
integrationType: IntegrationType.Email,
authMode: AuthMode.ApiKey,
bgColor: '#1A82E2',
icon: SendgridIcon,

Expand Down Expand Up @@ -387,6 +389,14 @@ Return ONLY the JSON array.`,
condition: { field: 'operation', value: 'list_all_lists' },
mode: 'advanced',
},
{
id: 'listPageToken',
title: 'Page Token',
type: 'short-input',
placeholder: 'Page token from a previous response',
condition: { field: 'operation', value: 'list_all_lists' },
mode: 'advanced',
},
// Template fields
{
id: 'templateName',
Expand Down Expand Up @@ -434,6 +444,14 @@ Return ONLY the JSON array.`,
condition: { field: 'operation', value: 'list_templates' },
mode: 'advanced',
},
{
id: 'templatePageToken',
title: 'Page Token',
type: 'short-input',
placeholder: 'Page token from a previous response (keep Page Size the same)',
condition: { field: 'operation', value: 'list_templates' },
mode: 'advanced',
},
{
id: 'versionName',
title: 'Version Name',
Expand Down Expand Up @@ -579,7 +597,10 @@ Return ONLY the HTML content.`,
templateGenerations,
listPageSize,
templatePageSize,
listPageToken,
templatePageToken,
attachments,
active,
...rest
} = params

Expand All @@ -599,7 +620,11 @@ Return ONLY the HTML content.`,
...(templateGenerations && { generations: templateGenerations }),
...(listPageSize && { pageSize: listPageSize }),
...(templatePageSize && { pageSize: templatePageSize }),
...(operation === 'list_all_lists' && listPageToken && { pageToken: listPageToken }),
...(operation === 'list_templates' &&
templatePageToken && { pageToken: templatePageToken }),
...(normalizedAttachments && { attachments: normalizedAttachments }),
Comment thread
waleedlatif1 marked this conversation as resolved.
...(active !== undefined && { active: toActiveFlag(active) }),
}
},
},
Expand Down Expand Up @@ -637,12 +662,14 @@ Return ONLY the HTML content.`,
listName: { type: 'string', description: 'List name' },
listId: { type: 'string', description: 'List ID' },
listPageSize: { type: 'number', description: 'Page size for listing lists' },
listPageToken: { type: 'string', description: 'Page token for listing lists' },
// Template inputs
templateName: { type: 'string', description: 'Template name' },
templateId: { type: 'string', description: 'Template ID' },
generation: { type: 'string', description: 'Template generation' },
templateGenerations: { type: 'string', description: 'Filter templates by generation' },
templatePageSize: { type: 'number', description: 'Page size for listing templates' },
templatePageToken: { type: 'string', description: 'Page token for listing templates' },
versionName: { type: 'string', description: 'Template version name' },
templateSubject: { type: 'string', description: 'Template subject' },
htmlContent: { type: 'string', description: 'HTML content' },
Expand Down Expand Up @@ -677,6 +704,10 @@ Return ONLY the HTML content.`,
templates: { type: 'json', description: 'Array of templates' },
generation: { type: 'string', description: 'Template generation' },
versions: { type: 'json', description: 'Array of template versions' },
nextPageToken: {
type: 'string',
description: 'Token for the next page of results (list_all_lists, list_templates)',
},
// Template version outputs
templateId: { type: 'string', description: 'Template ID' },
active: { type: 'boolean', description: 'Whether template version is active' },
Expand Down
15 changes: 9 additions & 6 deletions apps/sim/tools/sendgrid/add_contact.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { safeAssign } from '@/tools/safe-assign'
import type {
AddContactParams,
ContactResult,
Expand Down Expand Up @@ -73,7 +72,7 @@ export const sendGridAddContactTool: ToolConfig<AddContactParams, ContactResult>
typeof params.customFields === 'string'
? JSON.parse(params.customFields)
: params.customFields
safeAssign(contact, customFields as Record<string, unknown>)
contact.custom_fields = customFields as Record<string, unknown>
}

const body: SendGridContactRequest = {
Expand All @@ -99,7 +98,7 @@ export const sendGridAddContactTool: ToolConfig<AddContactParams, ContactResult>
return {
success: true,
output: {
jobId: data.job_id,
jobId: data.job_id ?? null,
email: params?.email || '',
firstName: params?.firstName,
lastName: params?.lastName,
Expand All @@ -110,10 +109,14 @@ export const sendGridAddContactTool: ToolConfig<AddContactParams, ContactResult>
},

outputs: {
jobId: { type: 'string', description: 'Job ID for tracking the async contact creation' },
jobId: {
type: 'string',
description: 'Job ID for tracking the async contact creation',
optional: true,
},
email: { type: 'string', description: 'Contact email address' },
firstName: { type: 'string', description: 'Contact first name' },
lastName: { type: 'string', description: 'Contact last name' },
firstName: { type: 'string', description: 'Contact first name', optional: true },
lastName: { type: 'string', description: 'Contact last name', optional: true },
message: { type: 'string', description: 'Status message' },
},
}
24 changes: 17 additions & 7 deletions apps/sim/tools/sendgrid/create_template_version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ import type {
} from '@/tools/sendgrid/types'
import type { ToolConfig } from '@/tools/types'

const INACTIVE_VALUES: unknown[] = [false, 'false', 0, '0']

/** Coerces any dynamic-reference form of SendGrid's active flag (boolean, string, or
* number) to the 0/1 integer the API requires. Shared with the block's own
* pre-coercion in blocks/blocks/sendgrid.ts so both layers stay in sync. */
export function toActiveFlag(active: unknown): 0 | 1 {
if (active === undefined) return 1
return INACTIVE_VALUES.includes(active) ? 0 : 1
}

export const sendGridCreateTemplateVersionTool: ToolConfig<
CreateTemplateVersionParams,
TemplateVersionResult
Expand Down Expand Up @@ -70,7 +80,7 @@ export const sendGridCreateTemplateVersionTool: ToolConfig<
const body: SendGridTemplateVersionRequest = {
name: params.name,
subject: params.subject,
active: params.active !== undefined ? params.active : 1,
active: toActiveFlag(params.active),
}

if (params.htmlContent) {
Expand Down Expand Up @@ -101,9 +111,9 @@ export const sendGridCreateTemplateVersionTool: ToolConfig<
name: data.name,
subject: data.subject,
active: data.active === 1,
htmlContent: data.html_content,
plainContent: data.plain_content,
updatedAt: data.updated_at,
htmlContent: data.html_content ?? null,
plainContent: data.plain_content ?? null,
updatedAt: data.updated_at ?? null,
},
}
},
Expand All @@ -114,8 +124,8 @@ export const sendGridCreateTemplateVersionTool: ToolConfig<
name: { type: 'string', description: 'Version name' },
subject: { type: 'string', description: 'Email subject' },
active: { type: 'boolean', description: 'Whether this version is active' },
htmlContent: { type: 'string', description: 'HTML content' },
plainContent: { type: 'string', description: 'Plain text content' },
updatedAt: { type: 'string', description: 'Last update timestamp' },
htmlContent: { type: 'string', description: 'HTML content', optional: true },
plainContent: { type: 'string', description: 'Plain text content', optional: true },
updatedAt: { type: 'string', description: 'Last update timestamp', optional: true },
},
}
20 changes: 12 additions & 8 deletions apps/sim/tools/sendgrid/get_contact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,24 @@ export const sendGridGetContactTool: ToolConfig<GetContactParams, ContactResult>
lastName: data.last_name,
createdAt: data.created_at,
updatedAt: data.updated_at,
listIds: data.list_ids,
customFields: data.custom_fields,
listIds: data.list_ids ?? [],
customFields: data.custom_fields ?? null,
},
}
},

outputs: {
id: { type: 'string', description: 'Contact ID' },
email: { type: 'string', description: 'Contact email address' },
firstName: { type: 'string', description: 'Contact first name' },
lastName: { type: 'string', description: 'Contact last name' },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last update timestamp' },
listIds: { type: 'json', description: 'Array of list IDs the contact belongs to' },
customFields: { type: 'json', description: 'Custom field values' },
firstName: { type: 'string', description: 'Contact first name', optional: true },
lastName: { type: 'string', description: 'Contact last name', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp', optional: true },
updatedAt: { type: 'string', description: 'Last update timestamp', optional: true },
listIds: {
type: 'json',
description: 'Array of list IDs the contact belongs to',
optional: true,
},
customFields: { type: 'json', description: 'Custom field values', optional: true },
},
}
31 changes: 29 additions & 2 deletions apps/sim/tools/sendgrid/list_all_lists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ export const sendGridListAllListsTool: ToolConfig<ListAllListsParams, ListsResul
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of lists to return per page (default: 100)',
description: 'Number of lists to return per page (default: 100, max: 1000)',
},
pageToken: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Page token from a previous response (nextPageToken) to fetch the next page',
},
},

Expand All @@ -28,6 +34,9 @@ export const sendGridListAllListsTool: ToolConfig<ListAllListsParams, ListsResul
if (params.pageSize) {
url.searchParams.append('page_size', params.pageSize.toString())
}
if (params.pageToken) {
url.searchParams.append('page_token', params.pageToken)
}
return url.toString()
},
method: 'GET',
Expand All @@ -42,17 +51,35 @@ export const sendGridListAllListsTool: ToolConfig<ListAllListsParams, ListsResul
throw new Error(error.errors?.[0]?.message || 'Failed to list all lists')
}

const data = (await response.json()) as { result?: SendGridList[] }
const data = (await response.json()) as {
result?: SendGridList[]
_metadata?: { next?: string }
}

let nextPageToken: string | null = null
if (data._metadata?.next) {
try {
nextPageToken = new URL(data._metadata.next).searchParams.get('page_token')
} catch {
nextPageToken = null
}
}

return {
success: true,
output: {
lists: data.result || [],
nextPageToken,
},
}
},

outputs: {
lists: { type: 'json', description: 'Array of lists' },
nextPageToken: {
type: 'string',
description: 'Token to pass as pageToken to fetch the next page, if more results exist',
optional: true,
},
},
}
35 changes: 30 additions & 5 deletions apps/sim/tools/sendgrid/list_templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,16 @@ export const sendGridListTemplatesTool: ToolConfig<ListTemplatesParams, Template
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of templates to return per page (default: 20)',
description:
'Number of templates to return per page (default: 20, max: 200). ' +
'When paginating with pageToken, pass the same pageSize used on the first request ' +
'to keep page boundaries consistent.',
},
pageToken: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Page token from a previous response (nextPageToken) to fetch the next page',
},
},

Expand All @@ -34,8 +43,9 @@ export const sendGridListTemplatesTool: ToolConfig<ListTemplatesParams, Template
if (params.generations) {
url.searchParams.append('generations', params.generations)
}
if (params.pageSize) {
url.searchParams.append('page_size', params.pageSize.toString())
url.searchParams.append('page_size', (params.pageSize || 20).toString())
if (params.pageToken) {
url.searchParams.append('page_token', params.pageToken)
Comment thread
waleedlatif1 marked this conversation as resolved.
}
return url.toString()
},
Expand All @@ -53,18 +63,33 @@ export const sendGridListTemplatesTool: ToolConfig<ListTemplatesParams, Template

const data = (await response.json()) as {
result?: SendGridTemplate[]
templates?: SendGridTemplate[]
_metadata?: { next?: string }
}

let nextPageToken: string | null = null
if (data._metadata?.next) {
try {
nextPageToken = new URL(data._metadata.next).searchParams.get('page_token')
} catch {
nextPageToken = null
}
}

return {
success: true,
output: {
templates: data.result || data.templates || [],
templates: data.result || [],
nextPageToken,
},
}
},

outputs: {
templates: { type: 'json', description: 'Array of templates' },
nextPageToken: {
type: 'string',
description: 'Token to pass as pageToken to fetch the next page, if more results exist',
optional: true,
},
},
}
4 changes: 2 additions & 2 deletions apps/sim/tools/sendgrid/remove_contacts_from_list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ export const sendGridRemoveContactsFromListTool: ToolConfig<
return {
success: true,
output: {
jobId: data.job_id,
jobId: data.job_id ?? null,
},
}
},

outputs: {
jobId: { type: 'string', description: 'Job ID for the request' },
jobId: { type: 'string', description: 'Job ID for the request', optional: true },
},
}
8 changes: 6 additions & 2 deletions apps/sim/tools/sendgrid/search_contacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,17 @@ export const sendGridSearchContactsTool: ToolConfig<SearchContactsParams, Contac
success: true,
output: {
contacts: data.result || [],
contactCount: data.contact_count,
contactCount: data.contact_count ?? null,
},
}
},

outputs: {
contacts: { type: 'json', description: 'Array of matching contacts' },
contactCount: { type: 'number', description: 'Total number of contacts found' },
contactCount: {
type: 'number',
description: 'Total number of contacts found',
optional: true,
},
},
}
2 changes: 1 addition & 1 deletion apps/sim/tools/sendgrid/send_mail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export const sendGridSendMailTool: ToolConfig<SendMailParams, SendMailResult> =

outputs: {
success: { type: 'boolean', description: 'Whether the email was sent successfully' },
messageId: { type: 'string', description: 'SendGrid message ID' },
messageId: { type: 'string', description: 'SendGrid message ID', optional: true },
to: { type: 'string', description: 'Recipient email address' },
subject: { type: 'string', description: 'Email subject' },
},
Expand Down
Loading
Loading