> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thunderphone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# أدوات الدوال

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

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

## آلية العمل

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

<Note>
  أدوات الدوال هي المسار الذي يتيح لك استخدام واجهة API الخاصة بك. يوفّر ThunderPhone أيضًا
  أدوات مُدارة من المنصة لا تحتاج إلى نقطة نهاية:
  [اتصالات التطبيقات](/ar/guides/connect-apps) (HubSpot، Salesforce، Slack،
  Google Calendar، Google Sheets، Cal.com)،
  [اتصالات API](/ar/guides/api-connections)، و
  [خوادم MCP](/ar/guides/mcp-servers).
</Note>

***

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

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

```json theme={null}
{
  "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"
    }
  }
}
```

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

| الحقل         | النوع      | مطلوب | الوصف                                       |
| ------------- | ---------- | ----- | ------------------------------------------- |
| `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` | `Content-Type` + `X-ThunderPhone-Signature`                                                          |
| مفتاح التوقيع | سر خطاف الويب الخاص بالمؤسسة                                                        | سر خطاف الويب الخاص بالمؤسسة                                                                         |

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

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

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

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

```http theme={null}
POST /appointments/search HTTP/1.1
Host: api.example.com
Content-Type: application/json
X-ThunderPhone-Signature: abc123...
X-ThunderPhone-Call-ID: 987654321
X-Api-Key: your-api-key
```

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

* `X-ThunderPhone-Signature` — ‏HMAC-SHA256 لبايتات نص الطلب
  الدقيقة، باستخدام **سر webhook الخاص بمؤسستك** كمفتاح
* `X-ThunderPhone-Call-ID` — معرّف المكالمة الحالية

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

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

### نص الطلب

بالنسبة إلى `POST` / `PUT` / `PATCH`، لا يحتوي النص إلا على
وسائط الأداة **فقط** (من دون غلاف)، ويُسلسَل بصيغة معيارية (مفاتيح مرتبة،
وفواصل مضغوطة):

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

بالنسبة إلى `GET` / `DELETE`، تُرسل الوسائط كـ **معلمات استعلام**
ويكون النص فارغًا — ويُحتسب التوقيع حينها على سلسلة البايتات الفارغة.
راجع
[التحقق من تواقيع webhook](/ar/guides/verify-webhook-signatures).

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

أعد استجابة JSON تحتوي على نتيجة الأداة:

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

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

## التوزيع في وضع Webhook

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

```json theme={null}
{
  "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 — وفق عقد الاستجابة نفسه
لاستدعاءات نقاط النهاية المباشرة. يُوقَّع الطلب باستخدام سر webhook الخاص بالمؤسسة
على النص الخام، مثل كل webhook آخر.

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

***

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

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

* HMAC-SHA256 على وحدات البايت الدقيقة لنص الطلب (JSON القياسي — مفاتيح مرتبة، دون مسافات بيضاء إضافية)
* باستخدام سر خطاف الويب الخاص بمؤسستك كمفتاح
* توقّع أدوات `GET` / `DELETE` سلسلة البايت الفارغة

<CodeGroup>
  ```python Python theme={null}
  import hmac
  import hashlib

  def verify_tool_call(body: bytes, signature: str, secret: str) -> bool:
      expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
      return hmac.compare_digest(expected, signature)

  @app.post("/appointments/search")
  async def search_appointments(request: Request):
      body = await request.body()
      signature = request.headers.get("X-ThunderPhone-Signature", "")

      if not verify_tool_call(body, signature, WEBHOOK_SECRET):
          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 theme={null}
  app.post('/appointments/search', express.raw({type: 'application/json'}), (req, res) => {
    const signature = req.headers['x-thunderphone-signature'] || '';
    const expected = crypto
      .createHmac('sha256', WEBHOOK_SECRET)
      .update(req.body)
      .digest('hex');

    if (!signature ||
        signature.length !== expected.length ||
        !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
      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>

تتوفر الوصفات الكاملة — بما في ذلك حالة النص الفارغ والتنبيه المتعلق بعدم وجود سر — في [التحقق من توقيعات خطافات الويب](/ar/guides/verify-webhook-signatures).

***

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

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

```json theme={null}
{
  "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="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="تحقق من تواقيع webhook" icon="shield-check" href="/ar/guides/verify-webhook-signatures">
    مساعد تحقق واحد لطلبات webhook واستدعاءات الأدوات.
  </Card>
</CardGroup>
