Files
botpress--botpress/integrations/shopify-admin/src/setup.ts
T
2026-07-13 13:34:48 +08:00

78 lines
2.8 KiB
TypeScript

import { RuntimeError } from '@botpress/sdk'
import { ShopifyClient } from './client'
import * as bp from '.botpress'
const WEBHOOK_TOPICS = ['ORDERS_CREATE', 'ORDERS_UPDATED', 'ORDERS_CANCELLED', 'ORDERS_FULFILLED', 'ORDERS_PAID']
export const register: bp.IntegrationProps['register'] = async ({ client, ctx, webhookUrl, logger }) => {
logger.forBot().info('Registering Shopify Admin integration...')
let shopify: ShopifyClient
try {
shopify = await ShopifyClient.create({ client, ctx })
} catch {
logger
.forBot()
.info('No Shopify credentials yet — skipping webhook subscription. Complete the OAuth wizard to finish setup.')
return
}
// Replace any previously-created subscriptions with a fresh set (e.g., after a re-auth).
const { state } = await client.getState({ type: 'integration', name: 'credentials', id: ctx.integrationId })
for (const id of state.payload.webhookSubscriptionIds ?? []) {
await shopify
.unsubscribeWebhook(id)
.catch((err) => logger.forBot().warn({ err }, `Failed to delete stale webhook subscription ${id}`))
}
const subscriptionIds: string[] = []
const failures: Array<{ topic: string; err: unknown }> = []
for (const topic of WEBHOOK_TOPICS) {
try {
const id = await shopify.subscribeWebhook(topic, webhookUrl)
if (id) {
subscriptionIds.push(id)
}
} catch (err) {
failures.push({ topic, err })
logger.forBot().warn({ err }, `Failed to subscribe to Shopify webhook topic ${topic}`)
}
}
await client.setState({
type: 'integration',
name: 'credentials',
id: ctx.integrationId,
payload: { ...state.payload, webhookSubscriptionIds: subscriptionIds },
})
if (subscriptionIds.length === 0 && failures.length === WEBHOOK_TOPICS.length) {
throw new RuntimeError(
`All Shopify webhook subscriptions failed (${failures.length}/${WEBHOOK_TOPICS.length}); the access token is likely invalid. Re-authorize the integration.`
)
}
logger.forBot().info(`Shopify Admin integration registered with ${subscriptionIds.length} webhook subscription(s).`)
}
export const unregister: bp.IntegrationProps['unregister'] = async ({ client, ctx, logger }) => {
logger.forBot().info('Unregistering Shopify Admin integration...')
let shopify: ShopifyClient
try {
shopify = await ShopifyClient.create({ client, ctx })
} catch {
logger.forBot().info('No Shopify credentials — nothing to unregister.')
return
}
const { state } = await client.getState({ type: 'integration', name: 'credentials', id: ctx.integrationId })
for (const id of state.payload.webhookSubscriptionIds ?? []) {
await shopify
.unsubscribeWebhook(id)
.catch((err) => logger.forBot().warn({ err }, `Failed to delete webhook subscription ${id}`))
}
logger.forBot().info('Shopify Admin integration unregistered.')
}