تخطَّ إلى المحتوى
المحتويات
الاستخدام والحساب

التحليلات

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

ما الموجود هنا

تأخذ كل المسارات النطاق نفسه في from وto وتعيده في range. ولا يوجد مؤشر ولا كائن ترقيم: النافذة الأطول من المسموح تُرفض ولا تُقسَّم إلى صفحات.

GET/v1/analytics/limitsGET/v1/analytics/summaryGET/v1/analytics/timeseriesGET/v1/analytics/heatmapGET/v1/analytics/agentsGET/v1/analytics/campaigns

تتطلب الستة جميعًا analytics.read، ويملكه المالك والمدير ومدير الفريق. وكلا بيانَي الاعتماد يعملان — انظر المصادقة.

النطاق

المعاملالقيمالوصف
from, toYYYY-MM-DDتواريخ شاملة بالمنطقة الزمنية لمساحة العمل، لا بالتوقيت العالمي ولا بتوقيت المتصل. و«آخر سبعة أيام» هو to ناقص ستة لا ناقص سبعة.
granularityday, hourللسلسلة الزمنية فقط: day أو hour. وحدّ الساعات أضيق من حدّ الأيام.

اسأل عن الحدود قبل بناء النطاق

ينشر GET /v1/analytics/limits قيم max_range_days وmax_hourly_range_days والمنطقة الزمنية ومستويات التفصيل وحدود الموظفين والحملات. والنافذة الأطول من المسموح تُرفض بـ 422 يسمّي الحدّ في details.issues — ولا تُضيَّق بصمت أبدًا — فأداة اختيار لا تسأل أولًا لا تعرف السقف إلا بالاصطدام به.

curl
curl https://whats.azzamkh.sa/api/v1/analytics/limits \
  -H "Authorization: Bearer $WA_API_KEY"

# 200 OK — every number here is DEPLOYMENT configuration and is only
# knowable from this route. Read them; never hardcode them.
# {
#   "timezone": "Asia/Riyadh",
#   "default_range_days": ...,
#   "max_range_days": ...,
#   "max_hourly_range_days": ...,
#   "granularities": ["day", "hour"],
#   "max_agents": ...,
#   "max_campaigns": ...
# }

curl "https://whats.azzamkh.sa/api/v1/analytics/summary?from=2026-08-08&to=2026-08-14" \
  -H "Authorization: Bearer $WA_API_KEY"

# 200 OK — a null average is NOT a zero: it means measured is 0.
# {
#   "range": {
#     "from": "2026-08-08", "to": "2026-08-14",
#     "timezone": "Asia/Riyadh", "days": 7, "max_range_days": 180
#   },
#   "conversations": { "opened": 214, "closed": 198, "reopened": 11 },
#   "messages": { "inbound": 1902, "outbound": 2411 },
#   "first_response": {
#     "measured": 187, "average_ms": 214000, "max_ms": 3600000
#   },
#   "resolution": { "measured": 0, "average_ms": null, "max_ms": null }
# }

يحمل range في كل استجابة القيم from وto وtimezone وdays وmax_range_days. اعرض نطاق الخادم لا النطاق الذي طلبته.

الاستجابات

الملخص

الحقلالوصف
conversations.openedالمحادثات المفتوحة في النطاق.
conversations.closedالإغلاقات في النطاق — انظر ملاحظة العدّ أدناه.
conversations.reopenedالمحادثات المعاد فتحها في النطاق.
messages.inbound, messages.outboundأعداد الرسائل الواردة والصادرة.
first_response, resolutionزمن أول رد وزمن الحل، ولكلٍّ measured و average_ms و max_ms.

المتوسط null ليس صفرًا

تكون average_ms وmax_ms بقيمة null تحديدًا حين تكون measured صفرًا. وتحويلها إلى 0 يطبع زمن رد مقداره صفر مللي ثانية لمساحة عمل لم يرد فيها أحد. كما أن measured حجم عيّنة: اعرضه بجوار المتوسط، فمتوسط على ثلاث محادثات ليس ادّعاءً كمتوسط على ثلاثة آلاف.

السلسلة الزمنية

الحقلالوصف
bucket, date, hourمفتاح الفترة وتاريخها وساعتها حين يكون التفصيل بالساعة.
conversations_opened/closed/reopenedالمفتوحة والمغلقة والمعاد فتحها في تلك الفترة.
messages_in, messages_outالواردة والصادرة في تلك الفترة.
first_response, resolutionملخّصا المدة نفساهما، لكل فترة.

السلسلة كثيفة: تحتوي أصفارها بالفعل، عن قصد. فالسلسلة المتفرّقة ترسم خطًا مستقيمًا عبر عطلة هادئة، وهو ما يُقرأ كنشاط لم يحدث. لا تملأ الفجوات ولا تعد تجميع الفترات ولا تعد الترتيب.

خريطة الحرارة

168 خلية بالضبط — سبعة أيام في أربع وعشرين ساعة — لكل منها messages_in وmessages_out وconversations_opened، مع كتلة max للقياس عليها. والأصفار موجودة أصلًا.

الموظفون

صف لكل عضو، فيه المحادثات المسندة والردود المرسلة والإغلاقات وملخّص أول رد. وهو محدود لا مُرقَّم: تُرتَّب الصفوف ثم تُقتطع، ويخبرك truncated أن الجواب هو قمة الجدول فعلًا لا صفحة اعتباطية.

قمع الحملات

الحقلالوصف
funnel.queued/sent/delivered/read/failedأعداد تراكمية، فـ queued لا يقل عن sent ولا يقل عن read.
rates.deliverydelivered مقسومًا على sent.
rates.readread مقسومًا على delivered.
rates.failurefailed مقسومًا على queued.

لكل نسبة مقام مختلف

النسب كسور بين 0 و1، والقيمة null تعني أن المقام كان صفرًا — لا أن النسبة صفر. وهذا القمع تراكمي محسوب من الطوابع الزمنية، بينما إحصاءات الحملة نفسها منفصلة محسوبة من الحالة الحالية. فلا تحاول التوفيق بينهما.

كيف تُحسب الأرقام

  • يعدّ رقم «المغلقة» الإغلاقات، من سجل يُضاف إليه فقط: المحادثة التي أُغلقت مرتين تُحسب مرتين، وإعادة الفتح لم تعد تمحو الإغلاق الذي ألغته. ولذلك قد يتجاوز عدد الإغلاقات عدد المفتوحة. سمِّها إغلاقات، وإلا قُرئت كخلل.
  • السلسلة وخريطة الحرارة كاملتان كما وصلتا. وأي شيء تضيفه — ملء فجوة أو إعادة ترتيب أو إعادة تجميع — رقم لم يعدّه أحد.
  • كل مدة تحمل measured الخاص بها. ومتوسطان بحجمَي عيّنة متباينين ليسا قابلين للمقارنة، ولا شيء يخبرك بذلك سوى الاستجابة.

الأخطاء المهمة هنا

الرمزHTTPمتى يحدث
VALIDATION_ERROR422تاريخ بصيغة خاطئة، أو نطاق معكوس، أو نافذة أطول من الحدّ. ويسمّي details.issues أيّها.
FORBIDDEN403المتصل لا يملك analytics.read.

كل رمز وحالته في صفحة الأخطاء.