chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:34:48 +08:00
commit 77bb5bf71f
3762 changed files with 353249 additions and 0 deletions
@@ -0,0 +1,323 @@
import { IntegrationDefinitionProps, z } from '@botpress/sdk'
const ticketSchema = z.object({
id: z.number().title('ID').describe('Unique Freshdesk ticket ID.'),
subject: z.string().title('Subject').describe('Subject of the ticket.'),
description: z.string().nullish().title('Description').describe('HTML content of the ticket description.'),
description_text: z.string().nullish().title('Description Text').describe('Plain-text ticket description.'),
status: z.enum(['open', 'pending', 'resolved', 'closed']).title('Status').describe('Ticket status.'),
priority: z.enum(['low', 'medium', 'high', 'urgent']).title('Priority').describe('Ticket priority.'),
source: z.number().nullish().title('Source').describe('Channel through which the ticket was created.'),
email: z.string().nullish().title('Email').describe('Requester email address.'),
name: z.string().nullish().title('Name').describe('Requester name.'),
requester_id: z.number().nullish().title('Requester ID').describe('Freshdesk requester user ID.'),
responder_id: z.number().nullish().title('Responder ID').describe('Agent assigned to the ticket.'),
group_id: z.number().nullish().title('Group ID').describe('Group the ticket is assigned to.'),
type: z.string().nullish().title('Type').describe('Ticket category type.'),
tags: z.array(z.string()).nullish().title('Tags').describe('Tags associated with the ticket.'),
cc_emails: z.array(z.string()).nullish().title('CC Emails').describe('List of CC email addresses.'),
due_by: z.string().nullish().title('Due By').describe('ISO 8601 timestamp for when the ticket is due.'),
created_at: z.string().title('Created At').describe('ISO 8601 timestamp of ticket creation.'),
updated_at: z.string().title('Updated At').describe('ISO 8601 timestamp of last update.'),
custom_fields: z
.record(z.string(), z.unknown())
.nullish()
.title('Custom Fields')
.describe('Custom field key-value pairs.'),
})
export const actions = {
createTicket: {
title: 'Create Ticket',
description: 'Creates a new ticket in Freshdesk.',
input: {
schema: z.object({
subject: z.string().title('Subject').describe('Subject of the ticket.'),
description: z.string().title('Description').describe('HTML content of the ticket description.'),
email: z.string().title('Email').describe('Requester email address.'),
priority: z
.enum(['low', 'medium', 'high', 'urgent'])
.default('medium')
.title('Priority')
.describe('Ticket priority: "low", "medium", "high", or "urgent".'),
status: z
.enum(['open', 'pending', 'resolved', 'closed'])
.default('open')
.title('Status')
.describe('Ticket status: "open", "pending", "resolved", or "closed".'),
tags: z.array(z.string()).optional().title('Tags').describe('Tags to associate with the ticket.'),
custom_fields: z
.record(z.string(), z.unknown())
.optional()
.title('Custom Fields')
.describe('Custom field key-value pairs.'),
}),
},
output: {
schema: z.object({
id: z.number().title('ID').describe('Unique Freshdesk ticket ID.'),
subject: z.string().title('Subject').describe('Subject of the ticket.'),
status: z.enum(['open', 'pending', 'resolved', 'closed']).title('Status').describe('Ticket status.'),
priority: z.enum(['low', 'medium', 'high', 'urgent']).title('Priority').describe('Ticket priority.'),
createdAt: z.string().title('Created At').describe('ISO 8601 timestamp of ticket creation.'),
url: z.string().title('URL').describe('URL to view the ticket in Freshdesk.'),
}),
},
},
getTicket: {
title: 'Get Ticket',
description: 'Retrieves a single Freshdesk ticket by ID.',
input: {
schema: z.object({
ticketId: z.coerce.number().int().positive().title('Ticket ID').describe('The Freshdesk ticket ID.'),
}),
},
output: {
schema: z.object({
id: z.number().title('ID').describe('Unique Freshdesk ticket ID.'),
subject: z.string().title('Subject').describe('Subject of the ticket.'),
description: z.string().nullish().title('Description').describe('HTML content of the ticket description.'),
status: z.enum(['open', 'pending', 'resolved', 'closed']).title('Status').describe('Ticket status.'),
priority: z.enum(['low', 'medium', 'high', 'urgent']).title('Priority').describe('Ticket priority.'),
requesterId: z.number().nullish().title('Requester ID').describe('Freshdesk requester user ID.'),
responderId: z.number().nullish().title('Responder ID').describe('Agent assigned to the ticket.'),
groupId: z.number().nullish().title('Group ID').describe('Group the ticket is assigned to.'),
createdAt: z.string().title('Created At').describe('ISO 8601 timestamp of ticket creation.'),
updatedAt: z.string().title('Updated At').describe('ISO 8601 timestamp of last update.'),
tags: z.array(z.string()).nullish().title('Tags').describe('Tags associated with the ticket.'),
customFields: z
.record(z.string(), z.unknown())
.nullish()
.title('Custom Fields')
.describe('Custom field key-value pairs.'),
}),
},
},
listTickets: {
title: 'List Tickets',
description: 'Lists Freshdesk tickets with optional filters and pagination.',
input: {
schema: z.object({
filter: z
.string()
.optional()
.title('Filter')
.describe('Predefined filter name: new_and_my_open, watching, spam, deleted.'),
order_by: z
.string()
.optional()
.title('Order By')
.describe('Field to sort by: created_at, due_by, updated_at, status.'),
order_type: z
.enum(['asc', 'desc'])
.optional()
.title('Order Type')
.describe('Sort direction. Defaults to desc.'),
per_page: z.number().optional().title('Per Page').describe('Tickets per page (max 100, default 30).'),
nextToken: z
.string()
.optional()
.title('Next Token')
.describe('Token to continue from the previous page of results.'),
}),
},
output: {
schema: z.object({
tickets: z.array(ticketSchema).title('Tickets').describe('List of matching tickets.'),
nextToken: z
.string()
.optional()
.title('Next Token')
.describe('Token to fetch the next page. Absent when there are no more results.'),
}),
},
},
updateTicket: {
title: 'Update Ticket',
description: 'Updates an existing Freshdesk ticket.',
input: {
schema: z.object({
ticketId: z.coerce.number().int().positive().title('Ticket ID').describe('The Freshdesk ticket ID to update.'),
status: z
.enum(['open', 'pending', 'resolved', 'closed'])
.optional()
.title('Status')
.describe('Updated ticket status: "open", "pending", "resolved", or "closed".'),
priority: z
.enum(['low', 'medium', 'high', 'urgent'])
.optional()
.title('Priority')
.describe('Updated ticket priority: "low", "medium", "high", or "urgent".'),
responderId: z.number().optional().title('Responder ID').describe('ID of the agent to assign the ticket to.'),
groupId: z.number().optional().title('Group ID').describe('ID of the group to assign the ticket to.'),
custom_fields: z
.record(z.string(), z.unknown())
.optional()
.title('Custom Fields')
.describe('Custom field key-value pairs.'),
}),
},
output: {
schema: z.object({
id: z.number().title('ID').describe('Unique Freshdesk ticket ID.'),
status: z.enum(['open', 'pending', 'resolved', 'closed']).title('Status').describe('Updated ticket status.'),
priority: z.enum(['low', 'medium', 'high', 'urgent']).title('Priority').describe('Updated ticket priority.'),
updatedAt: z.string().title('Updated At').describe('ISO 8601 timestamp of last update.'),
}),
},
},
deleteTicket: {
title: 'Delete Ticket',
description: 'Deletes a Freshdesk ticket. Deleted tickets can be restored from the Freshdesk UI.',
input: {
schema: z.object({
ticketId: z.coerce.number().int().positive().title('Ticket ID').describe('The Freshdesk ticket ID to delete.'),
}),
},
output: {
schema: z.object({}),
},
},
searchTickets: {
title: 'Search Tickets',
description: 'Searches Freshdesk tickets by agent, tag, status, or priority.',
input: {
schema: z.object({
agent_id: z
.number()
.optional()
.title('Agent ID')
.describe('Filter by the ID of the agent the ticket is assigned to.'),
tag: z.string().optional().title('Tag').describe('Filter by a tag associated with the ticket.'),
status: z
.enum(['open', 'pending', 'resolved', 'closed'])
.optional()
.title('Status')
.describe('Filter by ticket status: "open", "pending", "resolved", or "closed".'),
priority: z
.enum(['low', 'medium', 'high', 'urgent'])
.optional()
.title('Priority')
.describe('Filter by ticket priority: "low", "medium", "high", or "urgent".'),
limit: z
.number()
.default(20)
.title('Limit')
.describe('Maximum number of tickets to return (default 20, max 100).'),
nextToken: z
.string()
.optional()
.title('Next Token')
.describe('Token to continue from the previous page of results.'),
}),
},
output: {
schema: z.object({
tickets: z
.array(
z.object({
id: z.number().title('ID').describe('Unique Freshdesk ticket ID.'),
subject: z.string().title('Subject').describe('Subject of the ticket.'),
status: z.enum(['open', 'pending', 'resolved', 'closed']).title('Status').describe('Ticket status.'),
priority: z.enum(['low', 'medium', 'high', 'urgent']).title('Priority').describe('Ticket priority.'),
createdAt: z.string().title('Created At').describe('ISO 8601 timestamp of ticket creation.'),
requesterEmail: z.string().nullish().title('Requester Email').describe('Email address of the requester.'),
})
)
.title('Tickets')
.describe('Matching tickets.'),
nextToken: z
.string()
.optional()
.title('Next Token')
.describe('Token to fetch the next page. Absent when there are no more results.'),
}),
},
},
// TODO: re-add replyToTicket action
addNote: {
title: 'Add Note',
description: 'Adds an internal note to a Freshdesk ticket (not visible to the requester by default).',
input: {
schema: z.object({
ticketId: z.coerce
.number()
.int()
.positive()
.title('Ticket ID')
.describe('The Freshdesk ticket ID to add a note to.'),
body: z.string().title('Body').describe('HTML content of the note.'),
private: z
.boolean()
.optional()
.default(true)
.title('Private')
.describe('Set to false to make the note public. Defaults to true.'),
}),
},
output: {
schema: z.object({
id: z.number().title('ID').describe('Unique ID of the note.'),
body: z.string().title('Body').describe('HTML content of the note.'),
createdAt: z.string().title('Created At').describe('ISO 8601 timestamp of note creation.'),
}),
},
},
getContact: {
title: 'Get Contact',
description: 'Retrieves a Freshdesk contact by ID.',
input: {
schema: z.object({
contactId: z.coerce.number().int().positive().title('Contact ID').describe('The Freshdesk contact ID.'),
}),
},
output: {
schema: z.object({
id: z.number().title('ID').describe('Unique Freshdesk contact ID.'),
name: z.string().title('Name').describe('Full name of the contact.'),
email: z.string().nullish().title('Email').describe('Email address of the contact.'),
phone: z.string().nullish().title('Phone').describe('Phone number of the contact.'),
mobile: z.string().nullish().title('Mobile').describe('Mobile number of the contact.'),
companyId: z.number().nullish().title('Company ID').describe('ID of the associated company.'),
tags: z.array(z.string()).nullish().title('Tags').describe('Tags associated with the contact.'),
createdAt: z.string().title('Created At').describe('ISO 8601 timestamp of contact creation.'),
}),
},
},
searchContacts: {
title: 'Search Contacts',
description: 'Finds Freshdesk contacts by email or name.',
input: {
schema: z.object({
email: z.string().optional().title('Email').describe('Filter contacts by exact email address.'),
name: z.string().optional().title('Name').describe('Search contacts by name prefix (case-insensitive).'),
nextToken: z
.string()
.optional()
.title('Next Token')
.describe('Token to continue from the previous page of results.'),
}),
},
output: {
schema: z.object({
contacts: z
.array(
z.object({
id: z.number().title('ID').describe('Unique Freshdesk contact ID.'),
name: z.string().title('Name').describe('Full name of the contact.'),
email: z.string().nullish().title('Email').describe('Email address of the contact.'),
phone: z.string().nullish().title('Phone').describe('Phone number of the contact.'),
companyId: z.number().nullish().title('Company ID').describe('ID of the associated company.'),
})
)
.title('Contacts')
.describe('Matching contacts.'),
nextToken: z
.string()
.optional()
.title('Next Token')
.describe('Token to fetch the next page. Absent when there are no more results.'),
}),
},
},
} as const satisfies IntegrationDefinitionProps['actions']
@@ -0,0 +1,25 @@
import { IntegrationDefinitionProps, z } from '@botpress/sdk'
export const configuration = {
schema: z.object({
domain: z
.string()
.min(1)
.title('Freshdesk Subdomain')
.describe('E.g. "yourcompany" from yourcompany.freshdesk.com'),
apiKey: z
.string()
.secret()
.min(1)
.title('API Key')
.describe('Your Freshdesk API key, found under Profile Settings.'),
webhookSecret: z
.string()
.secret()
.optional()
.title('Webhook Secret')
.describe(
'Optional shared secret to authenticate incoming webhooks. Set this value and add it as the X-Webhook-Secret header in each Freshdesk Automation webhook action.'
),
}),
} as const satisfies IntegrationDefinitionProps['configuration']
@@ -0,0 +1,47 @@
import { IntegrationDefinitionProps, z } from '@botpress/sdk'
export const ticketEventSchema = z.object({
id: z.number().title('Ticket ID').describe('Freshdesk ticket ID.'),
subject: z.string().nullish().title('Subject').describe('Ticket subject.'),
status: z.enum(['open', 'pending', 'resolved', 'closed']).nullish().title('Status').describe('Ticket status.'),
priority: z.enum(['low', 'medium', 'high', 'urgent']).nullish().title('Priority').describe('Ticket priority.'),
requesterId: z.number().nullish().title('Requester ID').describe('Freshdesk requester user ID.'),
responderId: z.number().nullish().title('Responder ID').describe('Agent assigned to the ticket.'),
groupId: z.number().nullish().title('Group ID').describe('Group the ticket is assigned to.'),
type: z.string().nullish().title('Type').describe('Ticket category type.'),
tags: z.array(z.string()).nullish().title('Tags').describe('Tags associated with the ticket.'),
})
export const replyEventSchema = z.object({
body: z.string().title('Body').describe('HTML content of the reply.'),
bodyText: z.string().optional().title('Body Text').describe('Plain-text content of the reply.'),
customerEmail: z.string().optional().title('Customer Email').describe('Email of the customer who replied.'),
})
export const events = {
ticketCreated: {
title: 'Ticket Created',
description: 'Triggered when a new ticket is created in Freshdesk.',
schema: z.object({
ticket: ticketEventSchema.title('Ticket').describe('The newly created ticket.'),
}),
ui: {},
},
ticketUpdated: {
title: 'Ticket Updated',
description: 'Triggered when a ticket is updated (status, priority, or assignment change).',
schema: z.object({
ticket: ticketEventSchema.title('Ticket').describe('The updated ticket.'),
}),
ui: {},
},
ticketReplied: {
title: 'Ticket Replied',
description: 'Triggered when a customer adds a reply to a ticket.',
schema: z.object({
ticket: ticketEventSchema.title('Ticket').describe('The ticket that received the reply.'),
reply: replyEventSchema.title('Reply').describe('The reply that was added.'),
}),
ui: {},
},
} as const satisfies IntegrationDefinitionProps['events']
@@ -0,0 +1,3 @@
export { actions } from './actions'
export { configuration } from './configuration'
export { events } from './events'