Threadwire by TriTech

→ مرجع الـ API

الأدوات وأمثلة الكود

Postman

نزّل مجموعة Postman الخاصة بـ Threadwire واستوردها (Import ← أفلت الملف، أو الصق ذلك الرابط). افتح Variables في المجموعة واملأ api_key (مفتاح API الخاص بك) وinstance_id (معرّف رقمك). أما phone فهو من تصله الرسائل التجريبية، والمعرّفات مثل message_id تأتي من ردود سابقة. كل الطلبات تستخدمها، فلا حاجة إلى ضبط أي شيء آخر.

  • كل نقاط الاتصال موجودة فيها، مجمّعة كما في المرجع، مع جسم طلب جاهز لكل طلب يحتاج إليه.
  • بجانب Send a message طلب جاهز لكل نوع من الرسائل: صورة، ملف PDF، رسالة صوتية، ملف بصيغة base64، رابط مع معاينته أو بدونها، موقع، بطاقة جهة اتصال. وكذلك استطلاع، ملصق، رد مقتبس، رسالة مجدولة، مجموعة. تستخدم هذه الطلبات ملفات نموذجية من عندنا، فكل طلب يُرسل كما هو بعد الاستيراد.
  • الطلبات التي تحذف شيئًا أو تفك ربطه (إزالة رقم، فك ربط واتساب، حذف رسالة أو تصنيف) تستخدم متغيرات خاصة بها تنتهي بـ _to_remove وتُترك فارغة. بذلك لا يمكن أن يحذف تشغيل المجموعة كلها أي شيء بالخطأ.

Insomnia والأدوات الأخرى: استورد https://threadwire.net/docs/api.json، وهو وصف OpenAPI للمرجع، واضبط مصادقة Bearer Token على مفتاح API الخاص بك.

Laravel

حزمتنا tritech/threadwire-laravel ترسل عبر الـ API (نصوص، ملفات، مواقع، بطاقات جهات اتصال، استطلاعات)، وترمي استثناءً برفضنا وسببه، وتستقبل الويب هوك لديك كأحداث Laravel بعد التحقق من التوقيع. بدءًا من الإصدار 2.0 تشغّل WhatsApp OTP (verifyByLink() وsendOtpCode() وcheckOtp()؛ كان الإصدار 1.x يسمّيها بأسمائها القديمة التي لم تعد تعمل). ومن الإصدار نفسه تستعلم دوريًا عن الأحداث (events())، وتبدأ الرسائل الجماعية وتتابعها (createBroadcast()).

composer require tritech/threadwire-laravel

المصدر والأمثلة: github.com/khaledtarek54/threadwire-laravel.

أرسل رسالة بلغة البرمجة التي تستخدمها

كل مثال يرسل نصًا؛ وأضف الحقول الأخرى من إرسال الرسائل بالطريقة نفسها.

curl https://threadwire.net/api/v1/messages \
  -H "Authorization: Bearer $THREADWIRE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-shipped" \
  -d '{"instance_id": "YOUR_INSTANCE_ID", "to": "201012345678", "text": "Hi Sara, your order 1042 is on its way."}'
// PHP
$request = curl_init('https://threadwire.net/api/v1/messages');
curl_setopt_array($request, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer '.getenv('THREADWIRE_KEY'), 'Content-Type: application/json', 'Accept: application/json'],
    CURLOPT_POSTFIELDS => json_encode(['instance_id' => 'YOUR_INSTANCE_ID', 'to' => '201012345678', 'text' => 'Hi Sara, your order 1042 is on its way.']),
]);
$answer = json_decode(curl_exec($request), true);
if (curl_getinfo($request, CURLINFO_HTTP_CODE) >= 400) {
    throw new RuntimeException($answer['message'] ?? 'Threadwire refused the request');
}
$message = $answer['data'];
// Node.js 18 or later, in an ES module (.mjs, or "type": "module")
const response = await fetch('https://threadwire.net/api/v1/messages', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.THREADWIRE_KEY}`, 'Content-Type': 'application/json', Accept: 'application/json' },
  body: JSON.stringify({ instance_id: 'YOUR_INSTANCE_ID', to: '201012345678', text: 'Hi Sara, your order 1042 is on its way.' }),
});
if (!response.ok) throw new Error(await response.text());
const { data: message } = await response.json();
# Python, with requests
import os, requests

response = requests.post(
    'https://threadwire.net/api/v1/messages',
    headers={'Authorization': f"Bearer {os.environ['THREADWIRE_KEY']}", 'Accept': 'application/json'},
    json={'instance_id': 'YOUR_INSTANCE_ID', 'to': '201012345678', 'text': 'Hi Sara, your order 1042 is on its way.'},
)
response.raise_for_status()
message = response.json()['data']
// C# (.NET 8), with HttpClient
using System.Net.Http.Headers;
using System.Net.Http.Json;

var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("THREADWIRE_KEY"));
var response = await http.PostAsJsonAsync("https://threadwire.net/api/v1/messages",
    new { instance_id = "YOUR_INSTANCE_ID", to = "201012345678", text = "Hi Sara, your order 1042 is on its way." });
response.EnsureSuccessStatusCode();
// Java 11+, with java.net.http
var request = HttpRequest.newBuilder(URI.create("https://threadwire.net/api/v1/messages"))
    .header("Authorization", "Bearer " + System.getenv("THREADWIRE_KEY"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString("{\"instance_id\":\"YOUR_INSTANCE_ID\",\"to\":\"201012345678\",\"text\":\"Hi Sara, your order 1042 is on its way.\"}"))
    .build();
var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
// Go, with net/http
body := strings.NewReader(`{"instance_id":"YOUR_INSTANCE_ID","to":"201012345678","text":"Hi Sara, your order 1042 is on its way."}`)
req, _ := http.NewRequest("POST", "https://threadwire.net/api/v1/messages", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("THREADWIRE_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
# Ruby, with net/http
require 'net/http'
require 'json'

uri = URI('https://threadwire.net/api/v1/messages')
Net::HTTP.post(uri, { instance_id: 'YOUR_INSTANCE_ID', to: '201012345678', text: 'Hi Sara, your order 1042 is on its way.' }.to_json,
  'Authorization' => "Bearer #{ENV['THREADWIRE_KEY']}", 'Content-Type' => 'application/json')

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

n8n

في n8n، اختر Import from URL والصق أحد هذه الروابط؛ وكل منها يشرح إعداده في ملاحظة بجانبه. وهي تستخدم عقدتَي Webhook وHTTP Request الموجودتين في n8n نفسه، فلا حاجة إلى تثبيت أي شيء.

Make

لا يوجد تطبيق Threadwire في Make بعد. لكن وحدات Make نفسها تؤدي الغرض نفسه اليوم:

  • للاستقبال، أضف وحدة Webhooks → Custom webhook واجعل عنوانها رابط الويب هوك لديك (للمطورين ← الويب هوك في لوحة التحكم، للمسؤولين فقط). أرسل رسالة واحدة إلى رقمك ليتعرّف Make على الحقول (data.phone، data.body…)، ثم أضف فلترًا بعد الوحدة: type يساوي message.received.
  • للإرسال، أضف HTTP → Make a request: POST https://threadwire.net/api/v1/messages، وترويسة Authorization: Bearer YOUR_API_KEY، وجسم JSON فيه instance_id وto وtext.

لكل من n8n وMake:

  • اترك أحداثك كما هي. الأحداث قائمة واحدة لحسابك كله (للمطورين ← الويب هوك ← الأحداث)، والقائمة نفسها تحدد ما يحتفظ به GET /v1/events. إلغاء تحديد بقية الأحداث للحصول على message.received فقط يوقفها عن كل نظام على حسابك: تحديثات التسليم، ونتائج OTP، والرسائل الجماعية. بدلًا من ذلك، فلتر حسب type داخل الأداة، كما يفعل مسارا الاستقبال أعلاه.
  • اقفل العنوان. لا يستطيع n8n ولا Make التحقق من توقيعنا دون كود. لذلك اضبط ترويسة مصادقة في صفحة الويب هوك لديك («ترويسة المصادقة»: اسم وقيمة سرية من عندك)، واجعل الأداة تشترط الترويسة نفسها. في n8n: Authentication → Header Auth في عقدة Webhook، بذلك الاسم وتلك القيمة.
  • رابط واحد لكل حساب. يذهب إلى أداة واحدة من هذه الأدوات (أو إلى إضافة WooCommerce) في الوقت الواحد؛ ويمكن أن يكون للرقم رابطه الخاص للفصل بينها.
  • لا يوجد عنوان عام؟ استعلم دوريًا بدلًا من ذلك: Schedule Trigger في n8n كل دقيقة، ثم HTTP Request إلى GET /v1/events مع after (راجع الاستعلام الدوري).
  • الردود على من راسلوك لا تخضع أبدًا لحد الرسائل الأولى؛ أما الرسالة إلى شخص لم يراسلك قط فتخضع له، فدع الناس يراسلونك أولًا.

WooCommerce

إضافة Threadwire for WooCommerce ترسل تحديثات الطلبات على واتساب إلى المشترين الذين يطلبونها. بعد إتمام الشراء، تعرض صفحة الشكر ورسالة الطلب البريدية زر «Get order updates on WhatsApp»؛ والزر يفتح واتساب برسالة عن الطلب مكتوبة مسبقًا. عندما يرسلها المشتري، يرتبط الطلب بمحادثته، وكل حالة تختارها (قيد التنفيذ، مكتمل، ملغى…) ترسل إليه رسالة تكتبها أنت. كل تحديث هو رد في محادثة بدأها المشتري، فيبقى رقمك آمنًا: يذهب فقط إلى الهاتف الذي طلب، من الرقم الذي راسله، خلال 30 يومًا من رسالته. وأول هاتف يرسل الرقم المرجعي لطلب يحتفظ به.

للإعداد:

  1. ثبّت ملف zip في WordPress (Plugins → Add New → Upload).
  2. أنشئ مفتاح API يمكنه الإرسال (للمطورين ← مفاتيح API، للمسؤولين فقط).
  3. اجعل رابط الويب هوك لديك (للمطورين ← الويب هوك) هو العنوان الذي تعرضه الإضافة في WooCommerce → Settings → WhatsApp. أو اجعله رابط الويب هوك الخاص بذلك الرقم من صفحته، لتُبقي رابط حسابك للأنظمة الأخرى.
  4. اترك أحداثك كما هي: الإضافة تقرأ message.received فقط وتتجاهل الباقي. الأحداث قائمة واحدة لحسابك كله، فإلغاء تحديد البقية يوقفها عن كل نظام آخر أيضًا.
  5. أدخل هناك المفتاح، ومعرّف الرقم (في صفحة الرقم)، وسر التوقيع.

وكلاء الذكاء الاصطناعي (MCP)

Threadwire هو أيضًا خادم Model Context Protocol، فيستطيع وكيل ذكاء اصطناعي قراءة محادثاتك والرد عبر أرقامك. وجّه عميل MCP يقبل ترويسة Bearer (Claude Code، Cursor، أداة MCP Client في n8n، حزم MCP SDK) إلى https://threadwire.net/mcp مع مفتاح API الخاص بك كرمز Bearer. في Claude Code:

claude mcp add --transport http threadwire https://threadwire.net/mcp --header "Authorization: Bearer YOUR_KEY"
  • الأدوات: list_numbers، list_chats، get_messages، get_events (ما حدث منذ آخر مرة نظر فيها: مرّر after)، send_message (أعطه idempotency_key حتى لا تُرسل إعادة المحاولة مرتين أبدًا)، check_number، list_groups. ومعها start_otp وget_otp وcheck_otp (WhatsApp OTP)، وstart_broadcast وget_broadcast وcontrol_broadcast (الرسائل الجماعية).
  • الصفحات: تأتي القوائم صفحة صفحة، كما في الـ API: يقول الرد has_more، فيطلب الوكيل مرة أخرى مع page (next_page) أو cursor (next_cursor، للرسائل الأقدم) أو offset (next_offset، للمجموعات).
  • القواعد نفسها: كل أداة هي الـ API الذي وراءها: المفتاح الذي يقرأ فقط لا يمكنه الإرسال، وكل رسالة تُرسل بتمهّل وتُحمى مثل أي رسالة أخرى. كل طلب يُحتسب طلب API من الحصة الشهرية للباقة، ومنه فتح الجلسة.