---
title: "telephony.incoming / web.incoming"
description: "خطاف ويب حاجب يضبط إعدادات مكالمة واردة في الوقت الفعلي."
---

عندما تصل مكالمة هاتفية واردة إلى رقم **من دون وكيل
مُعيَّن**، أو تبدأ جلسة أداة ويب على مفتاح قابل للنشر في
`mode="webhook"`، يرسل ThunderPhone طلبًا **حاجبًا**
بـ `telephony.incoming` / `web.incoming` إلى
[عنوان URL القديم للويب هوك](/api-reference/organizations#legacy-single-url-webhook)
وينتظر استجابة إعداد: حتى **13 ثانية** للمكالمة الهاتفية، بما في ذلك إعادة محاولة واحدة، وحتى **10 ثوانٍ** لجلسة الأداة (راجع [المهلات وإعادات المحاولة](#timeouts-and-retries)). استخدم هذا
التبادل لاختيار موجّه وصوت وأدوات ديناميكيًا لكل مكالمة —
راجع [دليل إعداد المكالمات الديناميكي](/ar/guides/dynamic-call-config)
للاطلاع على النمط المتكامل.

<Note>
  تتلقى [نقاط نهاية الويب هوك](/ar/webhooks/endpoints) المشتركة أيضًا
  `telephony.incoming` / `web.incoming` — لكل مكالمة واردة
  وجلسة ويب **على الإطلاق**، سواء كانت مهيأة بعامل أم لا — لكن عمليات
  التسليم هذه إشعارات إرسال دون انتظار تتضمن `event_id`، وليست حاجبة
  مطلقًا. يحمل الويب هوك القديم ذو عنوان URL الواحد فقط تبادل الإعداد
  الوارد في هذه الصفحة. تتوفر أشكال إشعارات نقاط النهاية في
  [كتالوج الأحداث](/ar/webhooks/events).
</Note>

## المهلات وإعادات المحاولة

أجب بسرعة: المتصل ينتظر على الخط بينما تتخذ قرارك.

لمكالمة هاتفية (`telephony.incoming`):

- قد تستغرق المحاولة الأولى ما يصل إلى **10 ثوانٍ**.
- إذا انتهت مهلتها، أو تعذر الاتصال، أو تلقّت استجابة `5xx` أو `408` أو `429`، يحاول ThunderPhone مرة أخرى. تحصل إعادة المحاولة على ما تبقى من ميزانية قدرها **13 ثانية** للتبادل بأكمله: نحو 3 ثوانٍ بعد محاولة أولى انتهت مهلتها، وما يقارب 13 ثانية كاملة بعد فشل سريع. لا تتم إعادة المحاولة إذا كان سيتبقى أقل من ثانيتين.
- أي استجابة `4xx` أخرى، أو استجابة تتجاوز [حد الحجم](#response-size-limit)، أو استجابة `2xx` لا يحتوي نصها على إعداد صالح، تكون نهائية ولا تتم إعادة محاولتها.
- ترسل كلتا المحاولتين النص نفسه، و`X-ThunderPhone-Signature` نفسه، وترويسة `X-ThunderPhone-Idempotency-Key` نفسها (`telephony-incoming-<call_id>`)، بحيث يمكن لمعالج له آثار جانبية التعرّف على إعادة المحاولة.

لا يوجد وكيل صوتي بديل. إذا لم يصل إعداد قابل للاستخدام، تُنهى المكالمة فورًا بدلًا من ترك المتصل على خط صامت. تظهر في سجل المكالمات كمكالمة فاشلة غير مفوترة مع `end_reason` بقيمة `inbound_config_webhook_failed`، ويُرسل حدث [`telephony.complete`](/ar/webhooks/call-complete) المعتاد.

تحصل جلسة عنصر واجهة (`web.incoming`) على محاولة واحدة تصل مدتها إلى 10 ثوانٍ. إذا فشلت، يفشل طلب الجلسة بالرمز `502` أو `422`.

<Warning>
  **لا تتضمن المكالمات المهيأة عبر الويب هوك إعلان موافقة من ThunderPhone.**
  تتجاوز المكالمات المهيأة عبر هذا التبادل إعلان بدء المكالمة على مستوى
  الوكيل، وتُستثنى صراحةً من إطار إعلانات الموافقة في ThunderPhone
  (شروط الخدمة، قسم "التسجيل والموافقة"). تتحمل مؤسستك وحدها مسؤولية
  كل إشعار وموافقة مطلوبين بشأن التسجيل والمراقبة ومشاركة الذكاء
  الاصطناعي وتحديد هوية المتصل في هذه المكالمات —
  إذ لا يزال بالإمكان تسجيل المكالمات وتفريغها وتحليلها وخدمتها
  بالذكاء الاصطناعي. أدرج الإفصاحات المطلوبة في مسار مكالماتك الخاص قبل
  تفعيل هذا المسار.
</Warning>

## حمولة الطلب

للمكالمات الهاتفية (`telephony.incoming`):

```json
{
  "type": "telephony.incoming",
  "data": {
    "call_id":     987654321,
    "from_number": "+14155550199",
    "to_number":   "+15551234567"
  }
}
```

| الحقل | النوع | الوصف |
|-------|------|-------------|
| `call_id` | عدد صحيح | معرّف المكالمة — ثابت عبر جميع أحداث هذه المكالمة |
| `from_number` | سلسلة نصية | رقم المتصل بتنسيق E.164 |
| `to_number` | سلسلة نصية | وجهة E.164 (أحد أرقام ThunderPhone الخاصة بك) |

بالنسبة إلى جلسات عنصر واجهة الويب (`web.incoming`)، تحدد `data`
الصفحة المضمّنة بدلًا من أرقام الهاتف:

```json
{
  "type": "web.incoming",
  "data": {
    "call_id": 987654322,
    "origin_domain": "https://example.com",
    "publishable_key_prefix": "pk_live_a1b2"
  }
}
```

| الحقل | النوع | الوصف |
|-------|------|-------------|
| `call_id` | عدد صحيح | معرّف المكالمة |
| `origin_domain` | سلسلة نصية | مصدر الصفحة التي تستضيف الودجة، كما أرسله المتصفح. يمكن لعميل غير المتصفح إرسال أي قيمة، لذا لا تعاملها كدليل على مصدر الطلب |
| `publishable_key_prefix` | سلسلة نصية | الأحرف الأولى من المفتاح القابل للنشر الذي فتح الجلسة |
| `language`, `primary_language` | سلسلة نصية | موجود عند طلب جلسة الودجة تجاوزاً للغة |
| `voice` | سلسلة نصية | موجود عند طلب جلسة الودجة تجاوزاً للصوت |
| `website_context` | سلسلة نصية | موجود عند تمرير الودجة لسياق الصفحة لكل جلسة |

تصل حقول التجاوز (`language` و`voice` و`website_context` وأي
`variables` للمتصفح) فقط عندما يسمح بها المفتاح القابل للنشر في
[تجاوزات المتصفح](/ar/guides/embed-web-widget) الخاصة به. يُرفض طلب الجلسة الذي يتضمن تجاوزاً لا يسمح به المفتاح قبل استدعاء
هذا الخطاف الشبكي.

<Note>
  تسلّم عناصر الواجهة في وضع الويب هوك هذا الطلب إلى `webhook_url`
  الخاص بالمفتاح القابل للنشر عند تعيينه، مع الرجوع إلى عنوان URL
  للويب هوك على مستوى المؤسسة. وفي كلتا الحالتين، يُوقّع الطلب باستخدام
  `secret` الويب هوك الخاص بالمؤسسة.
</Note>

---

## مخطط الاستجابة

أعِد كائن JSON يصف إعدادات الوكيل لهذه المكالمة.
`prompt` و`voice` مطلوبان؛ وكل ما عداهما اختياري.

```json
{
  "prompt":  "You are a helpful booking assistant for Acme Restaurant.",
  "voice":   "john",
  "product": "spark",
  "background_track": null,
  "tools":   []
}
```

| الحقل | النوع | مطلوب | الوصف |
|-------|------|----------|-------------|
| `prompt` | سلسلة نصية | نعم | موجّه النظام الذي يوجّه الوكيل |
| `voice` | سلسلة نصية | نعم | معرّف الصوت من [`GET /v1/voices`](/api-reference/agents#voices)، مثل `john`. يُقبل `voice_name` كاسم بديل. تفشل الأصوات غير المعروفة في التحقق وتُرفض المكالمة |
| `product` | سلسلة نصية | لا | القيمة الافتراضية هي `spark`. القيم المسموح بها: `spark`، `bolt`، `storm-base`، `storm-base-with-ack`، `storm-extra`، `storm-extra-with-ack` |
| `thinking_level` | سلسلة نصية | لا | `minimal` أو `base` (الافتراضي) أو `extra`. يُتجاوز لمنتجات Storm: يفرض `storm-extra*` القيمة `extra`، بينما تفرض قيم `storm-*` الأخرى القيمة `base` |
| `audio_context_mode` | سلسلة نصية | لا | `full` (الافتراضي) أو `reduced` |
| `watchdog_enabled` | منطقي | لا | فعّل الإشراف على هذه المكالمة. القيمة الافتراضية هي `false` |
| `additional_audio_context` | منطقي \| فارغ | لا | أدرج آخر عدة أدوار من صوت المتصل بدلًا من الدور الأحدث فقط، مما يحسّن التصحيحات وجمع البيانات التي تتضمن تهجئة أو أرقامًا كثيرة مع زيادة طفيفة في زمن الاستجابة والتكلفة. تكون مفعّلة افتراضيًا للجلسات الواردة ومعطّلة للمكالمات الهاتفية الصادرة؛ يحتفظ `null` بالقيمة الافتراضية |
| `storm_feedback_mode` | سلسلة نصية | لا | `none` أو `acknowledgement` (الافتراضي) أو `tick` |
| `language` | سلسلة نصية | لا | اختصار لـ `primary_language` |
| `primary_language` | سلسلة نصية | لا | رمز اللغة بعد توحيده (الافتراضي `en`). ترفض الرموز التي يتعذر حلها المكالمة |
| `has_additional_languages` | منطقي | لا | القيمة الافتراضية هي `false` |
| `additional_languages` | مصفوفة من السلاسل النصية | لا | لغات إضافية يمكن للوكيل التبديل إليها |
| `native_voice_switching` | منطقي | لا | القيمة الافتراضية هي `false`. عند انتقال المكالمة إلى لغة أخرى، بدّل إلى صوت أصلي لتلك اللغة (مطابق من حيث الجنس) بدلًا من الاحتفاظ بالصوت المهيأ |
| `language_switching` | سلسلة نصية \| فارغ | لا | `ask_first` (الافتراضي) أو `follow_caller`؛ القيمة `null` مماثلة لـ `ask_first`. يحدد كيفية تعامل وكيل متعدد اللغات مع شخص آخر يتحدث لغة أخرى من لغاته. يبدّل `ask_first` فورًا عندما يطلبون اللغة أو يقولون جملة كاملة بها، ويسأل عما إذا كانوا يريدون المتابعة بها بعد قول شيء قصير، مثل «نعم». يبدّل `follow_caller` إلى أي لغة مهيأة يتحدثون بها، حتى لو كانت كلمة واحدة. ينطبق فقط عند تعيين `additional_languages` |
| `background_track` | سلسلة نصية \| فارغ | لا | معرّف الصوت المحيط أو `null` |
| `acknowledgement_prompt_mode` | سلسلة نصية | لا | `auto` (الافتراضي) أو `manual` (لمنتجات Storm المزودة بالإقرار) |
| `acknowledgement_prompt` | سلسلة نصية | لا | يُستخدم عندما تكون `acknowledgement_prompt_mode="manual"` |
| `silence_interval_seconds` | عدد صحيح \| فارغ | لا | 5–120. ثواني صمت المتصل قبل التحقق |
| `silence_max_checkins` | عدد صحيح \| فارغ | لا | 1–10 |
| `silence_checkins_enabled` | منطقي | لا | القيمة الافتراضية هي `true` |
| `connect_tone_enabled` | منطقي | لا | القيمة الافتراضية هي `false` |
| `pronunciation_dicts` | منطقي \| فارغ | لا | القيمة الافتراضية هي `false`؛ القيمة `null` مماثلة لـ `false`. عندما تكون القيمة `true`، يستخدم نطق Cartesia في المكالمة قاموس النطق الخاص بـ ThunderPhone للغة المكالمة، عند توفره. يعمل مع مكالمات الهاتف والأداة المصغرة. ينطبق فقط على أصوات Cartesia الخاصة بـ ThunderPhone، وليس على الأصوات التي تستخدم مفتاح Cartesia API الخاص بك. لا يُستخدم مع `agent_id`، حيث تُطبّق إعدادات الوكيل المحفوظة |
| `voicemail_action` | سلسلة نصية | لا | `prompt` (الافتراضي) أو `hangup` أو `message` |
| `voicemail_message` | سلسلة نصية | لا | يُستخدم عندما تكون `voicemail_action="message"` |
| `agent_name` | سلسلة نصية | لا | اسم العرض المُبلّغ عنه للوحات المعلومات والأداة المصغرة |
| `org_name` | سلسلة نصية | لا | اسم العرض للمؤسسة لشخصية الوكيل |
| `tools` | مصفوفة | لا | مخططات أدوات الوظائف المضمنة (راجع [أدوات الوظائف](/ar/tools/overview)) |
| `transfer_destinations` | مصفوفة من الكائنات \| فارغ | لا | ما يصل إلى 50 إدخالًا من `{name, number}` يمكن لهذه المكالمة التحويل إليها، ويجري التحقق منها مثل [أرقام التحويل](/api-reference/agents#transfer-numbers) الخاصة بالوكيل. يحوّل الوكيل بالاسم وإلى هذه الإدخالات فقط؛ تعني `[]` عدم وجود تحويلات. احذفها أو أرسل `null` للسماح للوكيل بالتحويل إلى رقم يختاره |
| `timezone` | سلسلة نصية | لا | منطقة زمنية من IANA لهذه المكالمة، مثل `America/Chicago`. يذكر الوكيل التاريخ والوقت وفقًا لها بدلًا من منطقته الزمنية الخاصة. يُسمح بها أيضًا إلى جانب `agent_id`. تُتجاهل القيم التي ليست مناطق زمنية من IANA. راجع [تعيين المنطقة الزمنية لكل مكالمة](/ar/guides/dynamic-call-config) |
| `call_id` | عدد صحيح | لا | إعادة اختيارية لمعرّف المكالمة في الطلب؛ تُتجاهل |

<Note>
  تُتجاهل المفاتيح غير المعروفة في المستوى الأعلى **بصمت** — لا يؤدي
  اسم الحقل المكتوب بخطأ إملائي إلى رفض الإعداد، بل لا يُطبّق فقط. لا يُقبل ترتيب النطق
  و`max_hold_seconds` هنا؛ إذ لا يمكن إعدادهما إلا في
  [الوكيل](/api-reference/agents) نفسه.
</Note>

بما أن `prompt` و`voice` مطلوبان، فإن إرجاع `{}` أو أي استجابة لا تجتاز التحقق يرفض المكالمة: تُنهى المكالمة الهاتفية كما هو موضح في [المهلات وإعادات المحاولة](#timeouts-and-retries)، ويفشل طلب جلسة الودجة برمز `422`. لا يوجد بديل لوكيل ثابت في هذا المسار (فالرقم أو المفتاح في وضع webhook لا يكون له وكيل مُعيّن).

---

## حد حجم الاستجابة

<Warning>
  تقتصر استجابات التهيئة على **5 MiB**. إذا أعاد معالج
  استجابة أكبر، بما في ذلك مع حالة `2xx`،
  يُبلغ ThunderPhone بأن الاستجابة تجاوزت الحد ويرفض
  المكالمة أو جلسة الودجت. اجعل الاستجابة مقتصرة على الحقول
  اللازمة لإعداد المكالمة؛ واستضف البيانات الكبيرة خلف أدوات الدوال أو
  خدمة أخرى بدلاً من تضمينها في التهيئة.
</Warning>

---

## مثال على معالج

<CodeGroup>
```python Python (FastAPI)
import hashlib
import hmac
import json
import os

from fastapi import FastAPI, HTTPException, Request

app = FastAPI()
WEBHOOK_SECRET = os.environ["THUNDERPHONE_WEBHOOK_SECRET"]

def verify(body: bytes, signature: str) -> bool:
    expected = hmac.new(WEBHOOK_SECRET.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature or "")

@app.post("/thunderphone-webhook")
async def webhook(request: Request):
    body = await request.body()
    if not verify(body, request.headers.get("X-ThunderPhone-Signature", "")):
        raise HTTPException(status_code=401)

    event = json.loads(body)
    if event["type"] == "telephony.incoming":
        caller = event["data"]["from_number"]
        prompt = (
            "Greet the caller as a San Francisco local…"
            if caller.startswith("+1415")
            else "You are a friendly customer support agent…"
        )
        return {
            "prompt": prompt,
            "voice": "john",
            "product": "spark",
        }
    if event["type"] == "web.incoming":
        return {
            "prompt": "You are the website's helpful voice assistant…",
            "voice": "john",
            "product": "spark",
        }
    return {}
```

```javascript Node.js (Express)
import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.THUNDERPHONE_WEBHOOK_SECRET;

function verify(body, signature) {
  const expected = crypto
    .createHmac("sha256", SECRET)
    .update(body)
    .digest("hex");
  return signature &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

app.post(
  "/thunderphone-webhook",
  express.raw({ type: "application/json" }),
  (req, res) => {
    if (!verify(req.body, req.header("X-ThunderPhone-Signature"))) {
      return res.sendStatus(401);
    }
    const event = JSON.parse(req.body.toString("utf8"));

    if (event.type === "telephony.incoming" || event.type === "web.incoming") {
      const caller = event.data.from_number || "web";
      const prompt = caller.startsWith("+1415")
        ? "Greet the caller as a San Francisco local…"
        : "You are a friendly customer support agent…";
      return res.json({
        prompt,
        voice: "john",
        product: "spark",
      });
    }
    res.json({});
  },
);
```
</CodeGroup>

---

## استجابة تتضمن أدوات دوال

أرفق أدوات كي يتمكن الذكاء الاصطناعي من استدعاء واجهات برمجة التطبيقات الخاصة بك أثناء المحادثة:

```json
{
  "prompt":  "You are a booking assistant. Use the available tools to help customers schedule appointments.",
  "voice":   "john",
  "product": "spark",
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "search_appointments",
        "description": "Find available appointment slots",
        "parameters": {
          "type": "object",
          "properties": {
            "date": { "type": "string", "description": "YYYY-MM-DD" },
            "service": { "type": "string" }
          },
          "required": ["date"]
        }
      },
      "endpoint": {
        "url": "https://api.example.com/appointments/search",
        "method": "POST",
        "headers": {
          "X-Api-Key": "your-key"
        }
      }
    }
  ]
}
```

<Tip>
  تُوقَّع طلبات نقاط نهاية الأدوات باستخدام **سر خطاف الويب نفسه الخاص بالمؤسسة**
  الذي وقّع هذا التبادل. راجع
  [أدوات الدوال](/ar/tools/overview) للاطلاع على البنية الدقيقة وتنسيق
  الطلب الموقّع.
</Tip>

---

## دليل سريع لمستويات المنتجات

| المنتج | زمن الاستجابة | الاستدلال | الإقرار |
|---------|---------|-----------|-----------------|
| `spark` | الأدنى | أساسي | — |
| `bolt` | منخفض | محسّن | — |
| `storm-base` | متوسط | قوي | — |
| `storm-base-with-ack` | متوسط | قوي | نص تلقائي أثناء التفكير |
| `storm-extra` | أعلى | عميق | — |
| `storm-extra-with-ack` | أعلى | عميق | نص تلقائي أثناء التفكير |

---

## ذو صلة

<CardGroup cols={2}>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/ar/webhooks/call-complete">
    حدث نهاية المكالمة غير المعطِّل.
  </Card>
  <Card title="أدوات الدوال" icon="screwdriver-wrench" href="/ar/tools/overview">
    مخطط JSON الكامل لـ `tools[]` وعقد نقطة النهاية الموقّع.
  </Card>
  <Card title="نقاط نهاية Webhook" icon="bolt" href="/ar/webhooks/endpoints">
    اشترك بعدة عناوين URL في `telephony.incoming` / `web.incoming`.
  </Card>
  <Card title="إعداد المكالمات الديناميكي" icon="wand-magic-sparkles" href="/ar/guides/dynamic-call-config">
    أنماط للموجّهات والأدوات واختبارات A/B لكل متصل.
  </Card>
</CardGroup>
