78 lines
2.8 KiB
TypeScript
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.')
|
|
}
|