chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import { z } from '@botpress/sdk'
|
||||
import { companySchema } from '../../definitions/actions/company'
|
||||
import { getAuthenticatedHubspotClient, propertiesEntriesToRecord } from '../utils'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
type HubspotClient = Awaited<ReturnType<typeof getAuthenticatedHubspotClient>>
|
||||
type HsCompany = NonNullable<Awaited<ReturnType<HubspotClient['searchCompany']>>>
|
||||
type BpCompany = z.infer<typeof companySchema>
|
||||
|
||||
const _mapHsCompanyToBpCompany = (hsCompany: HsCompany): BpCompany => ({
|
||||
id: hsCompany.id,
|
||||
name: hsCompany.properties['name'] ?? '',
|
||||
domain: hsCompany.properties['domain'] ?? '',
|
||||
createdAt: hsCompany.createdAt.toISOString(),
|
||||
updatedAt: hsCompany.updatedAt.toISOString(),
|
||||
properties: hsCompany.properties,
|
||||
})
|
||||
|
||||
const _getCompanyPropertyKeys = async (hsClient: HubspotClient) => {
|
||||
const properties = await hsClient.getAllObjectProperties('companies')
|
||||
return properties.results.map((property) => property.name)
|
||||
}
|
||||
|
||||
export const searchCompany: bp.IntegrationProps['actions']['searchCompany'] = async ({
|
||||
client,
|
||||
ctx,
|
||||
input,
|
||||
logger,
|
||||
}) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
const propertyKeys = await _getCompanyPropertyKeys(hsClient)
|
||||
|
||||
const company = await hsClient.searchCompany({
|
||||
name: input.name,
|
||||
domain: input.domain,
|
||||
propertiesToReturn: propertyKeys,
|
||||
})
|
||||
|
||||
return {
|
||||
company: company ? _mapHsCompanyToBpCompany(company) : undefined,
|
||||
}
|
||||
}
|
||||
|
||||
export const getCompany: bp.IntegrationProps['actions']['getCompany'] = async ({ ctx, client, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
const propertyKeys =
|
||||
input.propertiesToReturn && input.propertiesToReturn.length > 0
|
||||
? input.propertiesToReturn
|
||||
: await _getCompanyPropertyKeys(hsClient)
|
||||
|
||||
const company = await hsClient.getCompanyById({
|
||||
companyId: Number(input.companyId),
|
||||
propertiesToReturn: propertyKeys,
|
||||
})
|
||||
|
||||
return {
|
||||
company: _mapHsCompanyToBpCompany(company),
|
||||
}
|
||||
}
|
||||
|
||||
export const updateCompany: bp.IntegrationProps['actions']['updateCompany'] = async ({
|
||||
ctx,
|
||||
client,
|
||||
input,
|
||||
logger,
|
||||
}) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
|
||||
const additionalProperties = propertiesEntriesToRecord(input.properties ?? [])
|
||||
|
||||
const updatedCompany = await hsClient.updateCompany({
|
||||
companyId: Number(input.companyId),
|
||||
additionalProperties,
|
||||
})
|
||||
|
||||
return {
|
||||
company: {
|
||||
..._mapHsCompanyToBpCompany(updatedCompany),
|
||||
name: updatedCompany.properties['name'] ?? undefined,
|
||||
domain: updatedCompany.properties['domain'] ?? undefined,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
import { z } from '@botpress/sdk'
|
||||
import { contactSchema } from '../../definitions/actions/contact'
|
||||
import { buildContactUrl, getAuthenticatedHubspotClient, getOrFetchPortalId, propertiesEntriesToRecord } from '../utils'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
type HubspotClient = Awaited<ReturnType<typeof getAuthenticatedHubspotClient>>
|
||||
type HsContact = Awaited<ReturnType<HubspotClient['getContact']>>
|
||||
type BpContact = z.infer<typeof contactSchema>
|
||||
|
||||
const _mapHsContactToBpContact = (hsContact: HsContact): BpContact => ({
|
||||
id: hsContact.id,
|
||||
properties: hsContact.properties,
|
||||
email: hsContact.properties['email'] ?? '',
|
||||
phone: hsContact.properties['phone'] ?? '',
|
||||
createdAt: hsContact.createdAt.toISOString(),
|
||||
updatedAt: hsContact.updatedAt.toISOString(),
|
||||
})
|
||||
|
||||
const _getContactPropertyKeys = async (hsClient: HubspotClient) => {
|
||||
const properties = await hsClient.getAllObjectProperties('contacts')
|
||||
return properties.results.map((property) => property.name)
|
||||
}
|
||||
|
||||
export const searchContact: bp.IntegrationProps['actions']['searchContact'] = async ({
|
||||
client,
|
||||
ctx,
|
||||
input,
|
||||
logger,
|
||||
}) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
|
||||
const phoneStr = input.phone ? `phone ${input.phone}` : 'unknown phone'
|
||||
const emailStr = input.email ? `email ${input.email}` : 'unknown email'
|
||||
const infosStr = `${phoneStr} and ${emailStr}`
|
||||
const propertyKeys = input.properties?.length ? input.properties : await _getContactPropertyKeys(hsClient)
|
||||
logger
|
||||
.forBot()
|
||||
.debug(
|
||||
`Searching for contact with ${infosStr} ${propertyKeys?.length ? `and properties ${propertyKeys?.join(', ')}` : ''}`
|
||||
)
|
||||
|
||||
const contact = await hsClient.searchContact({
|
||||
phone: input.phone,
|
||||
email: input.email,
|
||||
propertiesToReturn: propertyKeys,
|
||||
})
|
||||
|
||||
if (!contact) {
|
||||
return {
|
||||
contact: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
const portalId = await getOrFetchPortalId({ client, ctx, hsClient })
|
||||
return {
|
||||
contact: _mapHsContactToBpContact(contact),
|
||||
url: buildContactUrl({ portalId, contactId: contact.id }),
|
||||
}
|
||||
}
|
||||
|
||||
export const listContactProperties: bp.IntegrationProps['actions']['listContactProperties'] = async ({
|
||||
ctx,
|
||||
client,
|
||||
logger,
|
||||
}) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
try {
|
||||
const properties = await hsClient.listContactProperties()
|
||||
return {
|
||||
properties: properties.map((property) => ({
|
||||
name: property.name,
|
||||
label: property.label,
|
||||
type: property.type,
|
||||
fieldType: property.fieldType,
|
||||
groupName: property.groupName,
|
||||
description: property.description,
|
||||
...(property.referencedObjectType ? { referencedObjectType: property.referencedObjectType } : {}),
|
||||
})),
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
logger.forBot().debug(`Contact properties could not be retrieved: ${err}`)
|
||||
return { properties: [] }
|
||||
}
|
||||
}
|
||||
|
||||
export const createContact: bp.IntegrationProps['actions']['createContact'] = async ({
|
||||
ctx,
|
||||
client,
|
||||
input,
|
||||
logger,
|
||||
}) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
const { email, phone, owner, companies, tickets, properties } = input
|
||||
const additionalProperties = propertiesEntriesToRecord(properties ?? [])
|
||||
const newContact = await hsClient.createContact({
|
||||
email,
|
||||
phone,
|
||||
ownerEmailOrId: owner,
|
||||
companies,
|
||||
ticketIds: tickets,
|
||||
additionalProperties,
|
||||
})
|
||||
return {
|
||||
contact: _mapHsContactToBpContact(newContact),
|
||||
}
|
||||
}
|
||||
|
||||
export const getContact: bp.IntegrationProps['actions']['getContact'] = async ({ ctx, client, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
|
||||
const propertyKeys = await _getContactPropertyKeys(hsClient)
|
||||
const [contact, portalId] = await Promise.all([
|
||||
hsClient.getContact({
|
||||
contactId: input.contactIdOrEmail,
|
||||
propertiesToReturn: propertyKeys,
|
||||
}),
|
||||
getOrFetchPortalId({ client, ctx, hsClient }),
|
||||
])
|
||||
return {
|
||||
contact: _mapHsContactToBpContact(contact),
|
||||
url: buildContactUrl({ portalId, contactId: contact.id }),
|
||||
}
|
||||
}
|
||||
|
||||
export const updateContact: bp.IntegrationProps['actions']['updateContact'] = async ({
|
||||
ctx,
|
||||
client,
|
||||
input,
|
||||
logger,
|
||||
}) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
const { contactIdOrEmail, phone, email, properties } = input
|
||||
const additionalProperties = propertiesEntriesToRecord(properties ?? [])
|
||||
const updatedContact = await hsClient.updateContact({
|
||||
contactId: contactIdOrEmail,
|
||||
additionalProperties,
|
||||
email,
|
||||
phone,
|
||||
})
|
||||
return {
|
||||
contact: {
|
||||
..._mapHsContactToBpContact(updatedContact),
|
||||
email: updatedContact.properties['email'] ?? undefined,
|
||||
phone: updatedContact.properties['phone'] ?? undefined,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const deleteContact: bp.IntegrationProps['actions']['deleteContact'] = async ({
|
||||
ctx,
|
||||
client,
|
||||
input,
|
||||
logger,
|
||||
}) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
await hsClient.deleteContact({
|
||||
contactId: input.contactId,
|
||||
})
|
||||
return {}
|
||||
}
|
||||
|
||||
export const listContacts: bp.IntegrationProps['actions']['listContacts'] = async ({ ctx, client, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
const propertyKeys = await _getContactPropertyKeys(hsClient)
|
||||
const { contacts, nextToken } = await hsClient.listContacts({
|
||||
properties: propertyKeys,
|
||||
nextToken: input.meta.nextToken,
|
||||
})
|
||||
return {
|
||||
contacts: contacts.map(_mapHsContactToBpContact),
|
||||
meta: {
|
||||
nextToken,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { z } from '@botpress/sdk'
|
||||
import { dealSchema } from '../../definitions/actions/deal'
|
||||
import { getAuthenticatedHubspotClient, propertiesEntriesToRecord } from '../utils'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
type HubspotClient = Awaited<ReturnType<typeof getAuthenticatedHubspotClient>>
|
||||
type HsDeal = Awaited<ReturnType<HubspotClient['getDealById']>>
|
||||
type BpDeal = z.infer<typeof dealSchema>
|
||||
|
||||
const _mapHsDealToBpDeal = (hsDeal: HsDeal): BpDeal => ({
|
||||
id: hsDeal.id,
|
||||
name: hsDeal.properties.dealname ?? '',
|
||||
createdAt: hsDeal.createdAt.toISOString(),
|
||||
updatedAt: hsDeal.updatedAt.toISOString(),
|
||||
properties: hsDeal.properties,
|
||||
})
|
||||
|
||||
const _getDealPropertyKeys = async (hsClient: HubspotClient) => {
|
||||
const properties = await hsClient.getAllObjectProperties('deals')
|
||||
return properties.results.map((property) => property.name)
|
||||
}
|
||||
|
||||
export const searchDeal: bp.IntegrationProps['actions']['searchDeal'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
const propertyKeys = await _getDealPropertyKeys(hsClient)
|
||||
|
||||
const deal = await hsClient.searchDeal({ name: input.name, propertiesToReturn: propertyKeys })
|
||||
|
||||
if (!deal) {
|
||||
return {
|
||||
deal: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
deal: _mapHsDealToBpDeal(deal),
|
||||
}
|
||||
}
|
||||
|
||||
export const createDeal: bp.IntegrationProps['actions']['createDeal'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
|
||||
const deal = await hsClient.createDeal({
|
||||
name: input.name,
|
||||
properties: propertiesEntriesToRecord(input.properties ?? []),
|
||||
})
|
||||
|
||||
return {
|
||||
deal: _mapHsDealToBpDeal(deal),
|
||||
}
|
||||
}
|
||||
|
||||
export const getDeal: bp.IntegrationProps['actions']['getDeal'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
const propertyKeys = await _getDealPropertyKeys(hsClient)
|
||||
|
||||
const deal = await hsClient.getDealById({ dealId: input.dealId, propertiesToReturn: propertyKeys })
|
||||
|
||||
return {
|
||||
deal: _mapHsDealToBpDeal(deal),
|
||||
}
|
||||
}
|
||||
|
||||
export const updateDeal: bp.IntegrationProps['actions']['updateDeal'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
|
||||
const deal = await hsClient.updateDealById({
|
||||
dealId: input.dealId,
|
||||
name: input.name,
|
||||
properties: propertiesEntriesToRecord(input.properties ?? []),
|
||||
})
|
||||
|
||||
return {
|
||||
deal: {
|
||||
..._mapHsDealToBpDeal(deal),
|
||||
name: deal.properties.dealname ?? undefined,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const deleteDeal: bp.IntegrationProps['actions']['deleteDeal'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
|
||||
await hsClient.deleteDealById({ dealId: input.dealId })
|
||||
|
||||
return {}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { getAuthenticatedHubspotClient } from '../utils'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
export const getFileUrl: bp.IntegrationProps['actions']['getFileUrl'] = async ({ ctx, client, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
try {
|
||||
const url = await hsClient.getFileUrl({ fileName: input.fileName })
|
||||
return { url }
|
||||
} catch (err: unknown) {
|
||||
logger.forBot().debug(`File ${input.fileName} URL could not be retrieved: ${err}`)
|
||||
return { url: undefined }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
import { RuntimeError } from '@botpress/sdk'
|
||||
import { randomUUID } from 'crypto'
|
||||
import { getHitlClient } from '../hitl/client'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
export const createUser: bp.IntegrationProps['actions']['createUser'] = async ({ client, input, logger }) => {
|
||||
try {
|
||||
const { name = 'Unknown', email, pictureUrl } = input
|
||||
|
||||
if (!email || !email.trim()) {
|
||||
throw new RuntimeError('An identifier (email or phone number) is required for HITL user creation.')
|
||||
}
|
||||
|
||||
const trimmedIdentifier = email.trim()
|
||||
const isEmail = trimmedIdentifier.includes('@')
|
||||
const contactType = isEmail ? ('email' as const) : ('phone' as const)
|
||||
|
||||
const userTags: Record<string, string> = { contactType }
|
||||
if (isEmail) {
|
||||
userTags.email = trimmedIdentifier
|
||||
} else {
|
||||
userTags.phoneNumber = trimmedIdentifier
|
||||
}
|
||||
|
||||
const { user: botpressUser } = await client.getOrCreateUser({
|
||||
name,
|
||||
pictureUrl,
|
||||
tags: userTags,
|
||||
})
|
||||
|
||||
await client.setState({
|
||||
id: botpressUser.id,
|
||||
type: 'user',
|
||||
name: 'hitlUserInfo',
|
||||
payload: {
|
||||
name,
|
||||
contactIdentifier: trimmedIdentifier,
|
||||
contactType,
|
||||
},
|
||||
})
|
||||
|
||||
logger.forBot().debug(`createUser: created/found user ${botpressUser.id} (${contactType})`)
|
||||
|
||||
return { userId: botpressUser.id }
|
||||
} catch (thrown: unknown) {
|
||||
const error = thrown instanceof Error ? thrown : new Error(String(thrown))
|
||||
throw new RuntimeError(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
export const startHitl: bp.IntegrationProps['actions']['startHitl'] = async ({ ctx, client, logger, input }) => {
|
||||
const hitlClient = getHitlClient(ctx, client, logger)
|
||||
|
||||
try {
|
||||
const { userId, title, description = 'No description available' } = input
|
||||
|
||||
const {
|
||||
state: { payload: userInfo },
|
||||
} = await client.getState({ id: userId, name: 'hitlUserInfo', type: 'user' })
|
||||
|
||||
if (!userInfo?.contactIdentifier) {
|
||||
throw new RuntimeError('User identifier not found. Please ensure the user is created with createUser first.')
|
||||
}
|
||||
|
||||
const channelState = await client
|
||||
.getState({ id: ctx.integrationId, name: 'hitlConfig', type: 'integration' })
|
||||
.catch(() => null)
|
||||
|
||||
const channelInfo = channelState?.state?.payload
|
||||
if (!channelInfo?.channelId) {
|
||||
throw new RuntimeError(
|
||||
'HITL channel not configured. Please make sure you enabled/configured HITL for this Integration.'
|
||||
)
|
||||
}
|
||||
|
||||
const { name, contactIdentifier } = userInfo
|
||||
const { channelId, defaultInboxId, channelAccounts } = channelInfo
|
||||
|
||||
const inboxId = input.hitlSession?.inboxId?.length ? input.hitlSession.inboxId : defaultInboxId
|
||||
const channelAccountId = channelAccounts?.[inboxId]
|
||||
|
||||
if (!channelAccountId) {
|
||||
throw new RuntimeError(
|
||||
`No channel account found for inbox ${inboxId}. Make sure this inbox was selected during setup.`
|
||||
)
|
||||
}
|
||||
|
||||
const integrationThreadId = randomUUID()
|
||||
|
||||
const result = await hitlClient.createConversation(
|
||||
channelId,
|
||||
channelAccountId,
|
||||
integrationThreadId,
|
||||
name,
|
||||
contactIdentifier,
|
||||
title || 'New Support Request',
|
||||
description
|
||||
)
|
||||
|
||||
const hubspotConversationId = result.data.conversationsThreadId
|
||||
|
||||
const { conversation } = await client.createConversation({
|
||||
channel: 'hitl',
|
||||
tags: {
|
||||
id: hubspotConversationId,
|
||||
userId,
|
||||
integrationThreadId,
|
||||
inboxId,
|
||||
},
|
||||
})
|
||||
|
||||
return { conversationId: conversation.id }
|
||||
} catch (thrown: unknown) {
|
||||
const error = thrown instanceof Error ? thrown : new Error(String(thrown))
|
||||
logger.forBot().error(`startHitl error: ${error.message}`)
|
||||
throw new RuntimeError(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
export const stopHitl: bp.IntegrationProps['actions']['stopHitl'] = async ({ ctx, client, input, logger }) => {
|
||||
const { conversationId } = input
|
||||
try {
|
||||
const { conversation } = await client.getConversation({ id: conversationId })
|
||||
const threadId = conversation.tags.id
|
||||
if (!threadId) {
|
||||
logger.forBot().warn(`stopHitl: no HubSpot thread ID on conversation ${conversationId} — skipping close`)
|
||||
return {}
|
||||
}
|
||||
const hitlClient = getHitlClient(ctx, client, logger)
|
||||
await hitlClient.closeThread(threadId)
|
||||
logger.forBot().info(`stopHitl: closed HubSpot thread ${threadId}`)
|
||||
} catch (thrown: unknown) {
|
||||
const error = thrown instanceof Error ? thrown : new Error(String(thrown))
|
||||
logger.forBot().error(`stopHitl error: ${error.message}`)
|
||||
throw new RuntimeError(error.message)
|
||||
}
|
||||
return {}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import * as companyActions from './company'
|
||||
import * as contactActions from './contact'
|
||||
import * as dealActions from './deal'
|
||||
import * as fileActions from './file'
|
||||
import { createUser, startHitl, stopHitl } from './hitl'
|
||||
import * as leadActions from './lead'
|
||||
import * as ownerActions from './owner'
|
||||
import * as ticketActions from './ticket'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
export default {
|
||||
...contactActions,
|
||||
...dealActions,
|
||||
...ticketActions,
|
||||
...leadActions,
|
||||
...companyActions,
|
||||
...ownerActions,
|
||||
...fileActions,
|
||||
createUser,
|
||||
startHitl,
|
||||
stopHitl,
|
||||
} as const satisfies bp.IntegrationProps['actions']
|
||||
@@ -0,0 +1,88 @@
|
||||
import { z } from '@botpress/sdk'
|
||||
import { leadSchema } from '../../definitions/actions/lead'
|
||||
import { getAuthenticatedHubspotClient, propertiesEntriesToRecord } from '../utils'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
type HubspotClient = Awaited<ReturnType<typeof getAuthenticatedHubspotClient>>
|
||||
type HsLead = Awaited<ReturnType<HubspotClient['getLeadById']>>
|
||||
type BpLead = z.infer<typeof leadSchema>
|
||||
|
||||
const _mapHsLeadToBpLead = (hsLead: HsLead): BpLead => ({
|
||||
id: hsLead.id,
|
||||
name: hsLead.properties.hs_lead_name ?? '',
|
||||
createdAt: hsLead.createdAt.toISOString(),
|
||||
updatedAt: hsLead.updatedAt.toISOString(),
|
||||
properties: hsLead.properties,
|
||||
})
|
||||
|
||||
const _getLeadPropertyKeys = async (hsClient: HubspotClient) => {
|
||||
const properties = await hsClient.getAllObjectProperties('leads')
|
||||
return properties.results.map((property) => property.name)
|
||||
}
|
||||
|
||||
export const searchLead: bp.IntegrationProps['actions']['searchLead'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
const propertyKeys = await _getLeadPropertyKeys(hsClient)
|
||||
|
||||
const lead = await hsClient.searchLead({ name: input.name, propertiesToReturn: propertyKeys })
|
||||
|
||||
if (!lead) {
|
||||
return {
|
||||
lead: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
lead: _mapHsLeadToBpLead(lead),
|
||||
}
|
||||
}
|
||||
|
||||
export const createLead: bp.IntegrationProps['actions']['createLead'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
|
||||
const lead = await hsClient.createLead({
|
||||
name: input.name,
|
||||
contactEmailOrId: input.contact,
|
||||
properties: propertiesEntriesToRecord(input.properties ?? []),
|
||||
})
|
||||
|
||||
return {
|
||||
lead: _mapHsLeadToBpLead(lead),
|
||||
}
|
||||
}
|
||||
|
||||
export const getLead: bp.IntegrationProps['actions']['getLead'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
const propertyKeys = await _getLeadPropertyKeys(hsClient)
|
||||
|
||||
const lead = await hsClient.getLeadById({ leadId: input.leadId, propertiesToReturn: propertyKeys })
|
||||
|
||||
return {
|
||||
lead: _mapHsLeadToBpLead(lead),
|
||||
}
|
||||
}
|
||||
|
||||
export const updateLead: bp.IntegrationProps['actions']['updateLead'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
|
||||
const lead = await hsClient.updateLead({
|
||||
leadId: input.leadId,
|
||||
name: input.name,
|
||||
properties: propertiesEntriesToRecord(input.properties ?? []),
|
||||
})
|
||||
|
||||
return {
|
||||
lead: {
|
||||
..._mapHsLeadToBpLead(lead),
|
||||
name: lead.properties.hs_lead_name ?? undefined,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const deleteLead: bp.IntegrationProps['actions']['deleteLead'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
|
||||
await hsClient.deleteLead({ leadId: input.leadId })
|
||||
|
||||
return {}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { getAuthenticatedHubspotClient } from '../utils'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
export const getOwner: bp.IntegrationProps['actions']['getOwner'] = async ({ ctx, client, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ ctx, client, logger })
|
||||
try {
|
||||
const owner = await hsClient.getOwnerById({ ownerId: input.ownerId })
|
||||
return {
|
||||
owner: {
|
||||
id: owner.id,
|
||||
email: owner.email,
|
||||
firstName: owner.firstName,
|
||||
lastName: owner.lastName,
|
||||
userId: owner.userId,
|
||||
type: owner.type,
|
||||
archived: owner.archived,
|
||||
createdAt: owner.createdAt.toISOString(),
|
||||
updatedAt: owner.updatedAt.toISOString(),
|
||||
},
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
logger.forBot().debug(`Owner ${input.ownerId} could not be retrieved: ${err}`)
|
||||
return { owner: undefined }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { z } from '@botpress/sdk'
|
||||
import { ticketSchema } from '../../definitions/actions/ticket'
|
||||
import { getAuthenticatedHubspotClient, propertiesEntriesToRecord } from '../utils'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
type HubspotClient = Awaited<ReturnType<typeof getAuthenticatedHubspotClient>>
|
||||
type HsTicket = Awaited<ReturnType<HubspotClient['createTicket']>>
|
||||
type BpTicket = z.infer<typeof ticketSchema>
|
||||
|
||||
const _mapHsTicketToBpTicket = (hsTicket: HsTicket): BpTicket => ({
|
||||
id: hsTicket.id,
|
||||
subject: hsTicket.properties.subject ?? '',
|
||||
category: hsTicket.properties.hs_ticket_category ?? '',
|
||||
description: hsTicket.properties.content ?? '',
|
||||
priority: hsTicket.properties.hs_ticket_priority ?? '',
|
||||
source: hsTicket.properties.source_type ?? '',
|
||||
properties: hsTicket.properties,
|
||||
})
|
||||
|
||||
export const createTicket: bp.IntegrationProps['actions']['createTicket'] = async ({ client, ctx, input, logger }) => {
|
||||
const hsClient = await getAuthenticatedHubspotClient({ client, ctx, logger })
|
||||
|
||||
const newTicket = await hsClient.createTicket({
|
||||
subject: input.subject,
|
||||
category: input.category,
|
||||
source: input.source,
|
||||
description: input.description,
|
||||
additionalProperties: propertiesEntriesToRecord(input.properties ?? []),
|
||||
pipelineNameOrId: input.pipeline,
|
||||
pipelineStageNameOrId: input.pipelineStage,
|
||||
priority: input.priority,
|
||||
ticketOwnerEmailOrId: input.ticketOwner,
|
||||
requesterEmailOrId: input.requester,
|
||||
companyIdOrNameOrDomain: input.company,
|
||||
})
|
||||
|
||||
return {
|
||||
ticket: _mapHsTicketToBpTicket(newTicket),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user