Рецепт: smoke-тест вебхука в CLI

Node-скрипт на 30 строк, который аутентифицируется на портале Bitrix24 через входящий вебхук и печатает вызывающего пользователя — полезно как первое, что вы запускаете после создания вебхука.
Мы всё ещё дорабатываем эту страницу. Некоторых данных здесь может не хватать — скоро дополним.

Цель

Убедиться, что только что созданный входящий вебхук Bitrix24 доступен, аутентифицирован и авторизован на ожидаемые scope — прежде чем встраивать его во что-то большее. Скрипт вызывает profile и app.info, печатает ответы и завершается с ненулевым кодом при любой ошибке.

Стек и предпосылки

  • Node.js 20+, ESM
  • @bitrix24/b24jssdk@^1.0.0
  • URL вебхука хотя бы с дефолтным scope. Задайте его как B24_HOOK.
pnpm add @bitrix24/b24jssdk
export B24_HOOK="https://your-portal.bitrix24.com/rest/1/xxxxxxxxxxxxxxxx/"

Полный пример

scripts/b24-ping.mjs:

import { B24Hook, SdkError } from '@bitrix24/b24jssdk'

const hookUrl = process.env.B24_HOOK
if (!hookUrl) {
  console.error('B24_HOOK is not set')
  process.exit(2)
}

const b24 = B24Hook.fromWebhookUrl(hookUrl)

try {
  const profile = await b24.actions.v2.call.make({ method: 'profile' })
  const appInfo = await b24.actions.v2.call.make({ method: 'app.info' })

  const me = profile.getData().result
  const app = appInfo.getData().result

  console.log(`portal:    ${app.DOMAIN}`)
  console.log(`as user:   #${me.ID} ${me.NAME ?? ''} ${me.LAST_NAME ?? ''}`)
  console.log(`scope:     ${app.SCOPE?.join?.(',') ?? app.SCOPE ?? '(none)'}`)
  console.log('webhook is alive')
}
catch (error) {
  if (error instanceof SdkError) {
    console.error(`SDK error [${error.cause?.name ?? 'unknown'}]: ${error.message}`)
  }
  else {
    console.error(error)
  }
  process.exit(1)
}

Запуск

node scripts/b24-ping.mjs
# portal:    your-portal.bitrix24.com
# as user:   #1 Anna Ivanova
# scope:     crm,user,im
# webhook is alive

Скопированный с опечаткой URL вебхука падает с 401, обёрнутым в SdkError, и скрипт завершается с кодом 1. Сетевой сбой автоматически повторяется встроенным RateLimiter (maxRetries по умолчанию 3, настраивается через restrictionParams.maxRetries — см. Система ограничений) до того, как ошибка всплывёт.

Как это работает

  • B24Hook.fromWebhookUrl() валидирует форму URL и извлекает id пользователя, секретный токен и хост портала из пути. Всё, что не похоже на https://<host>/rest/<userId>/<token>/, выбрасывает синхронно — устойчиво к опечаткам.
  • actions.v2.call.make({ method }) — современный вызов одного метода. Возвращает Promise<AjaxResult>; .getData().result — то, что Bitrix24 поместил под result для этого метода.
  • Ошибки возвращаются как SdkError с нижележащей ошибкой axios в cause. Перехват класса позволяет отличить ошибки SDK от багов вызывающего кода.

Ограничения

  • У входящих вебхуков жёсткий лимит частоты (2 RPS на пользователя на портал на момент написания). Для чего-то большего, чем smoke-тест, настройте restrictionParams — см. рецепт с дашбордом.
  • Метод profile возвращает пользователя, под которым создан вебхук, а не того, кто запускает скрипт. Имперсонации нет.
  • Этот рецепт намеренно избегает try { … } finally { b24.destroy() } — у B24Hook нет шага destroy. У B24Frame есть; это отдельный путь кода.

См. также