Bitrix Task Router
Assign Bitrix24 tasks to the right person automatically, by rule, with a human check before anything is written.
What it does
- Reads open tasks from Bitrix24 via an inbound webhook.
- Applies a routing rule to decide the responsible person for each task.
- Prints a preview of every proposed change (task → new owner, and why).
- Writes the assignments back to Bitrix only when run with
--commit. Default is a dry run.
Writing to the CRM is a real change to live data, so the script never writes on its own. Preview first, confirm, then commit. Once the team trusts the output, it can be wired to a scheduled task.
The routing rule
Default rule:
- Decide parity from the numeric task ID: even ID vs. odd ID.
- If the task title contains the keyword (default
RUSH, case-insensitive): even → Hazel, odd → Matt. - Otherwise (no keyword): even → Marco, odd → Rafael.
Assumptions baked in that need confirming:
- "Ending in an even/odd number" is read as the task ID being even/odd. If Marco means a different number (an order number in the title, a custom field), change
parity_sourcein the config. - The
RUSHkeyword is matched against the task title. If it lives in a tag, group, or custom field instead, changekeyword_fieldin the config. - A
RUSHmatch fully overrides the default Marco/Rafael split. If instead it should be an additional filter on top, that's a different rule, so flag it.
All of this is in config.json, so tuning the rule does not mean touching the code.
Setup
- Copy
config.example.jsontoconfig.jsonand fill in:user_ids: the Bitrix user IDs for Marco, Rafael, Hazel, Matt.parity_source,keyword,keyword_field: leave as defaults unless the assumptions above are wrong.task_filter: which tasks to consider (default: open and not closed).
- Copy
.env.exampleto.envand setBITRIX_WEBHOOK_URLto the inbound webhook base URL (thehttps://<domain>.bitrix24.com/rest/<user_id>/<token>/one). The webhook needs task scope (read + write).
The webhook URL carries its own auth, so treat .env like a password. Don't commit it.
Running it
Dry run (the default: shows the plan, writes nothing):
python scripts/bitrix_router.pyTry the rule with no Bitrix connection, using bundled fake data:
python scripts/bitrix_router.py --mockCommit the assignments to Bitrix (after you've eyeballed the dry run):
python scripts/bitrix_router.py --commitOutput
A table, one row per task: ID, title, current owner, proposed owner, and the reason ("RUSH + even -> hazel"). In dry-run mode it ends with a count of what would change. With --commit it reports each write and any failures.
How to read failures
BITRIX_WEBHOOK_URL not set→.envmissing or empty.- HTTP 401 / "Invalid token" → webhook URL wrong or revoked.
- "INVALID_USER" on write → a user ID in
config.jsondoesn't exist in Bitrix. - Tasks come back empty → check
task_filter; the default only pulls open tasks.
Going automatic
Once the dry runs look right and the team trusts it, this can run on a schedule (e.g. every 30 minutes) with --commit. Don't schedule the commit step until the preview has been validated against live data for a few days. An unsupervised mis-route is annoying to unwind.