---
title: "أدوات الدوال"
description: "زوّد وكلاء الذكاء الاصطناعي لديك بأدوات دوال تستدعي واجهات برمجة تطبيقات خارجية أثناء المحادثة — لجلب بيانات العملاء، وحجز المواعيد، وتحديث السجلات — باستخدام معلمات مكتوبة النوع."
---

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

## آلية العمل

1. عرّف الأدوات باستخدام مخطط (الوسيطات التي تقبلها الأداة)
2. وفّر إعداد `endpoint` (المكان الذي يستدعي فيه ThunderPhone واجهة برمجة التطبيقات لديك) — أو اتركه فارغًا لتلقي استدعاءات الأدوات عبر ويبهوك مؤسستك
3. أثناء المكالمة، يحدد الذكاء الاصطناعي وقت استخدام الأداة بناءً على المحادثة
4. يستدعي ThunderPhone نقطة النهاية لديك باستخدام وسيطات الأداة
5. تُعاد استجابة واجهة برمجة التطبيقات لديك إلى الذكاء الاصطناعي لمتابعة المحادثة

| الإمكانية | مكان التشغيل | الإعداد |
| --- | --- | --- |
| [الأدوات المضمنة](/ar/guides/built-in-tools) | ThunderPhone | تعليمات الموجّه؛ تحتاج بعض الأدوات أيضًا إلى إعداد وكيل |
| [اتصالات التطبيقات](/ar/guides/connect-apps) | ThunderPhone وموفر الخدمة المتصل | اربط الحساب وأرفق الإجراءات المعتمدة |
| [اتصالات API](/ar/guides/api-connections) وأدوات الدوال | واجهة HTTP API لديك | عرّف نقطة النهاية والمخطط، أو تلقَّ استدعاءات الدوال عبر ويبهوك |
| [خوادم MCP](/ar/guides/mcp-servers) | خادم MCP بعيد | أضف الخادم، واكتشف أدواته، وأرفقه بالوكيل |

---

## مخطط الأداة

تتبع كل أداة هذه البنية:

```json
{
  "type": "function",
  "function": {
    "name": "search_appointments",
    "description": "Find available appointment slots for a given date",
    "parameters": {
      "type": "object",
      "properties": {
        "date": {
          "type": "string",
          "description": "Date in YYYY-MM-DD format"
        },
        "service": {
          "type": "string",
          "description": "Type of service (e.g., 'consultation', 'follow-up')"
        }
      },
      "required": ["date"]
    }
  },
  "endpoint": {
    "url": "https://api.example.com/appointments/search",
    "method": "POST",
    "headers": {
      "X-Api-Key": "your-api-key"
    }
  },
  "timeout": 120
}
```

### إعداد الأداة

| الحقل | النوع | مطلوب | الوصف |
|-------|------|----------|-------------|
| `timeout` | رقم | لا | الحد الأقصى لوقت التنفيذ بالثواني (الافتراضي: `20`، الحد الأقصى: `180`) |

### تعريف الدالة

| الحقل | النوع | مطلوب | الوصف |
|-------|------|----------|-------------|
| `name` | سلسلة نصية | نعم | معرّف فريد للأداة |
| `description` | سلسلة نصية | نعم | يشرح للذكاء الاصطناعي متى يستخدم هذه الأداة |
| `parameters` | كائن | نعم | مخطط JSON لوسيطات الأداة |

### إعداد نقطة النهاية

| الحقل | النوع | مطلوب | الوصف |
|-------|------|----------|-------------|
| `url` | سلسلة نصية | نعم | عنوان URL لنقطة نهاية API لديك |
| `method` | سلسلة نصية | لا | طريقة HTTP (الافتراضية: `POST`) |
| `headers` | كائن | لا | رؤوس مخصصة لتضمينها |

<Note>
  لا يُرسل إعداد `endpoint` إلى نموذج الذكاء الاصطناعي **مطلقًا**—يستخدمه ThunderPhone فقط لتنفيذ استدعاء الأداة.
</Note>

---

## مسارا الاستدعاء

يعتمد الطلب الذي يتلقاه خادمك على ما إذا كانت الأداة تحتوي على
`endpoint`:

| | الأداة **مع** `endpoint` | الأداة **من دون** `endpoint` |
|---|---|---|
| وجهة الطلب | مباشرةً إلى `endpoint.url` | [عنوان URL القديم لخطاف الويب](/api-reference/organizations#legacy-single-url-webhook) الخاص بمؤسستك |
| النص | تنسيق الطلب المحدد (الوسيطات المجردة افتراضيًا) | غلاف `telephony.tool` / `web.tool` |
| الرؤوس | `endpoint.headers` الخاص بك + `X-ThunderPhone-Call-ID` + `X-ThunderPhone-Signature-V2` + `X-ThunderPhone-Signature` | `Content-Type` + `X-ThunderPhone-Signature-V2` + `X-ThunderPhone-Signature` |
| مفتاح التوقيع | السرّ الخاص بخطاف الويب للمؤسسة | السرّ الخاص بخطاف الويب للمؤسسة |

كلا المسارين **حاجبان** — ينتظر الذكاء الاصطناعي النتيجة في منتصف
الجملة. المهلة الافتراضية هي **20 ثانية**؛ اضبط `timeout` في المستوى الأعلى
للأداة للسماح بمدة تنفيذ أطول، حتى الحد الأقصى للمنصة البالغ **180 ثانية**.
أبقِ المعالجات سريعة. يمكن الجمع بين المسارين:
في مكالمة تكون لمؤسستها عنوان URL للويبهوك، تُستدعى الأدوات التي تحتوي على `endpoint`
مباشرةً، بينما تعود الأدوات الأخرى إلى الويبهوك.

## استدعاءات نقطة النهاية المباشرة

عندما يستدعي الذكاء الاصطناعي أداة لها `endpoint`، يرسل ThunderPhone
طلبًا إلى عنوان URL الخاص بك:

### رؤوس الطلب

```http
POST /appointments/search HTTP/1.1
Host: api.example.com
Content-Type: application/json
X-ThunderPhone-Signature-V2: t=1767225600,v1=5f2c...
X-ThunderPhone-Signature: abc123...
X-ThunderPhone-Call-ID: 987654321
X-Api-Key: your-api-key
```

تُضمَّن الرؤوس المخصصة من `endpoint.headers` دائمًا
كما هي، بالإضافة إلى هذه الرؤوس ذات نطاق ThunderPhone:

- `X-ThunderPhone-Signature-V2` — HMAC-SHA256 مؤرخ زمنيًا للطريقة
  والمسار والاستعلام والنص، باستخدام **سر webhook الخاص بمؤسستك**.
  تحقّق من هذا الرأس وارفض الطلبات التي يزيد عمرها على 5 دقائق؛ راجع
  [التحقق من تواقيع webhook](/ar/guides/verify-webhook-signatures)
- `X-ThunderPhone-Signature` — HMAC-SHA256 قديم للبايتات الدقيقة
  لنص الطلب، بالمفتاح نفسه، ولا يزال يُرسل لعمليات التحقق الحالية
- `X-ThunderPhone-Call-ID` — معرّف المكالمة الحالية

يُضبط `Content-Type: application/json` ما لم تتجاوزه `endpoint.headers`
الخاصة بك — تكون الأولوية لـ `Content-Type` المخصص.

<Warning>
  يستخدم التوقيع سر خطاف الويب على مستوى المؤسسة من
  [`GET /v1/webhook`](/api-reference/organizations#legacy-single-url-webhook).
  إذا لم تكن مؤسستك قد هيأت خطاف الويب القديم من قبل، فلن يوجد
  سر، وستحمل استدعاءات الأدوات `X-ThunderPhone-Call-ID` **فقط** —
  وسيؤدي معالج يفشل فشلًا قاطعًا عند غياب توقيع إلى رفضها.
  إما أن تهيئ خطاف الويب القديم للحصول على سر، أو تضع سرك المشترك
  الخاص في `endpoint.headers`.
</Warning>

### تنسيق الطلب

يحتوي كل اتصال بواجهة برمجة التطبيقات على إعداد `request_format`. اختر `vapi` أو
`retell` عندما يجب أن تستمر أداة مستوردة في استدعاء نقطة نهاية مُنشأة لتلك
المنصة. تستخدم الاتصالات الجديدة والحالية `standard` افتراضيًا.

بالنسبة إلى `POST` / `PUT` / `PATCH`، يُسلسل ThunderPhone الغلاف المحدد
بصيغة معيارية (مفاتيح مرتبة وفواصل مضغوطة). يغطي كلا التوقيعين هذه البايتات
بالضبط.

#### قياسي

يرسل `standard` وسيطات الأداة فقط، دون غلاف. هذا هو الإعداد
الافتراضي ويحافظ على نص طلب ThunderPhone الأصلي بايتًا ببايت:

```json
{"date":"2025-01-02","service":"consultation"}
```

#### Vapi

يرسل `vapi` [رسالة الخادم `tool-calls` الخاصة بـ Vapi](https://docs.vapi.ai/tools/custom-tools)
بالصيغة التي توثقها Vapi. يكون `call.id` هو معرّف مكالمة ThunderPhone. ويكون
معرّف استدعاء الأداة `id` فريدًا لهذا الاستدعاء، ويُعاد استخدامه لمطابقة
نتيجة نقطة النهاية. يظهر الاستدعاء في كلٍّ من `toolCallList` و
`toolWithToolCallList`، مع `function.arguments` ككائن JSON:

```json
{
  "message": {
    "type": "tool-calls",
    "timestamp": 1725000000123,
    "call": { "id": "987654321" },
    "toolCallList": [
      {
        "id": "call_00112233445566778899aabbccddeeff",
        "type": "function",
        "function": {
          "name": "search_appointments",
          "arguments": { "date": "2025-01-02", "service": "consultation" }
        }
      }
    ],
    "toolWithToolCallList": [
      {
        "type": "function",
        "function": { "name": "search_appointments" },
        "toolCall": {
          "id": "call_00112233445566778899aabbccddeeff",
          "type": "function",
          "function": {
            "name": "search_appointments",
            "arguments": { "date": "2025-01-02", "service": "consultation" }
          }
        }
      }
    ]
  }
}
```

لا تُرسل الحقول الخاصة بـ Vapi فقط، مثل `assistant` و`artifact` وكائن `call`
الكامل.

أعِد غلاف استجابة Vapi مع معرّف استدعاء الأداة المطابق:

```json
{
  "results": [
    {
      "toolCallId": "call_00112233445566778899aabbccddeeff",
      "result": "{\"available_slots\":[\"9:00 AM\",\"2:00 PM\"]}"
    }
  ]
}
```

يمنح ThunderPhone الذكاء الاصطناعي سلسلة `result` غير المغلفة. كما يقبل قيمة
JSON للتوافق مع نقاط النهاية التي تُعيد قيمة بالفعل. يُعاد `error` بدلًا من
`result` إلى الذكاء الاصطناعي كخطأ في الأداة. إذا أعادت نقطة النهاية غلاف Vapi
غير صالح أو غير مطابق، يسجل ThunderPhone تحذيرًا ويعود إلى تحليل الاستجابة
القياسي بدلًا من إخفاق المكالمة.

#### Retell

يرسل `retell` الطلب الموثق [لدالة مخصصة في Retell](https://docs.retellai.com/build/single-multi-prompt/custom-function):

```json
{
  "name": "search_appointments",
  "call": { "call_id": "987654321" },
  "args": { "date": "2025-01-02", "service": "consultation" }
}
```

يتضمن كائن `call` الحقل `call_id` فقط. لا يتضمن ThunderPhone الحقول الخاصة
بـ Retell التي لا يمكنه توفيرها بدقة عند الإرسال، مثل `agent_id` أو
`transcript` أو `transcript_object` أو `metadata` أو المتغيرات الديناميكية.
يقبل Retell أي نص استجابة؛ ويمرره ThunderPhone باستخدام معالجة الاستجابة
القياسية.

بالنسبة إلى `GET` / `DELETE`، تُرسل الوسيطات باعتبارها **معلمات استعلام**
ويكون النص فارغًا بغض النظر عن `request_format`. يغطي توقيع V2 سلسلة
الاستعلام كما أُرسلت؛ بينما يُحتسب التوقيع القديم على سلسلة البايتات الفارغة.
راجع [التحقق من توقيعات خطاف الويب](/ar/guides/verify-webhook-signatures).

### الاستجابة

أعِد استجابة JSON بنتيجة الأداة:

```json
{
  "available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
  "timezone": "America/Los_Angeles"
}
```

تُنسق الاستجابة وتُقدَّم إلى الذكاء الاصطناعي لمتابعة
المحادثة. تُغلَّف الاستجابات غير التابعة لـ JSON بصيغة `{"data": "<text>"}`؛
وتُبلَّغ مهلات الانتظار وإخفاقات الاتصال إلى الذكاء الاصطناعي كأخطاء، لكي
يتمكن الوكيل من الاعتذار والمتابعة بدلًا من التوقف.

## توزيع وضع خطاف الويب

تُوزَّع الأدوات **التي لا تحتوي على** `endpoint` إلى عنوان URL لخطاف
الويب القديم لمؤسستك كطلب موقّع من `telephony.tool` (مكالمات هاتفية) أو
`web.tool` (مكالمات ويب). بخلاف [إشعارات التدقيق](/ar/webhooks/events)
التي تُسلَّم إلى نقاط نهاية خطاف الويب بعد التنفيذ، فإن هذا الطلب **هو**
التنفيذ — استجابة HTTP الخاصة بك هي نتيجة الأداة.

```json
{
  "type": "telephony.tool",
  "data": {
    "call_id": 987654321,
    "tool_name": "search_appointments",
    "arguments": { "date": "2026-04-21" },
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  }
}
```

يحمل `web.tool` ‏`origin_domain` بدلًا من `from_number` /
`to_number`. استجب بنتيجة الأداة بتنسيق JSON — وفق عقد الاستجابة نفسه
المستخدم في استدعاءات نقاط النهاية المباشرة. يُوقَّع الطلب بسر خطاف الويب الخاص بالمؤسسة، مع رأسي التوقيع كليهما، مثل كل خطاف ويب آخر.

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

---

## التحقق من التوقيع

تُوقَّع استدعاءات الأدوات المباشرة بالطريقة نفسها التي تُوقَّع بها خطافات الويب، باستخدام سر خطاف الويب الخاص بمؤسستك:

- يوقّع `X-ThunderPhone-Signature-V2` الطابع الزمني والطريقة والمسار
  والاستعلام كما أُرسلت، وبايتات النص الأساسية الدقيقة. ارفض الطلبات التي يكون
  طابعها الزمني متقدماً أو متأخراً بأكثر من 5 دقائق عن ساعتك.
- يوقّع `X-ThunderPhone-Signature` (القديم) بايتات النص الأساسية فقط،
  وسلسلة البايتات الفارغة لِـ `GET` / `DELETE`. ولا يزال يُرسل دون تغيير.

تتحقق مساعدات SDK من رأس V2، بما في ذلك نافذة الـ 5 دقائق:

<CodeGroup>
```python Python
import json

from fastapi import FastAPI, HTTPException, Request
from thunderphone import verify_signature

app = FastAPI()

@app.post("/appointments/search")
async def search_appointments(request: Request):
    body = await request.body()
    query = request.scope.get("query_string", b"").decode("latin-1")
    path = request.url.path + (f"?{query}" if query else "")

    if not verify_signature(
        request.headers.get("X-ThunderPhone-Signature-V2"),
        secret=WEBHOOK_SECRET,
        method=request.method,
        path=path,
        body=body,
    ):
        raise HTTPException(status_code=401)

    data = json.loads(body)
    date = data["date"]

    # Look up availability
    slots = await get_available_slots(date)

    return {"available_slots": slots}
```

```javascript Node.js
import express from "express";
import { verifySignature } from "@thunderphone/sdk";

app.post('/appointments/search', express.raw({type: 'application/json'}), (req, res) => {
  const ok = verifySignature({
    header: req.header('X-ThunderPhone-Signature-V2'),
    secret: WEBHOOK_SECRET,
    method: req.method,
    path: req.originalUrl,
    body: req.body,
  });
  if (!ok) return res.status(401).send('Invalid signature');

  const { date, service } = JSON.parse(req.body);

  // Look up availability
  const slots = getAvailableSlots(date, service);

  res.json({ available_slots: slots });
});
```
</CodeGroup>

تتوفر الوصفات الكاملة — السلسلة الموقّعة، ومثال عملي، وتعليمة برمجية بدون
SDK، وحالة `GET` / `DELETE`، والتنبيه المتعلق بعدم وجود سر — في [التحقق من توقيعات خطافات الويب](/ar/guides/verify-webhook-signatures).

---

## مثال: تدفق حجز كامل

إليك مجموعة من الأدوات لنظام حجز مواعيد متكامل:

```json
{
  "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": "key" }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "book_appointment",
        "description": "Book an appointment at a specific time",
        "parameters": {
          "type": "object",
          "properties": {
            "date": { "type": "string", "description": "YYYY-MM-DD" },
            "time": { "type": "string", "description": "HH:MM format" },
            "customer_name": { "type": "string" },
            "customer_phone": { "type": "string" }
          },
          "required": ["date", "time", "customer_name"]
        }
      },
      "endpoint": {
        "url": "https://api.example.com/appointments/book",
        "method": "POST",
        "headers": { "X-Api-Key": "key" }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "cancel_appointment",
        "description": "Cancel an existing appointment",
        "parameters": {
          "type": "object",
          "properties": {
            "confirmation_number": { "type": "string" }
          },
          "required": ["confirmation_number"]
        }
      },
      "endpoint": {
        "url": "https://api.example.com/appointments/cancel",
        "method": "POST",
        "headers": { "X-Api-Key": "key" }
      }
    }
  ]
}
```

---

## أفضل الممارسات

<AccordionGroup>
  <Accordion title="اكتب أوصافًا واضحة">
    يساعد حقل `description` الذكاء الاصطناعي على فهم **متى** يستخدم الأداة. حدّد بوضوح ما الذي تفعله ومتى يكون استخدامها مناسبًا.
  </Accordion>

  <Accordion title="عالج الأخطاء بسلاسة">
    أرجع رسائل خطأ يمكن للذكاء الاصطناعي فهمها: `{"error": "No slots available for that date"}` بدلًا من أخطاء 500 العامة.
  </Accordion>

  <Accordion title="حافظ على إيجاز الاستجابات">
    أرجع فقط ما يحتاجه الذكاء الاصطناعي لمتابعة المحادثة. تؤدي الحمولات الكبيرة إلى إبطاء أوقات الاستجابة.
  </Accordion>

  <Accordion title="استخدم الحقول المطلوبة بحكمة">
    علّم الحقول بأنها `required` فقط عند الضرورة الفعلية. سيطلب الذكاء الاصطناعي من المستخدم المعلومات المطلوبة قبل استدعاء الأداة.
  </Accordion>
</AccordionGroup>

---

## ذات صلة

<CardGroup cols={2}>
  <Card title="الأدوات المضمّنة" icon="wrench" href="/ar/guides/built-in-tools">
    وجّه إجراءات المكالمات التي تديرها المنصة دون تحديد نقطة نهاية.
  </Card>
  <Card title="اتصالات التطبيقات" icon="plug" href="/ar/guides/connect-apps">
    أدوات تديرها المنصة لـ HubSpot وSalesforce وSlack وGoogle
    Calendar وGoogle Sheets وCal.com — لا حاجة إلى نقطة نهاية.
  </Card>
  <Card title="خوادم MCP" icon="server" href="/ar/guides/mcp-servers">
    أرفق خادم MCP ودع الوكيل يستدعي أدواته.
  </Card>
  <Card title="اتصالات API" icon="code" href="/ar/guides/api-connections">
    عمليات تكامل REST قابلة لإعادة الاستخدام يمكنك إرفاقها بالوكلاء.
  </Card>
  <Card title="التحقق من توقيعات خطاف الويب" icon="shield-check" href="/ar/guides/verify-webhook-signatures">
    مساعد تحقق واحد لخطافات الويب واستدعاءات الأدوات.
  </Card>
</CardGroup>
