الردود وWebhooks
كل ما يرسله المستلمون إليك — أصوات الاستطلاعات، وإرسالات النماذج، والتقييمات، ودورات عجلة الحظ — يُجمع لكل مشروع على حدة. ويعود إليك بطريقتين: عرض الردود لكل مستلم في لوحة التحكم، وWebhook اختياري يدفع كل تفاعل إلى نقطة النهاية الخاصة بك لحظة وصوله.
الردود لكل مستلم في لوحة التحكم
افتح لوحة التحكم ← رسالتك ← الردود. تُجمَّع كل التفاعلات التي جمعتها الرسالة حسب المستلم، وتُربط بـمصدر البيانات الخاص بالمشروع. وتعرض كل مجموعة من أجاب — عنوان بريده الإلكتروني وبقية الحقول من صفه — إلى جانب ما فعله: أي عنصر، وأي إجراء، والقيم المُرسلة، ومتى.
يعمل الإسناد عبر الرموز المميزة الموقّعة نفسها التي تحمي روابط العرض المباشر. فعندما تُخصَّص رسالة من مصدر بيانات، تحمل روابط كل مستلم رمزًا مميزًا مرتبطًا بصفه، وتُسند التفاعلات الواصلة برمز صالح إلى ذلك الصف. أما التفاعلات التي تصل دون رمز (مثل صوت في استطلاع من رسالة أُرسلت دون تخصيص) فتظل محتسبة — وتُدرج في مجموعة منفصلة باسم مجهول الهوية.
قائمة الأحداث الخام مقسّمة إلى صفحات (الأحدث أولًا): بعد تحميل أحدث صفحة، يجلب إجراء تحميل المزيد الأحداث الأقدم. ولا يتأثر كل ما يلي — الملخّصات الإجمالية، والمدرّجات التكرارية، والقمع، والاتجاه — بهذا التقسيم؛ فهو محسوب مسبقًا ويغطي دائمًا السجل الكامل للمشروع.
الطلبات وتنفيذها والاسترداد
يحصل أي مشروع يتضمن عنصر منتج على جدول الطلبات في صفحة الردود الخاصة به — صف واحد لكل عملية دفع، يتضمن المشتري والمبلغ والحالة ووقت تقديم الطلب.
- لحظة اكتمال الدفع، يتلقى المشتري رسالة تلقائيًا: محتوى التسليم للمنتج الرقمي، أو تأكيدًا بأن الطلب المادي في طريقه إلى التنفيذ.
- في الطلبات المادية، انقر تحديد كمُنفَّذ بعد شحن الطلب — لا يتولى MailInApp الشحن بنفسه، لكنه يرسل إلى المشتري إشعارًا بالشحن لحظة تفعيلك لهذا الخيار.
- انقر استرداد على أي طلب مدفوع لعكس المبلغ عبر حساب Stripe المتصل؛ ويتلقى المشتري رسالة تأكيد بالاسترداد. وتُرسل الرسالة نفسها تلقائيًا إذا اكتمل بيع في اللحظة التي نفدت فيها آخر وحدة — إذ يردّ MailInApp المبلغ إلى المشتري بدلًا من البيع بما يتجاوز المخزون بصمت.
- يفتح التواصل مع المشتري تذكرة دعم معبّأة مسبقًا بسياق ذلك الطلب — وهي أسرع طريقة لسؤال المشتري عن شيء مباشرة.
المقياس الرئيسي حسب الغرض
إذا كان للمشروع غرض محدد (استبيان، أو عرض ترويجي، أو نشرة إخبارية، أو فعالية)، فإن صفحة الردود تتصدّرها القيمة الوحيدة الأهم لذلك الغرض: معدل الاستجابة للاستبيانات، والمستلمون المتفاعلون للعروض الترويجية، ومرات الفتح المتتبَّعة للنشرات الإخبارية والفعاليات. أما المشاريع المعاملاتية والمشاريع التي لا غرض لها فتنتقل مباشرة إلى القمع والملخّصات الإجمالية أدناه. غيّر الغرض أو امسحه في أي وقت من القائمة المنسدلة بجوار عنوان الصفحة؛ فهو يحدد فقط القيمة المعروضة في الصدارة، ولا يؤثر أبدًا فيما يُسجَّل.
الملخّصات الإجمالية لـ CSAT وCES وNPS
يحصل كل عنصر تقييم على ملخّص إجمالي فوق قائمة المستلمين: عدد الردود، والمتوسط، ومدرّج تكراري (التوزيع الكامن وراء المتوسط — فمتوسط 4.1 يخفي ما إذا كانت كل التقييمات 4 أم انقسامًا بين 5 و1). وتعرض العناصر على نمط NPS أعداد المروّجين والمحايدين والمنتقدين والدرجة من −100…100 بدلًا من متوسط بسيط. ويؤدي تفصيل توزيع الردود المهمة نفسها لعناصر الاستطلاع، حسب كل خيار.
يقع قمع التفاعل (أُرسلت ← فُتحت (تقريبًا) ← تم الرد) فوق الملخّصات الإجمالية. ويعرض مخطط اتجاه الردود لكل عنصر (بفئات يومية أو أسبوعية) المتوسط عبر الزمن — فقيمة الاستبيان المتكرر تكمن في خط الاتجاه، لا في لقطة واحدة. ولا يظهر إلا عندما تتوفر للعنصر بيانات فئتين على الأقل.
الملخّصات الإجمالية لأسئلة الاستبيان
يحصل كل عنصر نموذج على ملخّص إجمالي لكل سؤال، تمامًا كما في عناصر التقييم والاستطلاع. تحصل أسئلة الاختيار من متعدد ومربعات الاختيار والمقياس الخطي والتقييم بالنجوم على مخطط شريطي لأعداد الخيارات؛ أما الأسئلة النصية الحرة (نص قصير، ونص طويل، وبريد إلكتروني، ورقم، وهاتف، وتاريخ) فتحصل على عدد الردود مع عدد قليل من الإجابات النموذجية. وتُلخَّص الاستبيانات متعددة الصفحات تمامًا كالاستبيانات أحادية الصفحة — فلا يُحتسب الإرسال إلا بعد إكمال كل الصفحات، لذا لا يظهر الاستبيان المتروك أبدًا كرد جزئي.
ليست نتائج الاستطلاعات والتقييمات وأسئلة الاستبيان هذه نهاية المطاف — إذ يمكن رسم أي منها مباشرة داخل رسالة مستقبلية بربط عنصر مخطط بـ«ردود الحملة»، دون أي إعادة إدخال يدوية. راجع ربط المخططات ببيانات حقيقية.
الواجبات وسجل الدرجات
يحصل كل عنصر واجب فيه إكمال أو إرسال واحد على الأقل على بطاقة إحصاءات (الإكمالات، والإكمالات المتأخرة، والإرسالات) فوق جدول سجل الدرجات. يحتوي الجدول على صف لكل طالب وعمود لكل واجب، ويعرض «تم» أو الإجابة المُرسلة باللون الأخضر، أو باللون الأحمر إذا وصلت بعد الموعد النهائي للعنصر. ولا تزدحم الجدول بالواجبات التي لم تتلقَّ ردودًا بعد. ومثل كل ملخّص إجمالي آخر، فهو محسوب مسبقًا ويغطي السجل الكامل للمشروع، ويتضمن كلا ملفي تصدير CSV عمودًا للواجب لكل عنصر.
الخريطة الحرارية للنقرات
أسفل الملخّصات الإجمالية، ترتّب الخريطة الحرارية للنقرات كل عنصر عادي يحمل رابطًا — الأزرار، والصور المرتبطة بروابط، وأيقونات التواصل الاجتماعي — حسب عدد النقرات، مع طول شريط وشدّة لون متناسبين مع الحجم النسبي. راجع كيف تُتتبَّع النقرات لمعرفة ما يُحتسب وما لا يُحتسب.
قمع عمق التمرير
يعرض قمع عمق التمرير نسبة زوار العرض المباشر الذين بلغوا كل مرحلة من مراحل 25/50/75/100% من الصفحة، فتعرف ما إذا كان الناس يغادرون مبكرًا أم يقرؤون حتى النهاية. ولا يعكس إلا زيارات العرض المباشر المستضاف، لا الرسالة المُرسلة نفسها — راجع عمق التمرير لمعرفة السبب.
اختبار A/B والفائزون التلقائيون
يضيف الإرسال بأكثر من نسخة واحدة (راجع الإرسال) مقارنة بين النسخ إلى صفحة الردود: معدل الفتح ومعدل النقر ومعدل الاستجابة جنبًا إلى جنب لكل نسخة، مع تمييز النسخة المتصدّرة حاليًا وفق المقياس الذي اعتمده الاختبار. ويُسند إلى كل مستلم نسخة بطريقة حتمية انطلاقًا من عنوان بريده الإلكتروني، فلا تعيد عمليات إعادة الإرسال والمحاولات المتكررة أبدًا توزيع من رأى أي نسخة. والنتائج تراكمية على مستوى المشروع، وتغطي كل عمليات إرسال A/B التي أجراها على الإطلاق، لا أحدثها فقط.
لا تقتصر النسخة على صياغة سطر الموضوع؛ بل يمكنها أيضًا تبديل هوية المُرسِل، أو محتوى المشروع بأكمله. وتُتتبَّع ردود الاستطلاع/الاختبار/تأكيد الحضور ومرات الفتح الخاصة بنسخة ذات محتوى مختلف في صفحة الردود الخاصة بمشروع تلك النسخة بدلًا من دمجها في هذه المقارنة، لأن التحقق من التفاعل يربط الإرسال بالمشروع المحدد الذي عُرض منه. وتضع لوحة المقارنة رابطًا إليه بدلًا من عرض صفر مضلّل.
يحوّل اختيار الفائز تلقائيًا اختبار A/B اليدوي إلى اختبار يدير نفسه بنفسه. اختر نسبة الاختبار (مثل إرسال الرسالة إلى 20% من القائمة موزّعة على النسخ)، ومدة الانتظار قبل الحسم، والمقياس الذي يُحسم على أساسه: الفتح، أو النقر، أو الرد داخل الرسالة، أو الإيرادات. والرد داخل الرسالة (إكمال استطلاع/اختبار/تأكيد حضور) هو الخيار الافتراضي الموصى به، لأنه لا يتأثر بميزة Mail Privacy Protection من Apple كما يتأثر تتبّع الفتح.
بعد انقضاء مدة الانتظار، يختار MailInApp النسخة صاحبة أفضل معدل لكل مستلم. وهذا ليس إجماليًا خامًا أبدًا، فلا يمكن لنسخة أُرسلت ببساطة إلى عدد أكبر من الأشخاص في الاختبار أن تبدو فائزة بحكم الحجم وحده. ثم تُرسل النسخة الفائزة إلى كل من استُبعد من الاختبار الأولي. وإذا كانت النتيجة تعادلًا أو كانت العيّنة صغيرة جدًا، يعود MailInApp إلى النسخة 1 ويوسمها بوضوح بدلًا من إعلان فائز زائف. ويعرض شريط الحالة في صفحة الردود بدقة الحالة التي بلغها الاختبار: لا يزال قيد الحسم، أو حُسم، أو تعادل، أو العيّنة أصغر من اللازم.
تحسين وقت الإرسال
متاح في باقة Pro وما فوقها. بدلًا من إرسال الرسالة إلى جميع مستلمي عملية الإرسال دفعة واحدة، يطّلع الإرسال في أفضل وقت لكل مستلم على سجل أوقات الفتح الخاص بكل جهة اتصال — أي ساعة من اليوم، بتوقيت UTC، فتح فيها رسائلك أكثر من غيرها. ويحتجز رسالته حتى تلك الساعة. أما من لا يملك بعد سجل فتح كافيًا لإعطاء إشارة موثوقة فيُرسل إليه مباشرة كإرسال فوري عادي.
ويسري بالطريقة نفسها على الإرسال اليدوي، والجدولة المتكررة، وخطوة الإرسال في الرحلة؛ وتظل الجدولة ترسل إلى كل من لا إشارة لديه في ساعتها المضبوطة، مطابقةً للسلوك السابق للتحسين. ولا يمكن حاليًا الجمع بينه وبين اختبار الفائز التلقائي في عملية الإرسال نفسها، لأن المستلم المؤجَّل لن يُحتسب بحلول وقت حسم الفائز.
التقسيم حسب حقل
استخدم التقسيم حسب لتوزيع الملخّصات الإجمالية نفسها على فئات وفق أي حقل من مصدر بياناتك — متوسط CSAT لكل موظف دعم، وNPS لكل باقة، وهكذا. ويوضع المستلمون الذين حُذف صفهم أو تقلّص منذ الإرسال في فئة (غير معروف)؛ وإذا أنتج حقل نصي حر أكثر من 20 قيمة مختلفة، تُدمج أصغر الفئات في مجموعة أخرى في النهاية حتى لا يتضخم العرض.
تصدير CSV
يصدّر تنزيل CSV في صفحة الردود ملفًا عريضًا بصف واحد لكل مستلم: كل حقل من حقول مصدر البيانات، ووقت أول فتح، وعمود لكل عنصر تفاعلي (عنوانه سؤاله). وتحصل إجابات أسئلة المتابعة على عمود خاص بها <question> — follow-up. ويقدّم تصدير ثانٍ لـ الأحداث الخام صفًا لكل حدث (المستلم، والعنصر، والإجراء، والقيمة، والطابع الزمني) للمحللين الذين يفضّلون الصيغة الطويلة.
دورة حياة الاستبيان
يمكن أن يكون للمشروع تاريخ إغلاق و/أو حدّ أقصى للردود (maxResponses). وعند بلوغ أيٍّ منهما، تُرفض أحداث التفاعل الجديدة — ويعرض العرض المباشر إشعار إغلاق بدلًا من العناصر التفاعلية، مع استمرار ظهور المحتوى الثابت — وتُظهر صفحة الردود ما إذا كان الاستبيان مغلقًا حاليًا. ولا يُصفّى شيء بأثر رجعي: تبقى الردود المسجّلة مسبقًا في بياناتك.
تنبيهات الدرجة المنخفضة داخل التطبيق
إلى جانب علامة lowScore في Webhook (أدناه)، يمكن للمشروع إدراج عدد قليل من عناوين البريد الإلكتروني لإشعارها مباشرة — دون الحاجة إلى خطوة في Zapier/Make. فكلما تجاوز رد تقييم الحدّ المضبوط لعنصره، يرسل MailInApp رسالة إلى تلك العناوين (عبر إعدادات SMTP الخاصة بك) تتضمن السؤال، والدرجة، وهوية المستلم إن كانت معروفة، ورابطًا مباشرًا إلى صفحة الردود. وإذا لم يكن هناك خادم ترحيل SMTP مضبوط، يُتخطّى التنبيه بصمت — ويظل Webhook يُطلَق. وتُحدّد التنبيهات بسقف لكل مشروع في الساعة حتى لا تُغرق موجة من الدرجات المنخفضة خادم الترحيل لديك.
إعادة بناء البيانات المجمّعة
تُقدَّم الملخّصات الإجمالية والقمع والاتجاه من بيانات مجمّعة محسوبة مسبقًا لكل مشروع، تُحدَّث مع وصول الأحداث — فتبقى سريعة مهما كان حجم سجل المشروع. وإذا أظهر مشروع إجماليات منخفضة على نحو غير متوقع أو صفرية، فالأرجح أنه جمع ردودًا قبل وجود هذه البيانات المجمّعة له؛ انقر إعادة بناء البيانات المجمّعة في صفحة الردود الخاصة به مرة واحدة لإعادة تشغيل سجل أحداثه الكامل داخل البيانات المجمّعة. ولا تحتاج المشاريع الجديدة إلى ذلك أبدًا.
Webhooks
إذا كنت تفضّل أن تصل البيانات إلى أنظمتك الخاصة — نظام CRM، أو جدول بيانات، أو أداة أتمتة — فاضبط Webhook في صفحة الردود نفسها: أدخل عنوان URL يبدأ بـ HTTPS وانقر تفعيل.
يغطي هذا الـ Webhook رسالة واحدة. لتلقّي تفاعلات كل رسائلك، إضافة إلى أحداث الحساب مثل العملاء المحتملين الجدد والحجوزات وتحرّكات الصفقات، في مكان واحد، استخدم Webhook الحساب بدلًا منه. ويُوقَّع بالطريقة نفسها.
يحدث أمران:
- يُعرض عليك سر التوقيع (
whsec_…) — انسخه فورًا، فهو يُعرض هذه المرة فقط. ويُخزَّن من جهة الخادم ويُخفى في كل مكان بعد ذلك، مثل كل بيانات الاعتماد في MailInApp. - ومن ثم، يُرسل كل تفاعل إلى عنوان URL الخاص بك عبر POST بصيغة JSON، فور تسجيله.
يمكنك تدوير السر (يُصدر سر جديد ويُعرض مرة واحدة) أو إزالة Webhook في أي وقت.
الحمولة
{
"type": "interaction.received",
"projectId": "abc123",
"event": {
"campaignId": "abc123",
"blockId": "poll-1",
"blockType": "poll",
"action": "vote",
"value": { "option": "Blue" },
"recipient": "row:3",
"projectId": "abc123",
"receivedAt": 1752480000000
},
"recipient": {
"key": "row:3",
"row": { "email": "[email protected]", "first_name": "Ada" }
},
"lowScore": false
}
event.valueهو البيانات المجمّعة نفسها — خيار الاستطلاع المختار، أو قيم حقول النموذج، أو عدد النجوم.- تكون قيمة
recipientهيnullفي التفاعلات مجهولة الهوية. أما في التفاعلات المُسندة، فإنkeyهو فهرس صف المستلم في مصدر بياناتك ("row:3"= الصف الرابع). - يُضمَّن
recipient.row— صف البيانات الكامل للمستلم — في مصادر البيانات المستضافة. أما في المصادر من نوع API فلا نستدعي نقطة النهاية الخاصة بك مع كل تفاعل؛ اربط على فهرس الصف من جهتك. - تكون قيمة
lowScoreهيtrueعندما يكون الحدث إجراءrateعلى عنصر تقييم تقع قيمته عند حدّ التنبيه المضبوط لذلك العنصر أو دونه — وهي الإشارة التي تُصفّي عليها أتمتة Zapier/Make (أو تنبيهك داخل التطبيق) لاستدعاء مدير الدعم. ويُحذف تمامًا في الأحداث غير المتعلقة بالتقييم، أو عندما لا يكون للعنصر حدّ مضبوط.
التحقق من التوقيعات
كل عملية تسليم موقّعة حتى تتمكن نقطة النهاية الخاصة بك من التأكد من أنها صادرة فعلًا عن MailInApp. وتُرسل ترويستان:
| الترويسة | المحتوى |
|---|---|
X-MailInApp-Timestamp | وقت توقيع عملية التسليم، بالحقبة الزمنية بالمللي ثانية |
X-MailInApp-Signature | v1= متبوعة بقيمة سداسية عشرية لـ HMAC-SHA256(secret, timestamp + "." + rawBody) |
احسب التوقيع المتوقع من نص الطلب الخام (قبل أي تحليل لـ JSON) وقارن باستخدام مقارنة ثابتة الزمن. ويمنع رفض الطوابع الزمنية القديمة إعادة تشغيل عمليات التسليم:
import { createHmac, timingSafeEqual } from "node:crypto";
function isValidDelivery(headers, rawBody, secret) {
const timestamp = headers["x-mailinapp-timestamp"];
const given = Buffer.from(headers["x-mailinapp-signature"] ?? "");
const expected = Buffer.from(
"v1=" +
createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex"),
);
if (given.length !== expected.length || !timingSafeEqual(given, expected)) {
return false;
}
// Reject deliveries signed more than 5 minutes ago (replay protection).
return Math.abs(Date.now() - Number(timestamp)) < 5 * 60 * 1000;
}
دلالات التسليم
- المحاولة الأولى فورية، ثم تُعاد تلقائيًا. تنتهي مهلة عمليات التسليم بعد 5 ثوانٍ؛ وأي نتيجة غير استجابة
2xx(انتهاء المهلة، أو فشل الاتصال، أو حالة خطأ) تُعامَل على أنها فشل. ويُخزَّن الحدث دائمًا في MailInApp أولًا، فلا يضيع شيء بفوات عملية تسليم — تعامل مع Webhook على أنه إشارة فورية، ومع عرض الردود على أنه مصدر الحقيقة. - إعادة المحاولة تلقائيًا مع تباعد متزايد. تُعاد محاولة التسليم الفاشل على فترات متزايدة — نحو دقيقة 1، ثم 5 دقائق، ثم 30 دقيقة، ثم ساعتين 2، ثم 6 ساعات — باستخدام عنوان URL والسر الحاليين لـ Webhook، فيُعتمد السر المُدوَّر أو عنوان URL المحدَّث تلقائيًا. وإذا فشلت كل المحاولات، تتوقف إعادة المحاولة من تلقاء نفسها، لكن عملية التسليم لا تُحذف أبدًا.
- إعادة التسليم يدويًا. تظهر أي عملية تسليم لا تزال فاشلة (قيد إعادة المحاولة أو استُنفدت محاولاتها) ضمن عمليات التسليم الفاشلة في صفحة الردود، مع سبب آخر فشل وزر إعادة التسليم — وهو مفيد مباشرة بعد إصلاح الخلل من جهتك، بدلًا من انتظار إعادة المحاولة المجدولة التالية.
- لا تعترض طريق المستلم أبدًا. تجري عمليات التسليم بعد الإقرار بتفاعل المستلم؛ فلا يمكن لنقطة نهاية بطيئة أو معطّلة أن تؤخر صوته أو إرساله أو تُفشله.
- استجب بسرعة. أعد أي استجابة
2xxبسرعة ونفّذ المعالجة الثقيلة بشكل غير متزامن.
تنبيه بشأن الثقة: نقاط نهاية التفاعل عامة بحكم الضرورة (فالبريد الوارد لا يستطيع إجراء المصادقة)، لذا فالأحداث مجهولة الهوية غير مصادق عليها بطبيعة التصميم. أما الأحداث المُسندة فتحميها رموز المستلمين المميزة الموقّعة. تحقّق من توقيع عملية التسليم، وتعامل مع
event.valueعلى أنه مدخلات مستخدم.