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.') }