التحليلات
ست نقاط نهاية للقراءة فقط على نطاق تاريخي واحد بتوقيت مساحة العمل. تجيب عن عدد المحادثات، وسرعة الرد، وأوقات ذروة الأسبوع، ومن تحمّل العبء، وكيف كان أداء الحملة.
ما الموجود هنا
تأخذ كل المسارات النطاق نفسه في from وto وتعيده في range. ولا يوجد مؤشر ولا كائن ترقيم: النافذة الأطول من المسموح تُرفض ولا تُقسَّم إلى صفحات.
تتطلب الستة جميعًا analytics.read، ويملكه المالك والمدير ومدير الفريق. وكلا بيانَي الاعتماد يعملان — انظر المصادقة.
النطاق
| المعامل | القيم | الوصف |
|---|---|---|
| from, to | YYYY-MM-DD | تواريخ شاملة بالمنطقة الزمنية لمساحة العمل، لا بالتوقيت العالمي ولا بتوقيت المتصل. و«آخر سبعة أيام» هو to ناقص ستة لا ناقص سبعة. |
| granularity | day, hour | للسلسلة الزمنية فقط: day أو hour. وحدّ الساعات أضيق من حدّ الأيام. |
اسأل عن الحدود قبل بناء النطاق
ينشر GET /v1/analytics/limits قيم max_range_days وmax_hourly_range_days والمنطقة الزمنية ومستويات التفصيل وحدود الموظفين والحملات. والنافذة الأطول من المسموح تُرفض بـ 422 يسمّي الحدّ في details.issues — ولا تُضيَّق بصمت أبدًا — فأداة اختيار لا تسأل أولًا لا تعرف السقف إلا بالاصطدام به.
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.delivery | delivered مقسومًا على sent. |
| rates.read | read مقسومًا على delivered. |
| rates.failure | failed مقسومًا على queued. |
لكل نسبة مقام مختلف
النسب كسور بين 0 و1، والقيمة null تعني أن المقام كان صفرًا — لا أن النسبة صفر. وهذا القمع تراكمي محسوب من الطوابع الزمنية، بينما إحصاءات الحملة نفسها منفصلة محسوبة من الحالة الحالية. فلا تحاول التوفيق بينهما.
كيف تُحسب الأرقام
- يعدّ رقم «المغلقة» الإغلاقات، من سجل يُضاف إليه فقط: المحادثة التي أُغلقت مرتين تُحسب مرتين، وإعادة الفتح لم تعد تمحو الإغلاق الذي ألغته. ولذلك قد يتجاوز عدد الإغلاقات عدد المفتوحة. سمِّها إغلاقات، وإلا قُرئت كخلل.
- السلسلة وخريطة الحرارة كاملتان كما وصلتا. وأي شيء تضيفه — ملء فجوة أو إعادة ترتيب أو إعادة تجميع — رقم لم يعدّه أحد.
- كل مدة تحمل
measuredالخاص بها. ومتوسطان بحجمَي عيّنة متباينين ليسا قابلين للمقارنة، ولا شيء يخبرك بذلك سوى الاستجابة.
الأخطاء المهمة هنا
| الرمز | HTTP | متى يحدث |
|---|---|---|
| VALIDATION_ERROR | 422 | تاريخ بصيغة خاطئة، أو نطاق معكوس، أو نافذة أطول من الحدّ. ويسمّي details.issues أيّها. |
| FORBIDDEN | 403 | المتصل لا يملك analytics.read. |
كل رمز وحالته في صفحة الأخطاء.