How-to
Article MarkdownReport an error

How to configure UniTalk

Connect UniTalk to ConnectiveOne with the built-in UniTalk provider preset. Completed calls appear in the call archive with recording, assignee, and client card fields.

This is a full implementation guide: preset, webhook, two operator-assignment paths (with ready JSON), client fields, smoke test, and troubleshooting.

Prerequisites

  • UniTalk admin access
  • ConnectiveOne bot settings (Settings → Bots → Telephony)
  • Operator emails in ConnectiveOne match emails in UniTalk (for auto-assignment)
  • For path A (recommended): SIP line (line in UniTalk) ↔ operator email table
  • For path B (optional): UniTalk API key (Integration → API)

When to use it

  • UniTalk is your telephony provider
  • You need a quick setup without manual webhook field mapping
  • Completed calls should appear in Operator Panel with recording and assignee

Two ways to assign the operator

Path A — operator_mapping Path B — action_telephony_staff_enrich
Idea Static SIP → email table in Advanced Config UniTalk API /users/list, match on line
External API No Yes (cache required — UniTalk rate limits)
When to choose Stable line list (typical production setup) Lines change often; you do not want a manual table
Channel setup operator_mapping block in JSON API Key + Webhook enrich action = action_telephony_staff_enrich

When operator_mapping matches, ConnectiveOne skips enrich — no extra API calls.

action_telephony_staff_enrich is a generic internal action (any HTTP staff list via json_config). Below is a ready UniTalk configuration.


Step 1: Open channel settings

  1. SettingsBots
  2. Select the bot
  3. Open the Telephony tab
  4. Create a new channel or edit an existing one

Minimum fields:

Channel field Value
Name e.g. UniTalk
Active On
Default country code e.g. UA / 380 (as on your instance)

After the first save you get Webhook URL and token.

Step 2: Apply the UniTalk preset

  1. In Advanced Config (JSON), select UniTalk from the provider preset list
  2. Click Apply preset
  3. Save and copy the Webhook URL (including ?token=...)

The preset adds:

  • event_detection — only CALL_END
  • field_mapping / status_mapping / direction_mapping
  • client_field_mapping — UTM, source, comment → client card
  • recordings from call.link

Preset JSON (without operator_mapping) also lives in the repo: apps/engine/modules/extra/telephony/presets/unitalk.json.

Step 3: Webhook in UniTalk

  1. UniTalk cabinet → Event handlers
  2. Add a Send webhook handler
  3. Bind only to CALL_END (do not send CALL_NEW, etc.)
Field in UniTalk Value
Method POST
URL Full ConnectiveOne Webhook URL, e.g. https://<your-domain>/kw/telephony/webhook/<channel_id>?token=<webhook_token>
Body Standard JSON

Token only in the URL (?token=...). Do not change the /kw/telephony/webhook/... path.

Example CALL_END body (inbound)

{
  "event": "CALL_END",
  "call": {
    "id": "sample-call-id",
    "from": "380501234567",
    "to": "9578",
    "direction": "in",
    "state": "ANSWER",
    "secondsFullTime": 120,
    "secondsTalk": 90,
    "date": "2026-09-02T12:00:00.000Z",
    "link": "https://example.test/recording.mp3",
    "utmSource": "google",
    "utmCampaign": "brand",
    "source": "ads",
    "comment": "Call comment"
  }
}
UniTalk field After UniTalk preset in ConnectiveOne
event Must be CALL_END, otherwise 200 ignored
call.id Call ID (idempotency — retry does not create a duplicate)
call.from / call.to Client number or operator SIP (depends on direction)
call.direction in / out
call.state ANSWER → answered; NOANSWER, BUSY, … → missed
call.link Recording
call.utmSource, utmCampaign, source, comment Client card (client_field_mapping)

Direction and operator SIP:

Direction Client number Operator SIP (key in operator_mapping / enrich lookup)
in (inbound) call.from call.to
out (outbound) call.to call.from

In the ConnectiveOne channel form: webhook format = JSON.


After Apply preset, add operator_mapping to the same JSON (same level as event_detection, field_mapping, …), then Validate JSON / Save.

Fragment example

"operator_mapping": {
  "source": {
    "in": "callee_number",
    "out": "caller_number"
  },
  "map": {
    "9578": "[email protected]",
    "201": "[email protected]"
  }
}

Full Advanced Config example (preset + mapping)

Copy, replace SIP → email with your values, save:

{
  "event_detection": {
    "mode": "event_field",
    "event_field": "event",
    "call_ended_values": ["CALL_END"]
  },
  "field_mapping": {
    "call_id": "call.id",
    "caller_number": "call.from",
    "callee_number": "call.to",
    "status": "call.state",
    "duration": "call.secondsFullTime",
    "talk_duration": "call.secondsTalk",
    "recording_url": "call.link",
    "direction": "call.direction",
    "date": "call.date",
    "utm_source": "call.utmSource",
    "utm_campaign": "call.utmCampaign",
    "call_source": "call.source"
  },
  "status_mapping": {
    "ANSWER": "answered",
    "NOANSWER": "missed",
    "BUSY": "missed",
    "CANCEL": "missed",
    "AUTOCANCEL": "missed",
    "UNREACHABLE": "missed",
    "VOICE_MAIL": "missed",
    "FAIL": "failed",
    "BLOCKED": "failed",
    "AUDIO_ERR": "failed"
  },
  "direction_mapping": {
    "in": "in",
    "out": "out",
    "inbound": "in",
    "outbound": "out"
  },
  "recordings": {
    "enabled": true,
    "download": false
  },
  "transcription": {
    "enabled": false,
    "source": "provider"
  },
  "client_field_mapping": {
    "utm_source": "call.utmSource",
    "utm_campaign": "call.utmCampaign",
    "call_source": "call.source",
    "last_call_comment": "call.comment"
  },
  "operator_mapping": {
    "source": {
      "in": "callee_number",
      "out": "caller_number"
    },
    "map": {
      "9578": "[email protected]",
      "201": "[email protected]"
    }
  }
}

Rules:

  1. Keys in map are raw SIP strings as in UniTalk ("9578"), before E.164 (not +3809578).
  2. Email in ConnectiveOne must match an active Operator Panel user.
  3. Each UniTalk operator must have an internal line filled in.
  4. Webhook enrich action can stay empty.

Step 4B: Dynamic assignment via action_telephony_staff_enrich (optional)

Use when you do not maintain operator_mapping (or as a fallback when a line is missing from the table).

4B.1 Channel fields

Field Value
API Key UniTalk API key (Integration → API)
API Base URL (if present) https://api.unitalk.cloud/api
Webhook enrich action action_telephony_staff_enrich

The key is a secret. Do not publish it in chats or tickets.

4B.2 Action parameters (json_config)

The action ships with the product (internal). If you use an Action Jail wrapper on the instance, put the same parameters in the action JSON config.

Ready UniTalk example:

{
  "api_url": "https://api.unitalk.cloud/api/users/list",
  "http_method": "POST",
  "auth_header_name": "Authorization",
  "auth_scheme": "raw",
  "request_body": {},
  "response_items_path": "",
  "match_field": "line",
  "lookup_source": {
    "in": "callee_number",
    "out": "caller_number"
  },
  "email_field": "email",
  "name_fields": ["firstName", "lastName"],
  "cache_ttl_seconds": 300,
  "timeout_ms": 8000
}
Parameter Why
match_field: line Internal PBX SIP in /users/list (not phone — mobile, often null)
lookup_source Where to take SIP from the normalized call: in → callee_number, out → caller_number
cache_ttl_seconds Staff-list cache (UniTalk limits ~15 req/s)
api_key In json_config or only in the channel API Key field

If the API returns a root array, leave response_items_path as "". If wrapped as { "data": [ … ] }, set "data".

4B.3 Sample UniTalk /users/list fragment

[
  {
    "id": 1,
    "email": "[email protected]",
    "firstName": "Ivan",
    "lastName": "Petrenko",
    "line": "9578",
    "phone": null,
    "role": "OPERATOR"
  }
]

ConnectiveOne finds line = call SIP and writes manager_email / manager_name → assignment by email.

General enrich how-to: Configure webhook enrichment.
Implementor template: docs/developer/engine/modules/telephony/action_telephony_staff_enrich.template.md.


Step 5: Client card fields

The preset already includes client_field_mapping:

Key in extra_data Webhook path
utm_source call.utmSource
utm_campaign call.utmCampaign
call_source call.source
last_call_comment call.comment

For fields to show on the client card, add matching custom fields in Instance Settings (extra_data schema). Telephony merges values without Action Jail.


Step 6: Save and smoke-test

  1. Save the channel (active).
  2. Use Test webhook in the form or the curl below.
  3. Make test inbound and outbound calls in UniTalk.
  4. Operator Panel → Closed requests: telephony dialogue, recording (if call.link), assignee.

Example curl (local / stage smoke)

Replace URL and token. Body as in step 3; for path A align "to" / emails with your operator_mapping.

curl -X POST 'https://<your-domain>/kw/telephony/webhook/<channel_id>?token=<webhook_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "event": "CALL_END",
    "call": {
      "id": "smoke-unitalk-001",
      "from": "380501234567",
      "to": "9578",
      "direction": "in",
      "state": "ANSWER",
      "secondsFullTime": 60,
      "secondsTalk": 45,
      "date": "2026-09-02T12:00:00.000Z",
      "link": "https://example.test/recording.mp3",
      "utmSource": "google",
      "utmCampaign": "brand",
      "source": "ads",
      "comment": "Smoke test"
    }
  }'

Expected: HTTP 200 with dialogue_id.
Same call.id again → 200, already processed, no duplicate.

Non-CALL_END (e.g. "event": "CALL_NEW") → 200 ignored, no dialogue.

Acceptance checklist

# Check Expected
1 CALL_END Dialogue created, telephony channel, completed
2 Non-CALL_END 200 ignored, no dialogue
3 call.link present Recording on the dialogue
4 Inbound / outbound Client by correct number
5 SIP in and out Operator assigned (mapping or enrich)
6 UTM / comment Values on client card (if Instance Settings fields exist)
7 Same call.id twice No duplicate
8 Path B Cache / no rate-limit lock; or path A without enrich

Troubleshooting

Symptom Check
200 ignored on every webhook Body has "event": "CALL_END"; UniTalk preset applied (event_detection)
Dialogue exists, no operator Email in map / UniTalk matches C1 user; SIP as "9578", not E.164; for out — line in call.from
Enrich not called Matching operator_mapping — expected (enrich skipped)
Enrich error / no email match_field = line; /users/list has line; channel API Key set
Duplicate dialogues Different call.id from UniTalk; idempotency is per id
UTM not visible in UI Merge into extra_data works — add custom field display in Instance Settings
403 / unauthorized webhook URL token matches channel token

What the UniTalk preset includes

  • Event detection for CALL_END only
  • Field, status, and direction mapping
  • Recordings from call.link
  • client_field_mapping (UTM, source, comment)

operator_mapping and webhook enrich are not in the Apply preset button — add them in steps 4A / 4B.

Limitations

  • Only completed calls (CALL_END); no realtime during the call
  • Click-to-call from ConnectiveOne is out of scope
  • UniTalk transcript / analytics is a separate scope
Using your own AI agent?Install the open skill so your AI agent can work with current official ConnectiveOne documentation.Get the skillNeed support?Couldn’t find the answer or need help from the ConnectiveOne team? Create a request in Client Portal.Create a request