mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
improvement(resend): add error handling, authMode, and naming consistency (#3382)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { ResendIcon } from '@/components/icons'
|
||||
import type { BlockConfig } from '@/blocks/types'
|
||||
import { AuthMode } from '@/blocks/types'
|
||||
|
||||
export const ResendBlock: BlockConfig = {
|
||||
type: 'resend',
|
||||
@@ -11,6 +12,7 @@ export const ResendBlock: BlockConfig = {
|
||||
category: 'tools',
|
||||
bgColor: '#181C1E',
|
||||
icon: ResendIcon,
|
||||
authMode: AuthMode.ApiKey,
|
||||
|
||||
subBlocks: [
|
||||
{
|
||||
@@ -18,16 +20,13 @@ export const ResendBlock: BlockConfig = {
|
||||
title: 'Operation',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
// Email Operations
|
||||
{ label: 'Send Email', id: 'send_email' },
|
||||
{ label: 'Get Email', id: 'get_email' },
|
||||
// Contact Operations
|
||||
{ label: 'Create Contact', id: 'create_contact' },
|
||||
{ label: 'List Contacts', id: 'list_contacts' },
|
||||
{ label: 'Get Contact', id: 'get_contact' },
|
||||
{ label: 'Update Contact', id: 'update_contact' },
|
||||
{ label: 'Delete Contact', id: 'delete_contact' },
|
||||
// Domain Operations
|
||||
{ label: 'List Domains', id: 'list_domains' },
|
||||
],
|
||||
value: () => 'send_email',
|
||||
@@ -41,7 +40,6 @@ export const ResendBlock: BlockConfig = {
|
||||
password: true,
|
||||
},
|
||||
|
||||
// Send Email fields
|
||||
{
|
||||
id: 'fromAddress',
|
||||
title: 'From Address',
|
||||
@@ -80,7 +78,7 @@ export const ResendBlock: BlockConfig = {
|
||||
"Order confirmation" -> "Your Order #12345 is Confirmed"
|
||||
"Newsletter about new features" -> "New Features You'll Love"
|
||||
|
||||
Return ONLY the subject line - no explanations.`,
|
||||
Return ONLY the subject line - no explanations, no extra text.`,
|
||||
placeholder: 'Describe the email topic...',
|
||||
},
|
||||
},
|
||||
@@ -100,7 +98,7 @@ Return ONLY the subject line - no explanations.`,
|
||||
- Keep paragraphs short
|
||||
- Include appropriate greeting and sign-off
|
||||
|
||||
Return ONLY the email body - no explanations.`,
|
||||
Return ONLY the email body - no explanations, no extra text.`,
|
||||
placeholder: 'Describe the email content...',
|
||||
},
|
||||
},
|
||||
@@ -114,6 +112,7 @@ Return ONLY the email body - no explanations.`,
|
||||
],
|
||||
value: () => 'text',
|
||||
condition: { field: 'operation', value: 'send_email' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'cc',
|
||||
@@ -121,6 +120,7 @@ Return ONLY the email body - no explanations.`,
|
||||
type: 'short-input',
|
||||
placeholder: 'cc@example.com',
|
||||
condition: { field: 'operation', value: 'send_email' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'bcc',
|
||||
@@ -128,6 +128,7 @@ Return ONLY the email body - no explanations.`,
|
||||
type: 'short-input',
|
||||
placeholder: 'bcc@example.com',
|
||||
condition: { field: 'operation', value: 'send_email' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'replyTo',
|
||||
@@ -135,6 +136,7 @@ Return ONLY the email body - no explanations.`,
|
||||
type: 'short-input',
|
||||
placeholder: 'reply@example.com',
|
||||
condition: { field: 'operation', value: 'send_email' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'scheduledAt',
|
||||
@@ -142,6 +144,14 @@ Return ONLY the email body - no explanations.`,
|
||||
type: 'short-input',
|
||||
placeholder: '2024-08-05T11:52:01.858Z',
|
||||
condition: { field: 'operation', value: 'send_email' },
|
||||
mode: 'advanced',
|
||||
wandConfig: {
|
||||
enabled: true,
|
||||
generationType: 'timestamp',
|
||||
prompt:
|
||||
'Generate an ISO 8601 timestamp for scheduling email delivery. Return ONLY the timestamp - no explanations, no extra text.',
|
||||
placeholder: 'Describe when to send (e.g., "tomorrow at 9am")...',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'tags',
|
||||
@@ -149,9 +159,15 @@ Return ONLY the email body - no explanations.`,
|
||||
type: 'short-input',
|
||||
placeholder: 'category:welcome,type:onboarding',
|
||||
condition: { field: 'operation', value: 'send_email' },
|
||||
mode: 'advanced',
|
||||
wandConfig: {
|
||||
enabled: true,
|
||||
prompt:
|
||||
'Generate comma-separated key:value pairs for email tags based on the description. Example format: "category:welcome,type:onboarding". Return ONLY the tag pairs - no explanations, no extra text.',
|
||||
placeholder: 'Describe the email tags...',
|
||||
},
|
||||
},
|
||||
|
||||
// Get Email fields
|
||||
{
|
||||
id: 'emailId',
|
||||
title: 'Email ID',
|
||||
@@ -161,7 +177,6 @@ Return ONLY the email body - no explanations.`,
|
||||
required: true,
|
||||
},
|
||||
|
||||
// Create Contact fields
|
||||
{
|
||||
id: 'email',
|
||||
title: 'Email',
|
||||
@@ -196,7 +211,6 @@ Return ONLY the email body - no explanations.`,
|
||||
condition: { field: 'operation', value: ['create_contact', 'update_contact'] },
|
||||
},
|
||||
|
||||
// Get/Update/Delete Contact fields
|
||||
{
|
||||
id: 'contactId',
|
||||
title: 'Contact ID or Email',
|
||||
@@ -239,7 +253,6 @@ Return ONLY the email body - no explanations.`,
|
||||
inputs: {
|
||||
operation: { type: 'string', description: 'Operation to perform' },
|
||||
resendApiKey: { type: 'string', description: 'Resend API key' },
|
||||
// Send email inputs
|
||||
fromAddress: { type: 'string', description: 'Email address to send from' },
|
||||
to: { type: 'string', description: 'Recipient email address' },
|
||||
subject: { type: 'string', description: 'Email subject' },
|
||||
@@ -250,9 +263,7 @@ Return ONLY the email body - no explanations.`,
|
||||
replyTo: { type: 'string', description: 'Reply-to email address' },
|
||||
scheduledAt: { type: 'string', description: 'Scheduled send time in ISO 8601 format' },
|
||||
tags: { type: 'string', description: 'Email tags as key:value pairs' },
|
||||
// Get email inputs
|
||||
emailId: { type: 'string', description: 'Email ID to retrieve' },
|
||||
// Contact inputs
|
||||
email: { type: 'string', description: 'Contact email address' },
|
||||
firstName: { type: 'string', description: 'Contact first name' },
|
||||
lastName: { type: 'string', description: 'Contact last name' },
|
||||
@@ -262,24 +273,22 @@ Return ONLY the email body - no explanations.`,
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
// Send email outputs
|
||||
id: { type: 'string', description: 'Email or contact ID' },
|
||||
to: { type: 'string', description: 'Recipient email address' },
|
||||
subject: { type: 'string', description: 'Email subject' },
|
||||
body: { type: 'string', description: 'Email body content' },
|
||||
// Get email outputs
|
||||
id: { type: 'string', description: 'Email or contact ID' },
|
||||
from: { type: 'string', description: 'Sender email address' },
|
||||
html: { type: 'string', description: 'HTML email content' },
|
||||
text: { type: 'string', description: 'Plain text email content' },
|
||||
lastEvent: { type: 'string', description: 'Last event status' },
|
||||
createdAt: { type: 'string', description: 'Creation timestamp' },
|
||||
scheduledAt: { type: 'string', description: 'Scheduled send timestamp' },
|
||||
tags: { type: 'json', description: 'Email tags as name-value pairs' },
|
||||
// Contact outputs
|
||||
email: { type: 'string', description: 'Contact email address' },
|
||||
firstName: { type: 'string', description: 'Contact first name' },
|
||||
lastName: { type: 'string', description: 'Contact last name' },
|
||||
unsubscribed: { type: 'boolean', description: 'Whether the contact is unsubscribed' },
|
||||
contacts: { type: 'json', description: 'Array of contacts' },
|
||||
// Domain outputs
|
||||
domains: { type: 'json', description: 'Array of domains' },
|
||||
hasMore: { type: 'boolean', description: 'Whether more results are available' },
|
||||
deleted: { type: 'boolean', description: 'Whether the resource was deleted' },
|
||||
|
||||
@@ -1599,13 +1599,13 @@ import {
|
||||
} from '@/tools/redis'
|
||||
import { reductoParserTool, reductoParserV2Tool } from '@/tools/reducto'
|
||||
import {
|
||||
mailSendTool,
|
||||
resendCreateContactTool,
|
||||
resendDeleteContactTool,
|
||||
resendGetContactTool,
|
||||
resendGetEmailTool,
|
||||
resendListContactsTool,
|
||||
resendListDomainsTool,
|
||||
resendSendTool,
|
||||
resendUpdateContactTool,
|
||||
} from '@/tools/resend'
|
||||
import {
|
||||
@@ -2390,7 +2390,7 @@ export const tools: Record<string, ToolConfig> = {
|
||||
luma_update_event: lumaUpdateEventTool,
|
||||
linkedin_share_post: linkedInSharePostTool,
|
||||
linkedin_get_profile: linkedInGetProfileTool,
|
||||
resend_send: mailSendTool,
|
||||
resend_send: resendSendTool,
|
||||
resend_get_email: resendGetEmailTool,
|
||||
resend_create_contact: resendCreateContactTool,
|
||||
resend_list_contacts: resendListContactsTool,
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { CreateContactParams, CreateContactResult } from '@/tools/resend/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('ResendCreateContactTool')
|
||||
|
||||
export const resendCreateContactTool: ToolConfig<CreateContactParams, CreateContactResult> = {
|
||||
id: 'resend_create_contact',
|
||||
name: 'Create Contact',
|
||||
@@ -58,6 +61,17 @@ export const resendCreateContactTool: ToolConfig<CreateContactParams, CreateCont
|
||||
transformResponse: async (response: Response): Promise<CreateContactResult> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.id) {
|
||||
logger.error('Resend Create Contact API error:', JSON.stringify(data, null, 2))
|
||||
return {
|
||||
success: false,
|
||||
error: data.message || 'Failed to create contact',
|
||||
output: {
|
||||
id: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { DeleteContactParams, DeleteContactResult } from '@/tools/resend/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('ResendDeleteContactTool')
|
||||
|
||||
export const resendDeleteContactTool: ToolConfig<DeleteContactParams, DeleteContactResult> = {
|
||||
id: 'resend_delete_contact',
|
||||
name: 'Delete Contact',
|
||||
@@ -24,7 +27,7 @@ export const resendDeleteContactTool: ToolConfig<DeleteContactParams, DeleteCont
|
||||
|
||||
request: {
|
||||
url: (params: DeleteContactParams) =>
|
||||
`https://api.resend.com/contacts/${encodeURIComponent(params.contactId)}`,
|
||||
`https://api.resend.com/contacts/${encodeURIComponent(params.contactId.trim())}`,
|
||||
method: 'DELETE',
|
||||
headers: (params: DeleteContactParams) => ({
|
||||
Authorization: `Bearer ${params.resendApiKey}`,
|
||||
@@ -35,10 +38,22 @@ export const resendDeleteContactTool: ToolConfig<DeleteContactParams, DeleteCont
|
||||
transformResponse: async (response: Response): Promise<DeleteContactResult> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (data.message && !data.deleted) {
|
||||
logger.error('Resend Delete Contact API error:', JSON.stringify(data, null, 2))
|
||||
return {
|
||||
success: false,
|
||||
error: data.message || 'Failed to delete contact',
|
||||
output: {
|
||||
id: '',
|
||||
deleted: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.contact || data.id || '',
|
||||
id: data.contact ?? data.id ?? '',
|
||||
deleted: data.deleted ?? true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { GetContactParams, GetContactResult } from '@/tools/resend/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('ResendGetContactTool')
|
||||
|
||||
export const resendGetContactTool: ToolConfig<GetContactParams, GetContactResult> = {
|
||||
id: 'resend_get_contact',
|
||||
name: 'Get Contact',
|
||||
@@ -24,7 +27,7 @@ export const resendGetContactTool: ToolConfig<GetContactParams, GetContactResult
|
||||
|
||||
request: {
|
||||
url: (params: GetContactParams) =>
|
||||
`https://api.resend.com/contacts/${encodeURIComponent(params.contactId)}`,
|
||||
`https://api.resend.com/contacts/${encodeURIComponent(params.contactId.trim())}`,
|
||||
method: 'GET',
|
||||
headers: (params: GetContactParams) => ({
|
||||
Authorization: `Bearer ${params.resendApiKey}`,
|
||||
@@ -35,15 +38,31 @@ export const resendGetContactTool: ToolConfig<GetContactParams, GetContactResult
|
||||
transformResponse: async (response: Response): Promise<GetContactResult> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.id) {
|
||||
logger.error('Resend Get Contact API error:', JSON.stringify(data, null, 2))
|
||||
return {
|
||||
success: false,
|
||||
error: data.message || 'Failed to retrieve contact',
|
||||
output: {
|
||||
id: '',
|
||||
email: '',
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
createdAt: '',
|
||||
unsubscribed: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.id,
|
||||
email: data.email,
|
||||
firstName: data.first_name || '',
|
||||
lastName: data.last_name || '',
|
||||
createdAt: data.created_at || '',
|
||||
unsubscribed: data.unsubscribed || false,
|
||||
email: data.email ?? '',
|
||||
firstName: data.first_name ?? '',
|
||||
lastName: data.last_name ?? '',
|
||||
createdAt: data.created_at ?? '',
|
||||
unsubscribed: data.unsubscribed ?? false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { GetEmailParams, GetEmailResult } from '@/tools/resend/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('ResendGetEmailTool')
|
||||
|
||||
export const resendGetEmailTool: ToolConfig<GetEmailParams, GetEmailResult> = {
|
||||
id: 'resend_get_email',
|
||||
name: 'Get Email',
|
||||
@@ -23,7 +26,7 @@ export const resendGetEmailTool: ToolConfig<GetEmailParams, GetEmailResult> = {
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params: GetEmailParams) => `https://api.resend.com/emails/${params.emailId}`,
|
||||
url: (params: GetEmailParams) => `https://api.resend.com/emails/${params.emailId.trim()}`,
|
||||
method: 'GET',
|
||||
headers: (params: GetEmailParams) => ({
|
||||
Authorization: `Bearer ${params.resendApiKey}`,
|
||||
@@ -34,22 +37,45 @@ export const resendGetEmailTool: ToolConfig<GetEmailParams, GetEmailResult> = {
|
||||
transformResponse: async (response: Response): Promise<GetEmailResult> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.id) {
|
||||
logger.error('Resend Get Email API error:', JSON.stringify(data, null, 2))
|
||||
return {
|
||||
success: false,
|
||||
error: data.message || 'Failed to retrieve email',
|
||||
output: {
|
||||
id: '',
|
||||
from: '',
|
||||
to: [],
|
||||
subject: '',
|
||||
html: '',
|
||||
text: null,
|
||||
cc: [],
|
||||
bcc: [],
|
||||
replyTo: [],
|
||||
lastEvent: '',
|
||||
createdAt: '',
|
||||
scheduledAt: null,
|
||||
tags: [],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.id,
|
||||
from: data.from,
|
||||
to: data.to || [],
|
||||
subject: data.subject,
|
||||
html: data.html || '',
|
||||
text: data.text || null,
|
||||
cc: data.cc || [],
|
||||
bcc: data.bcc || [],
|
||||
replyTo: data.reply_to || [],
|
||||
lastEvent: data.last_event || '',
|
||||
createdAt: data.created_at || '',
|
||||
scheduledAt: data.scheduled_at || null,
|
||||
tags: data.tags || [],
|
||||
from: data.from ?? '',
|
||||
to: data.to ?? [],
|
||||
subject: data.subject ?? '',
|
||||
html: data.html ?? '',
|
||||
text: data.text ?? null,
|
||||
cc: data.cc ?? [],
|
||||
bcc: data.bcc ?? [],
|
||||
replyTo: data.reply_to ?? [],
|
||||
lastEvent: data.last_event ?? '',
|
||||
createdAt: data.created_at ?? '',
|
||||
scheduledAt: data.scheduled_at ?? null,
|
||||
tags: data.tags ?? [],
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -60,13 +86,13 @@ export const resendGetEmailTool: ToolConfig<GetEmailParams, GetEmailResult> = {
|
||||
to: { type: 'json', description: 'Recipient email addresses' },
|
||||
subject: { type: 'string', description: 'Email subject' },
|
||||
html: { type: 'string', description: 'HTML email content' },
|
||||
text: { type: 'string', description: 'Plain text email content' },
|
||||
text: { type: 'string', description: 'Plain text email content', optional: true },
|
||||
cc: { type: 'json', description: 'CC email addresses' },
|
||||
bcc: { type: 'json', description: 'BCC email addresses' },
|
||||
replyTo: { type: 'json', description: 'Reply-to email addresses' },
|
||||
lastEvent: { type: 'string', description: 'Last event status (e.g., delivered, bounced)' },
|
||||
createdAt: { type: 'string', description: 'Email creation timestamp' },
|
||||
scheduledAt: { type: 'string', description: 'Scheduled send timestamp' },
|
||||
scheduledAt: { type: 'string', description: 'Scheduled send timestamp', optional: true },
|
||||
tags: { type: 'json', description: 'Email tags as name-value pairs' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ export { resendGetContactTool } from '@/tools/resend/get_contact'
|
||||
export { resendGetEmailTool } from '@/tools/resend/get_email'
|
||||
export { resendListContactsTool } from '@/tools/resend/list_contacts'
|
||||
export { resendListDomainsTool } from '@/tools/resend/list_domains'
|
||||
export { mailSendTool } from '@/tools/resend/send'
|
||||
export { resendSendTool } from '@/tools/resend/send'
|
||||
export type {
|
||||
CreateContactParams,
|
||||
CreateContactResult,
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { ListContactsParams, ListContactsResult } from '@/tools/resend/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('ResendListContactsTool')
|
||||
|
||||
export const resendListContactsTool: ToolConfig<ListContactsParams, ListContactsResult> = {
|
||||
id: 'resend_list_contacts',
|
||||
name: 'List Contacts',
|
||||
@@ -28,11 +31,23 @@ export const resendListContactsTool: ToolConfig<ListContactsParams, ListContacts
|
||||
transformResponse: async (response: Response): Promise<ListContactsResult> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (data.message) {
|
||||
logger.error('Resend List Contacts API error:', JSON.stringify(data, null, 2))
|
||||
return {
|
||||
success: false,
|
||||
error: data.message || 'Failed to list contacts',
|
||||
output: {
|
||||
contacts: [],
|
||||
hasMore: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
contacts: data.data || [],
|
||||
hasMore: data.has_more || false,
|
||||
contacts: data.data ?? [],
|
||||
hasMore: data.has_more ?? false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { ListDomainsParams, ListDomainsResult } from '@/tools/resend/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('ResendListDomainsTool')
|
||||
|
||||
export const resendListDomainsTool: ToolConfig<ListDomainsParams, ListDomainsResult> = {
|
||||
id: 'resend_list_domains',
|
||||
name: 'List Domains',
|
||||
@@ -28,10 +31,22 @@ export const resendListDomainsTool: ToolConfig<ListDomainsParams, ListDomainsRes
|
||||
transformResponse: async (response: Response): Promise<ListDomainsResult> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (data.message) {
|
||||
logger.error('Resend List Domains API error:', JSON.stringify(data, null, 2))
|
||||
return {
|
||||
success: false,
|
||||
error: data.message || 'Failed to list domains',
|
||||
output: {
|
||||
domains: [],
|
||||
hasMore: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
domains: (data.data || []).map(
|
||||
domains: (data.data ?? []).map(
|
||||
(domain: {
|
||||
id: string
|
||||
name: string
|
||||
@@ -46,7 +61,7 @@ export const resendListDomainsTool: ToolConfig<ListDomainsParams, ListDomainsRes
|
||||
createdAt: domain.created_at,
|
||||
})
|
||||
),
|
||||
hasMore: data.has_more || false,
|
||||
hasMore: data.has_more ?? false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { MailSendParams, MailSendResult } from '@/tools/resend/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const mailSendTool: ToolConfig<MailSendParams, MailSendResult> = {
|
||||
export const resendSendTool: ToolConfig<MailSendParams, MailSendResult> = {
|
||||
id: 'resend_send',
|
||||
name: 'Send Email',
|
||||
description: 'Send an email using your own Resend API key and from address',
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { UpdateContactParams, UpdateContactResult } from '@/tools/resend/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('ResendUpdateContactTool')
|
||||
|
||||
export const resendUpdateContactTool: ToolConfig<UpdateContactParams, UpdateContactResult> = {
|
||||
id: 'resend_update_contact',
|
||||
name: 'Update Contact',
|
||||
@@ -42,7 +45,7 @@ export const resendUpdateContactTool: ToolConfig<UpdateContactParams, UpdateCont
|
||||
|
||||
request: {
|
||||
url: (params: UpdateContactParams) =>
|
||||
`https://api.resend.com/contacts/${encodeURIComponent(params.contactId)}`,
|
||||
`https://api.resend.com/contacts/${encodeURIComponent(params.contactId.trim())}`,
|
||||
method: 'PATCH',
|
||||
headers: (params: UpdateContactParams) => ({
|
||||
Authorization: `Bearer ${params.resendApiKey}`,
|
||||
@@ -58,6 +61,17 @@ export const resendUpdateContactTool: ToolConfig<UpdateContactParams, UpdateCont
|
||||
transformResponse: async (response: Response): Promise<UpdateContactResult> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.id) {
|
||||
logger.error('Resend Update Contact API error:', JSON.stringify(data, null, 2))
|
||||
return {
|
||||
success: false,
|
||||
error: data.message || 'Failed to update contact',
|
||||
output: {
|
||||
id: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
Reference in New Issue
Block a user