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

# واجهة جافاسكربت للودجت

> الأوامر والأحداث، وكيف تثبت أن الزائر المسجّل هو فعلًا من تقول صفحتك إنه هو.

كل ما يعرضه الودجت يمرّ عبر دالة واحدة:

```js theme={null}
Linkia('open');
Linkia('identify', { userId: 'user_42', userHash: '…' });
Linkia('on', 'message', (message) => console.log(message.text));
```

تصبح موجودة بمجرد تشغيل طابور الأوامر، فيمكنك مناداتها قبل تحميل الودجت — راجع
[مناداته قبل تحميله](/ar/widget#calling-before-load). تُعاد المناداة بالترتيب عند وصوله، مع
تطبيق `init` أولًا مهما كان موضعه في الطابور.

## الأوامر

| الأمر                                    | ماذا يفعل                                                   |
| ---------------------------------------- | ----------------------------------------------------------- |
| `Linkia('open')`                         | يفتح النافذة، ويحمّل واجهة المحادثة عند أول استخدام.        |
| `Linkia('close')`                        | يغلقها.                                                     |
| `Linkia('toggle')`                       | يفتح أو يغلق.                                               |
| `Linkia('hide')` / `Linkia('show')`      | يخفي الودجت كله بما فيه الزر، أو يعيده.                     |
| `Linkia('init', options)`                | تجاوزات خاصة بالصفحة، ولا أثر لها بعد الإقلاع.              |
| `Linkia('boot')`                         | يُقلع فورًا بدل انتظار خلوّ المتصفح.                        |
| `Linkia('identify', claim)`              | يخبرنا بهوية الزائر — انظر [أدناه](#identity-verification). |
| `Linkia('logout')`                       | ينهي الجلسة ويبدأ جلسة مجهولة جديدة.                        |
| `Linkia('trackEvent', name, properties)` | يُطلق حدثًا تستطيع الأتمتة التصرّف بناءً عليه.              |
| `Linkia('setLocale', 'ar')`              | يغيّر لغة الودجت واتجاهه معها.                              |
| `Linkia('on', event, handler)`           | يشترك في حدث.                                               |
| `Linkia('off', event, handler)`          | يلغي اشتراك نفس الدالة.                                     |
| `Linkia('destroy')`                      | يزيل الودجت من الصفحة تمامًا.                               |

لا تُعيد الأوامر قيمة — فالمناداة المؤجَّلة لا شيء لديها لتعيده بعد. اقرأ الحالة عبر الأحداث.

## الأحداث

```js theme={null}
Linkia('on', 'unread', ({ count }) => {
  document.title = count ? `(${count}) Acme` : 'Acme';
});
```

| الحدث            | الحمولة                 | متى يقع                                          |
| ---------------- | ----------------------- | ------------------------------------------------ |
| `ready`          | `{ visitor }`           | أقلع الودجت وعرف هوية هذا المتصفح.               |
| `open` / `close` | —                       | فُتحت النافذة أو أُغلقت بأي طريقة.               |
| `unread`         | `{ count }`             | تغيّر عدد غير المقروء، بما في ذلك عودته إلى صفر. |
| `message`        | الرسالة                 | وصل رد من موظف أو وكيل ذكاء اصطناعي أو أتمتة.    |
| `identified`     | `{ visitor, verified }` | قُبلت مناداة `identify()`. والمهم هو `verified`. |
| `logout`         | —                       | أُنهيت الجلسة.                                   |

يقع `ready` مرة واحدة في كل تحميل للصفحة. اشترك قبل الإقلاع — من طابور الأوامر — وإلا فقد
تشترك بعد وقوعه.

<h2 id="identity-verification">
  التحقق من الهوية
</h2>

إن كان زوارك يسجّلون الدخول، فأخبرنا بهويتهم: عندها ترتبط محادثاتهم بذلك العميل، ويتبعهم سجلّهم
من الحاسوب إلى الهاتف.

افعل ذلك بتوقيع. فبدونه تكون `identify()` مجرد ادّعاء من متصفح، ويستطيع أي شخص يفتح أدوات
المطور أن يدّعي هوية غيره.

<Steps>
  <Step title="احصل على المفتاح السري">
    **الإعدادات ← القنوات ← محادثة الموقع ← الأمان.** يظهر مرة عند الإنشاء، ومرة أخرى مع كل تدوير،
    ويبدأ بـ `wc_sec_`.

    <Warning>
      هذا مفتاح خادم. إن وصل إلى حزمة الواجهة الأمامية فلن يثبت التحقق شيئًا، لأن الزائر يستطيع حساب
      التوقيع بنفسه. ضعه حيث تضع مفاتيح API لديك.
    </Warning>
  </Step>

  <Step title="وقّع معرّف المستخدم في خادمك">
    `userHash` هو HMAC-SHA256 لمعرّف المستخدم — نفس النص الذي تمرّره في `userId` — بمفتاح السر،
    مُرمَّزًا ست عشريًا.

    <CodeGroup>
      ```javascript Node.js theme={null}
      import crypto from 'node:crypto';

      export function linkiaUserHash(userId) {
        return crypto
          .createHmac('sha256', process.env.LINKIA_WEBCHAT_SECRET)
          .update(String(userId))
          .digest('hex');
      }
      ```

      ```python Python theme={null}
      import hashlib
      import hmac
      import os

      def linkia_user_hash(user_id: str) -> str:
          return hmac.new(
              os.environ["LINKIA_WEBCHAT_SECRET"].encode(),
              str(user_id).encode(),
              hashlib.sha256,
          ).hexdigest()
      ```

      ```php PHP theme={null}
      function linkia_user_hash(string $userId): string {
          return hash_hmac('sha256', $userId, getenv('LINKIA_WEBCHAT_SECRET'));
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="مرّره إلى الودجت">
    اطبع التوقيع في الصفحة للمستخدم المسجّل، وعرّف مرة واحدة بعد الإقلاع:

    ```html theme={null}
    <script>
      Linkia('identify', {
        userId: 'user_42',
        userHash: '5f3a9c…',          // محسوب في الخادم كما سبق
        name: 'نادية فاروق',
        email: 'nadia@acme.com',
        attributes: { plan: 'pro', seats: 12 },
      });
    </script>
    ```
  </Step>

  <Step title="اشترطه">
    بعد أن يبدأ موقعك بالتوقيع، فعّل **اشتراط توقيع صحيح** من تبويب **الأمان**. وقبل ذلك تُقبل
    الادعاءات غير الموقّعة لكنها تُخزَّن كغير موثّقة: سياق مفيد للموظف، ولا يُبنى عليه أي تعريف.
  </Step>
</Steps>

### ما الذي يغيّره «موثّق»

|                               | ادّعاء غير موقّع | ادّعاء موثّق |
| ----------------------------- | ---------------- | ------------ |
| ظهور الاسم والبريد للموظف     | نعم              | نعم          |
| الارتباط بمعرّف `userId` لديك | لا               | نعم          |
| لمّ شمله بسجلّه على جهاز جديد | **لا**           | نعم          |
| القبول عند اشتراط التحقق      | لا — `403`       | نعم          |

الصف الثالث هو بيت القصيد: لمّ شمل متصفح بزائر معرّف سابقًا هو ما قد يحوّل «عرّفني كشخص آخر»
إلى استيلاء على حساب، فلا يحدث إلا بتوقيع نستطيع التحقق منه.

### الخصائص الإضافية

`attributes` سياق حر يراه الموظف بجانب المحادثة: الباقة، قيمة السلة، تاريخ التسجيل. قيم بسيطة
فقط — نصوص (تُقتطع عند ٥٠٠ حرف) وأرقام وقيم منطقية، وحتى ٣٠ مفتاحًا. تُهمَل الكائنات المتداخلة.

لا تضع فيها ما لا تريد أن يقرأه موظف.

## تسجيل خروج الزوار

```js theme={null}
Linkia('logout');
```

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

ولا يُحذف شيء — تبقى المحادثة في صندوق الوارد بسجلّها كاملًا.

## أحداث للأتمتة

```js theme={null}
Linkia('trackEvent', 'viewed_pricing', { plan: 'pro' });
```

يُطلق مُشغِّل `webchat.event` لأتمتاتك. ولا يُخزَّن: ما يجعل الحدث مفيدًا هو أتمتة تتصرف بناءً
عليه، وجدول بكل مشاهدة صفحة في كل موقع عميل تكلفة بلا قارئ.

## أخطاء قد تراها

| الرمز | المعنى                                                                                                                              |
| ----- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `401` | معرّف موقع مجهول أو قناة موقوفة، أو جلسة زائر منتهية. يجدّد الودجت الجلسة تلقائيًا، وتبقى العملية الفاشلة ظاهرة مع زر إعادة محاولة. |
| `403` | هذا النطاق ليس في قائمة القناة — أو توقيع مطلوب مفقود أو خاطئ.                                                                      |
| `429` | تجاوز حد. تبقى الرسالة ظاهرة مع زر إعادة محاولة.                                                                                    |

<Note>
  معرّف محادثة لا تخص هذا الزائر يعطي `404` لا `403`، وهذا مقصود: فـ `403` يؤكد وجود المحادثة،
  وهو بالضبط ما يريد معرفته من يخمّن المعرّفات.
</Note>
