v1.2.0

Recipe: Webhook CLI smoke test

A 30-line Node script that authenticates against a Bitrix24 portal via inbound webhook and prints the calling user — useful as the first thing you run after creating a webhook.
We are still updating this page. Some data may be missing here — we will complete it shortly.

Goal

Verify that a freshly minted Bitrix24 inbound webhook is reachable, authenticated, and authorized for the scopes you expect — before you wire it into anything bigger. The script calls profile and app.info, prints the answers, and exits non-zero on any error.

Stack & Prerequisites

  • Node.js 20+, ESM
  • @bitrix24/b24jssdk@^1.0.0
  • A webhook URL with at least the default scope. Set it as B24_HOOK.
pnpm add @bitrix24/b24jssdk
export B24_HOOK="https://your-portal.bitrix24.com/rest/1/xxxxxxxxxxxxxxxx/"

Full Example

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

Run It

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

A copy-pasted-with-typo webhook URL fails with a 401 wrapped in SdkError and the script exits with code 1. A network hiccup is retried automatically by the built-in RateLimiter (maxRetries defaults to 3, configurable via restrictionParams.maxRetries — see Restrictions System) before the failure is surfaced.

How It Works

  • B24Hook.fromWebhookUrl() validates the URL shape and pulls the user id, secret token, and portal hostname out of the path. Anything that doesn't look like https://<host>/rest/<userId>/<token>/ throws synchronously — typo-resistant.
  • actions.v2.call.make({ method }) is the modern single-method call. It returns Promise<AjaxResult>; .getData().result is whatever Bitrix24 placed under result for that method.
  • Errors come back as SdkError with the underlying axios error attached on cause. Catching the class lets you distinguish SDK errors from caller bugs.

Limitations

  • Inbound webhooks have a hard rate cap (2 RPS per user per portal at the time of writing). For more than a smoke test, configure restrictionParams — see the dashboard recipe.
  • The profile method returns the user the webhook was created under, not whoever runs the script. There is no impersonation.
  • This recipe deliberately avoids try { … } finally { b24.destroy() }B24Hook has no destroy step. B24Frame does; that's a separate code path.

See also