تحديد الرسائل كمقروءة (Seen)

تحديد رسائل محددة أو دردشة كاملة كمقروءة (العلامات الزرقاء).

POST
https://api.wawp.net/v2/send/seen?access_token=YOUR_ACCESS_TOKEN&chatId=201234567890%40c.us&instance_id=123456789&messageIds=%5B%22false_201234567890%40c.us_AAAAAAAAAAAAAAAAAAAA%22%5D&participant=null

تسجيل الدخول مطلوب

سجل الدخول لاستبدال المعرفات (Instance ID) ورمز الوصول (Access Token) بمعلومات حسابك الحقيقي لاختبار ال API مباشرة.

تسجيل الدخول
اختبار /v2/send/seen
POST
POST

لا توجد معاملات استعلام مطلوبة

هذه النهاية الطرفية لا تتوقع بيانات في الرابط.

توصيات

  • Use this when a human agent opens a conversation to keep your CRM in sync with WhatsApp.

  • Batch multiple message IDs in a single call to save API resources.

مزامنة الحالة: إتقان محرك إيصالات القراءة

تعد نقطة النهاية /v2/send/seen الآلية الأساسية لإدارة "التواجد والانتباه" داخل محادثة واتساب. في نظام واتساب البيئي، يعد الانتقال من العلامات الرمادية (تم التسليم) إلى العلامات الزرقاء (تمت القراءة) حدثاً عالي الأهمية يحدد توقعات المستخدم. من خلال تحديد الرسائل كمقروءة برمجياً، يمكنك مزامنة CRM المخصص الخاص بك، أو لوحة التحكم، أو حالة البوت مع واجهة واتساب الأصلية، مما يضمن شعور العميل بأنه مسموع وبقاء مساحة عمل الوكيل منظمة.


🏗️ مسار إيصالات القراءة

تحديد الرسالة كـ "مقروءة" هو حدث مزامنة ثنائي الاتجاه يتعامل معه Wawp:

  1. تحديد الهدف: يستقبل المحرك مصفوفة من messageIds. هذه المعرفات هي تجزئات تشفيرية فريدة يتم إنشاؤها عند إرسال الرسالة أو استلامها لأول مرة. يقوم Wawp بتحديد مكان هذه الإدخالات المحددة داخل مخزن الرسائل المحلي للجلسة.
  2. بث العلامات الزرقاء: بمجرد تحديد الهوية، يرسل Wawp حزمة "تأكيد قراءة" متخصصة عبر WhatsApp WebSocket. يتم بعد ذلك نشر هذه الحزمة إلى جهاز المرسل الأصلي، حيث تتحول علامات التسليم فوراً إلى اللون الأزرق.
  3. مسح الرسائل غير المقروءة داخلياً: بالتزامن مع ذلك، يوجه Wawp شبكة واتساب لمسح شارة "عدد الرسائل غير المقروءة" لتلك الدردشة المحددة على جميع الأجهزة المرتبطة (مثلاً، إذا كان لديك WhatsApp Web أو Desktop مفتوحاً بجانب مثيل API الخاص بك).

🛡️ أفضل الممارسات الاستراتيجية لإدارة القراءة

1. مزامنة "الإنسان في الحلقة" (Human-in-the-Loop)

تتطلب أتمتة إيصالات القراءة مواءمة دقيقة مع نشاط الوكيل الفعلي.

  • سير العمل: لا تقم بتشغيل /v2/send/seen إلا عندما يقوم الوكيل بفتح الدردشة فعلياً في لوحة التحكم المخصصة الخاصة بك.
  • تأثير تجربة المستخدم: إذا قمت بتحديد كل شيء كمقروء تلقائياً، يتوقع العميل رداً فورياً. إذا لم يكن الوكيل موجوداً بالفعل، فإنك تخلق "فجوة استجابة" تؤدي إلى إحباط العميل.

2. التجميع عالي الكفاءة (Batching)

يدعم Wawp تجميع رسائل متعددة في استدعاء API واحد لسبب وجيه.

  • التنفيذ: إذا أرسل المستخدم خمس رسائل (نص، صورة، ثم مزيد من النصوص) أثناء غياب وكيلك، فلا تستدعي نقطة نهاية seen خمس مرات. بدلاً من ذلك، اجمع المعرفات الخمسة messageIds وأرسلها في مصفوفة واحدة.
  • الأداء: يقلل التجميع من عدد عمليات نقل WebSocket، مما يحافظ على عرض النطاق الترددي لمثيلك ويقلل الحمل على شبكة واتساب.

3. محاكاة القراءة الطبيعية (استراتيجية التأخير)

البوتات التي تستجيب فوراً وتحدد الرسائل كمقروءة في أجزاء من الثانية غالباً ما تبدو "روبوتية" وغير بشرية.

  • توصية: لتدفقات البوت المؤتمتة، قم بتنفيذ تأخير بسيط وعشوائي (مثلاً من 800 ملي ثانية إلى ثانيتين) بين استلام الرسالة وتحديدها كمقروءة. يحاكي هذا العملية البشرية لالتقاط الهاتف وقراءة الرسالة، مما يجعل التفاعل يبدو أكثر طبيعية.

🧩 حالات استخدام متقدمة

تتبع "الفتح" في CRM الأصلي

إذا كنت تقوم ببناء CRM مخصص فوق Wawp، استخدم نقطة نهاية seen لتتبع أداء الوكلاء. من خلال قياس الوقت بين الـ Webhook الخاص بـ message.received واستدعاء نظامك لـ /v2/send/seen، يمكنك حساب "متوسط وقت العرض"، وهو مؤشر أداء رئيسي (KPI) حاسم لفرق الدعم.

"فرز" تدفق البوت

في بوت متعدد المراحل، يمكنك استخدام إيصالات القراءة للإشارة إلى مراحل معينة. على سبيل المثال، حدد استفسار المستخدم الأولي كمقروء فقط بعد أن ينجح البوت في تصنيف القصد. يوفر هذا للمستخدم تأكيداً مرئياً بأن النظام قد "فهم" المدخلات وهو الآن يعالج النتيجة.


🛠️ المزالق الشائعة والحلول

  • معرف المشارك (في المجموعات): في الدردشات الجماعية، يتطلب تحديد الرسالة كمقروءة chatId للمجموعة واختيارياً معرف المشارك participant للمرسل الأصلي. إذا أغفلت معرف المشارك في البيئات الجماعية عالية التزامن، قد تفشل بعض إصدارات المحرك في تحديد تجزئة الرسالة المحددة، مما يؤدي إلى خطأ في الإيصال.
  • حلقات "المقروء بالفعل": تجنب استدعاء نقطة النهاية seen للرسائل التي أرسلتها أنت بنفسك. على الرغم من أنها غير ضارة، إلا أنها استدعاء API ضائع. يجب أن يركز معظم منطق CRM حصرياً على الرسائل الواردة (غير المقروءة).
  • مزامنة مفاتيح الأمان: في حالات نادرة، إذا كان الجلسة تحت حمل ثقيل، قد تنتهي مهلة حزمة "Seen". يوفر Wawp علامة acknowledged: true في الاستجابة للتأكيد على أن البروكسي قد مرر الطلب للشبكة. إذا تلقيت فشلاً، تحقق من حالة الجلسة عبر /v2/session/status.

ملخص الإمكانيات:

  • تشغيل علامات واتساب الزرقاء (إيصالات القراءة) برمجياً.
  • دعم تحديد رسائل متعددة كمقروءة في استدعاء API واحد.
  • مزامنة عدادات الرسائل غير المقروءة عبر جميع أجهزة واتساب المرتبطة.
  • دعم أصلي لإيصالات القراءة للفرد، المجموعات، والقنوات.
  • تكامل عالي الدقة مع لوحات تحكم CRM لتتبع نشاط الوكلاء.
  • تأكيد تسليم موثوق عبر شبكة تسليم بروكسي Wawp.

البارامترات

قم بتهيئة المعاملات المطلوبة للتفاعل مع نقطة النهاية هذه. جميع وسائط الاستعلام والبيانات مدرجة أدناه مع تفاصيلها.

محتوى الطلب

يرسل كـ JSON
string

المعرف الفريد لجلسة واتساب

مثال:
string

رمز وصول API الخاص بك

مثال:
string

رقم الهاتف المستهدف أو معرف المجموعة

مثال:
array

مصفوفة من معرفات الرسائل لتحديدها كمقروءة.

مثال:
string

المشارك الذي أرسل الرسالة (للمجموعات).

مثال:

أمثلة الكود

استخدم أمثلة الكود الجاهزة لدمج واجهة برمجة التطبيقات (API) في مشروعك بسرعة وكفاءة. اختر لغة البرمجة والمكتبة التي تفضلها.

1const baseUrl = "https://api.wawp.net";
2const endpoint = "/v2/send/seen";
3const params = new URLSearchParams({
4 "instance_id": "123456789",
5 "access_token": "YOUR_ACCESS_TOKEN"
6}).toString();
7const body = {
8 "chatId": "201234567890@c.us",
9 "messageIds": [
10 "false_201234567890@c.us_AAAAAAAAAAAAAAAAAAAA"
11 ],
12 "participant": "null"
13};
14
15fetch(`${baseUrl}${endpoint}${params ? '?' + params : ''}`, {
16 method: "POST",
17 headers: { "Content-Type": "application/json" },
18 body: JSON.stringify(body)
19})
20 .then(async (response) => {
21 if (response.ok) {
22 const data = await response.json();
23 console.log("Success:", data);
24 return data;
25 }
26
27 // Error Handling
28 if (response.status === 400) {
29 console.error("Error 400: طلب غير صالح - معاملات مطلوبة مفقودة");
30 }
31 if (response.status === 400) {
32 console.error("Error 400: Bad Request - Invalid Number (Egypt)");
33 }
34 if (response.status === 400) {
35 console.error("Error 400: Bad Request - Invalid Number (Saudi Arabia)");
36 }
37 if (response.status === 400) {
38 console.error("Error 400: Bad Request - Invalid Number (Unknown)");
39 }
40 if (response.status === 400) {
41 console.error("Error 400: طلب غير صالح (تنسيق XML)");
42 }
43 if (response.status === 400) {
44 console.error("Error 400: طلب غير صالح (نص عادي)");
45 }
46 if (response.status === 401) {
47 console.error("Error 401: غير مصرح - مفتاح الوصول غير صالح أو مفقود");
48 }
49 if (response.status === 401) {
50 console.error("Error 401: غير مصرح (تنسيق XML)");
51 }
52 if (response.status === 404) {
53 console.error("Error 404: غير موجود - الجلسة غير موجودة");
54 }
55 if (response.status === 404) {
56 console.error("Error 404: غير موجود (تنسيق XML)");
57 }
58 if (response.status === 429) {
59 console.error("Error 429: طلبات كثيرة جداً - تم تجاوز حد المعدل");
60 }
61 if (response.status === 500) {
62 console.error("Error 500: خطأ في الخادم الداخلي - فشل غير متوقع");
63 }
64 if (response.status === 500) {
65 console.error("Error 500: خطأ في الخادم الداخلي (HTML)");
66 }
67 if (response.status === 502) {
68 console.error("Error 502: بوابة غير صالحة - فشل الاتصال بالخادم الرئيسي");
69 }
70 if (response.status === 502) {
71 console.error("Error 502: بوابة غير صالحة (تنسيق XML)");
72 }
73
74 const errorText = await response.text();
75 console.error(`Error ${response.status}: ${errorText}`);
76 })
77 .catch((error) => console.error("Network Error:", error));
عينات تفاعلية
Ln 77, Col 1javascript

الردود المتوقعة

استكشف كافة الردود والنتائج المحتملة من الخادم. قمنا بتوثيق كل كود حالة (Status Code) مع أمثلة للبيانات لتسهيل معالجة الأخطاء والنجاح.

تم إرسال الرسالة بنجاح
النوع:
application/json
object *
string *
object *
number *
boolean *
string *
string *
number *
string *
string *
string *
boolean *
number *
boolean *
boolean *
boolean *
boolean *
boolean *
array *
array *
array *
boolean *
array *

Example

{
"_data": {
  "id": {
    "fromMe": true,
    "remote": "000000000000@c.us",
    "id": "MSG_ID_123456",
    "_serialized": "true_000000000000@c.us_MSG_ID_123456"
    },
  "viewed": false,
  "body": "BASE64_IMAGE_DATA",
  "type": "image",
  "t": 1759108866,
  "from": {
    "server": "c.us",
    "user": "111111111111",
    "_serialized": "111111111111@c.us"
    },
  "to": {
    "server": "c.us",
    "user": "000000000000",
    "_serialized": "000000000000@c.us"
    },
  "ack": 0,
  "isNewMsg": true,
  "star": false,
  "kicNotified": false,
  "caption": "Here's your requested image.",
  "deprecatedMms3Url": "https://example.com/media-url",
  "directPath": "/media/direct/path/example",
  "mimetype": "image/jpeg",
  "filehash": "FILE_HASH_PLACEHOLDER",
  "encFilehash": "ENC_FILE_HASH_PLACEHOLDER",
  "size": 192487,
  "mediaKey": "MEDIA_KEY_PLACEHOLDER",
  "mediaKeyTimestamp": 1759108865,
  "streamable": false,
  "mediaHandle": null,
  "isFromTemplate": false,
  "pollInvalidated": false,
  "isSentCagPollCreation": false,
  "latestEditMsgKey": null,
  "latestEditSenderTimestampMs": null,
  "mentionedJidList": {
    },
  "groupMentions": {
    },
  "isEventCanceled": false,
  "eventInvalidated": false,
  "isVcardOverMmsDocument": false,
  "isForwarded": false,
  "isQuestion": false,
  "questionReplyQuotedMessage": null,
  "questionResponsesCount": 0,
  "readQuestionResponsesCount": 0,
  "labels": {
    },
  "hasReaction": false,
  "disappearingModeInitiator": "chat",
  "disappearingModeTrigger": "chat_settings",
  "productHeaderImageRejected": false,
  "lastPlaybackProgress": 0,
  "isDynamicReplyButtonsMsg": false,
  "isCarouselCard": false,
  "parentMsgId": null,
  "callSilenceReason": null,
  "isVideoCall": false,
  "callDuration": null,
  "callCreator": null,
  "callParticipants": null,
  "isCallLink": null,
  "callLinkToken": null,
  "isMdHistoryMsg": false,
  "stickerSentTs": 0,
  "lastUpdateFromServerTs": 0,
  "invokedBotWid": null,
  "bizBotType": null,
  "botResponseTargetId": null,
  "botPluginType": null,
  "botPluginReferenceIndex": null,
  "botPluginSearchProvider": null,
  "botPluginSearchUrl": null,
  "botPluginSearchQuery": null,
  "botPluginMaybeParent": false,
  "botReelPluginThumbnailCdnUrl": null,
  "botMessageDisclaimerText": null,
  "botMsgBodyType": null,
  "requiresDirectConnection": false,
  "bizContentPlaceholderType": null,
  "hostedBizEncStateMismatch": false,
  "senderOrRecipientAccountTypeHosted": false,
  "placeholderCreatedWhenAccountIsHosted": false,
  "galaxyFlowDisabled": false,
  "links": {
    }
  },
"mediaKey": "MEDIA_KEY_PLACEHOLDER",
"id": {
  "fromMe": true,
  "remote": "000000000000@c.us",
  "id": "MSG_ID_123456",
  "_serialized": "true_000000000000@c.us_MSG_ID_123456"
  },
"ack": 0,
"hasMedia": true,
"body": "Here's your requested image.",
"type": "image",
"timestamp": 1759108866,
"from": "111111111111@c.us",
"to": "000000000000@c.us",
"deviceType": "android",
"isForwarded": false,
"forwardingScore": 0,
"isStatus": false,
"isStarred": false,
"fromMe": true,
"hasQuotedMsg": false,
"hasReaction": false,
"vCards": {
  },
"mentionedIds": {
  },
"groupMentions": {
  },
"isGif": false,
"links": {
  }
}
طلب غير صالح - معاملات مطلوبة مفقودة
غير مصرح - مفتاح الوصول غير صالح أو مفقود
غير موجود - الجلسة غير موجودة
طلبات كثيرة جداً - تم تجاوز حد المعدل
خطأ في الخادم الداخلي - فشل غير متوقع
بوابة غير صالحة - فشل الاتصال بالخادم الرئيسي
الموضوع السابقإرسال بطاقة جهة اتصال
الموضوع التاليبدء الكتابة (Start Typing)

Command Palette

Search for a command to run...