تخطّ إلى المحتوى الرئيسي

حملات In-app

اعرض رسائل مستهدفة للمستخدمين أثناء استخدامهم النشط لتطبيقك. لا تحتاج رسائل In-app إلى إذن، ويمكن أن تتضمن محتوى غنيًا تفاعليًا، وتوجد بجوار Push وEmail في معالج Campaign الموحد.

نظرة عامة

تتيح لك حملات In-app:

  • تهيئة المستخدمين الجدد بنصائح ودروس مفيدة.
  • إعلان الميزات وتحديثات المنتج.
  • زيادة التفاعل عبر المطالبات وCTAs.
  • الترويج للعروض برسائل سياقية.
  • إجراء التجارب بنسخ A/B ومجموعات تحكم.

المزايا الأساسية:

  • لا تتطلب إذنًا، بخلاف Push.
  • محتوى غني وتفاعلي.
  • مرتبطة بنشاط المستخدم الحالي.
  • معدلات تفاعل أعلى من Push أو Email.
  • يُعرض بخطوط التطبيق وألوانه ووضعه الداكن (الرسائل الأصلية).

المتطلبات الأساسية

تأكد أولًا من دمج SDK:

يزامن SDK الحملات المؤهلة ويعرضها عندما يطابق المستخدم شروط المشغّل والاستهداف.

أنواع الرسائل

اختر التخطيط الذي يناسب حالة الاستخدام:

النوعالتخطيطالأنسب لـ
Modalوسط الشاشة مع خلفيةالإعلانات المهمة وإطلاق الميزات
Bannerشريط علوي أو سفلينصائح سريعة وعروض حساسة للوقت
Slide-upيظهر من الأسفلمطالبات خفيفة وفتح الإنجازات
Fullscreenيغطي الشاشة كاملةالتهيئة والتحديثات الكبيرة
Customعرض يحدده المطور، يُضبط من APIمتطلبات UI فريدة

إنشاء حملة In-app

تستخدم حملات In-app المعالج نفسه ذي الخطوات الست مثل القنوات الأخرى؛ راجع إنشاء الحملات للغلاف المشترك. الخطوتان المختلفتان هما Compose وDelivery.

خطوة Compose

تستخدم خطوة Compose VariantTabs مع منتقي طرق من 3 بطاقات، وهو البوابة نفسها في Email:

  • Create with Drag & Drop: محرر مرئي لغير المطورين.
  • Create with HTML: عرض مقسم بمحرر كود يسارًا ومعاينة iframe معزولة حية يمينًا.
  • Create from Template: اختر من قوالب In-app المحفوظة.

أيًا كانت الطريقة، يُخزن HTML المنشأ في customContent للنسخة. بعد إنشاء النسخة، تُختصر إلى بطاقة AuthoredSummary مع صورة مصغرة 200×220 داخل iframe للرسالة المعروضة؛ انقرها لإعادة فتح المحرر.

رسائل HTML تتطلب موافقة صريحة من التطبيق

تنتج الطرق الثلاث أعلاه HTML يعرضه التطبيق داخل web view. ولأن رسالة HTML تنفذ JavaScript كتبها المؤلف داخل التطبيق، لن تعرضها حزمة SDK ما لم يفعّل المطورون ذلك صراحةً (allowHtmlJsInAppMessages).

التطبيق الذي لم يفعّل ذلك يتجاهل حملات HTML بصمت - ولا يرى المستخدم شيئًا. إن لم تكن متأكدًا، راجع المطورين قبل جدولة حملة HTML، أو استخدم رسالة أصلية بدلًا منها.

الرسائل الأصلية

الرسالة الأصلية محتوى منظَّم - عنوان ونص وصورة وحتى ثلاثة أزرار - يرسمه التطبيق بمكوناته الخاصة. لا يوجد web view ولا تجاهل، لذا تُعرض في كل تطبيق بغض النظر عن الإعداد أعلاه، وتطابق خطوط التطبيق وألوانه ووضعه الداكن، وتعمل مع قارئات الشاشة.

المقابل هو التحكم: أنت تختار الكلمات والصورة والأزرار، والتطبيق يقرر شكلها.

الأصليةHTML
تُعرض دون موافقة التطبيقنعملا
تطابق تصميم التطبيقنعمفقط إذا أعدت بناءه بـ CSS
تحكم كامل في التخطيطلانعم
تعمل حيث لا يوجد web view (مثل tvOS)نعملا

يُكتب المحتوى الأصلي في بطاقة App style ضمن خطوة Compose، إلى جانب Drag & Drop وHTML. وإذا كنت تنشئ الحملات عبر واجهة API فراجع Campaigns API لمرجع الحقول.

الألوان والخط وCSS المخصص

ضمن Style (optional) يمكنك تجاوز خلفية البطاقة ولون النص ولون الزر الرئيسي ونص الزر ونصف قطر الزوايا. اترك الحقل فارغًا فترث الرسالة قيمته من التطبيق - وهذا بالضبط ما يجعل الرسالة الأصلية تبدو جزءًا منه، فلا تغيّر شيئًا إلا حين تحتاج الحملة إلى حضور للعلامة التجارية.

إذا ضبطت لون الزر دون لون النص، يُختار لون النص تلقائيًا - أسود أو أبيض، أيهما يبقى مقروءًا فوق لونك.

خياران يعملان على الويب فقط:

  • الخط - لا يستطيع التطبيق عرض سوى الخطوط المرفقة معه، فاسم خط لا يملكه سيؤدي إلى بديل يبدو خاطئًا. تحتفظ الهواتف بخط التطبيق نفسه.
  • CSS مخصص، ضمن Advanced - لكل ما لا تعبّر عنه الحقول. تُعاد كتابة كل محدِّد تكتبه ليقع داخل هذه الرسالة قبل تطبيقه، فلا تصل أي قاعدة إلى بقية الصفحة، والقواعد هنا تتجاوز حقول الألوان أعلاه. لا توجد في الهواتف محركات CSS فتتجاهله.

ما يمكن استهدافه: البطاقة نفسها، وh2 (العنوان)، وp (نص الرسالة)، وbutton.primary وbutton.secondary. تُتاح حقول الألوان أيضًا كمتغيرات CSS - --joryio-inapp-bg و--joryio-inapp-fg و--joryio-inapp-primary و--joryio-inapp-primary-fg و--joryio-inapp-radius و--joryio-inapp-font - بحيث يمكنك ضبطها داخل media query.

تعمل تبويبات نسخ A/B نفسها مع In-app، بما فيها مجموعات التحكم.

جعل الأزرار تعمل (الويب)

تعمل رسالة HTML المخصصة داخل إطار معزول (sandbox)، لذا لا يمكنها الوصول مباشرةً إلى صفحتك أو صفحتنا. بدلاً من ذلك توفّر Joryio جسراً صغيراً.

السمة onclick المضمّنة لا تعمل، ولن تعمل. تُزال كل سمات معالجات الأحداث من HTML عند حفظ الرسالة - وهذا تحديداً ما يمنع الرسالة من تنفيذ شيفرة عشوائية على موقعك. كتابة onclick="..." تنتج زراً يبدو صحيحاً ولا يفعل شيئاً. استخدم إحدى الآليتين أدناه.

data-joryio-action - الطريقة المعتادة

<button data-joryio-action="requestPushPermission">تفعيل الإشعارات</button>
<button data-joryio-action="closeMessage">لا، شكراً</button>
العمليةما تفعله
requestPushPermissionتعرض طلب الإشعارات في المتصفح
closeMessageتغلق الرسالة
logConversionتسجّل تحويلاً لهذه الحملة

يمكن تمرير اسم إلى logConversion عبر data-joryio-event؛ وبدونه يُسجَّل التحويل باسم in_app_conversion.

كل ذلك متاح أيضاً في لوحة الخصائص في المحرر - On click وConversion event (optional) وClick name (reports) - لذا معظم الرسائل لا تحتاج إلى HTML.

النقرات تُسجَّل تلقائياً

كل نقرة على <a> أو <button> يتم الإبلاغ عنها تلقائياً. لتسمية نقرة في التقارير، أضف data-action:

<a href="/pricing" data-action="pricing_cta">اطّلع على الخطط</a>

روابط http(s) والروابط النسبية للجذر تُفتح من الصفحة المضيفة؛ أما المرساة و mailto: وtel: فتعمل كالمعتاد.

window.joryioBridge - للرسائل التي لها سكربت خاص

الرسالة التي تتضمن <script> خاصاً بها يمكنها استدعاء الجسر مباشرةً، وهذه الطريقة الوحيدة لتمرير وسائط:

<button id="save">احفظ مقاسي</button>
<script>
document.getElementById('save').addEventListener('click', function () {
joryioBridge.setCustomUserAttribute('preferred_size', 'M');
joryioBridge.logCustomEvent('size_selected', { size: 'M' });
joryioBridge.closeMessage();
});
</script>
الدالةالغرض
logCustomEvent(name, properties)تسجيل حدث للمستخدم
setCustomUserAttribute(key, value)كتابة سمة في الملف الشخصي
logConversion(event)تسجيل تحويل لهذه الحملة
logClick(action)تسجيل نقرة بالاسم
changeUser(userId)تعريف الزائر
requestPushPermission()عرض طلب الإشعارات
navigate(url, target)فتح رابط من الصفحة المضيفة
closeMessage()إغلاق الرسالة

لاحظ الفرق: استخدام addEventListener داخل <script> الخاص بك سليم تماماً - ما يُزال هو سمة onclick.

هذه خاصة بالويب فقط. على iOS وAndroid تعمل رسالة HTML داخل web view للتطبيق وتستخدم الرسائل native أزرار التطبيق نفسه، لذا اربط أزرار الحث هناك عبر إعدادات أزرار الحملة لا عبر الـ markup.

خطوة Delivery

صُممت خطوة Delivery لحملات In-app خصيصًا: بدل منتقي نوع الإرسال الذي تستخدمه القنوات الأخرى، تحصل على ما يلي.

منتقي مشغّل رئيسي

صف من خمس بطاقات، مع تعليم On Event بـ RECOMMENDED:

المشغّلمتى تظهر الرسالة
Immediateفي جلسة المستخدم المؤهلة التالية.
On Event، موصى بهعند إطلاق حدث متتبع للمستخدم.
Push Notification Tapبعد أن تقود نقرة Push المستخدم إلى تطبيقك.
Attribute Changeعند تغير قيمة سمة مراقبة.
Attribute Thresholdعند عبور سمة رقمية حدًا.

لكل بطاقة عنوان فرعي من سطر ووصف أطول. يكشف اختيارها إعدادًا خاصًا بالوضع في لوحة رمادية ناعمة أسفلها:

  • Immediate: لا إعداد إضافيًا؛ فقط تأخير العرض المشترك أدناه.
  • On Event: منتقي حدث قابل للبحث مع بديل + Create event وشروط خصائص اختيارية.
  • Push Notification Tap: مقتطف للنسخ واللصق يوضح ربط SDK بمعرف الحملة.
  • Attribute Change: منتقي سمة وحقلا قيمة من/إلى.
  • Attribute Threshold: منتقي سمة وعامل (>, <, , , =) وقيمة حد.

تأخير العرض

يتشارك كل وضع مشغّل في حقل Display delay واحد. أدخل المدة بالثواني أو الدقائق أو الساعات عبر منتقي الوحدة؛ تنتظر الرسالة هذه المدة بعد إطلاق المشغّل قبل الظهور.

الجدولة

اختر تاريخي starts at وexpires at بمنطقتين زمنيتين مستقلتين. يثبت منتقي المنطقة workspace default في الأعلى، ثم Recipient local time، ثم قائمة IANA الكاملة، لتبقى الحالات الشائعة فوق صندوق البحث.

حدود التكرار

تحوي بطاقة واحدة عناصر تحكم التكرار:

  • Max impressions per user: مثل 3 مرات.
  • Time window: 1h / 24h / 7d / 30d / 90d / lifetime، أو نافذة مخصصة.
  • Min delay between impressions: أقل فجوة بين مرات الظهور المتتالية.

أسفلها بطاقة منفصلة Workspace touching rules تقدم مفتاح Ignore Touching Rules. تجاوز قواعد التواصل مناسب للرسائل المعاملية أو الحرجة لكنه لا ينبغي أن يكون افتراضيًا.

أفضل ممارسات التكرار
  • لا تغمر المستخدمين بعدة رسائل In-app في الجلسة نفسها.
  • باعد مرات الظهور؛ فجوة 24h+ افتراضية جيدة.
  • احجز "Ignore Touching Rules" للرسائل الحرجة فعلًا.

وضع التقييم

منتقي من 3 بطاقات، لا قائمة منسدلة لأن المفاضلات مهمة جدًا لإخفائها:

الوضعالكمونما تحصل عليهما تتخلى عنه
Differential Sync، موصى به~80msحملات غير محدودة واستهداف كامل بالشرائح/الكيانات/السلوك وبيانات الكيان في القوالب.رحلة ذهاب وإياب إلى الخادم عند تغير السمات المراقبة.
Session start only<10msتقييم مرة عند بداية الجلسة.لا تظهر التغييرات قبل بدء جلسة جديدة.

يحتفظ كلا الوضعين بالحملات المتزامنة على الجهاز ويُطلقان المحفزات محليًا، لذا تظهر الرسالة دون طلب شبكة لحظة العرض.

تشرح لوحة نصية تفصيلية أسفل البطاقات الوضع المختار. Differential Sync هو الخيار الصحيح لمعظم حالات الإنتاج.

العرض من الخادم

في وضعي Differential Sync وSession start only، يُعرض محتوى الرسالة على الخادم قبل وصوله إلى الجهاز: تُحل رموز التخصيص وContent Blocks وبيانات الكتالوج من الخادم. وبذلك تملك رسائل In-app قدرة العرض نفسها لـ Email: تعمل بيانات الكيان ومقتطفات blocks.* وعمليات بحث كتالوج المنتجات.

استخدم زر Server render test في منشئ حملة In-app لعرض رسالتك من الخادم لمستخدم تختاره ورؤية ما سيتلقاه SDK بالضبط. تحقق من التخصيص والكتل ومخرجات الكتالوج قبل تفعيل الحملة.

الإعدادات المتقدمة

لوحة مطوية أسفل بطاقة التقييم. عند فتحها:

Watch mode: يتحكم في وقت إعادة SDK تقييم أهلية الحملة بعد تغير السمات:

  • Auto، موصى به: يكتشف SDK تلقائيًا السمات التي يعتمد عليها استهداف الحملة وقوالبها ويعيد التقييم عند تغيرها.
  • Always: يعيد التقييم مع كل تغير سمة.
  • Never: بداية الجلسة فقط.

Priority tiebreaker: يستخدم عندما تشترك حملتان مؤهلتان في الأولوية نفسها:

  • Newest، الافتراضي: أظهر أحدث حملة أنشئت أولًا.
  • Oldest: أظهر أقدم حملة أولًا، FIFO.
  • Random: اختيار عشوائي من الحملات المؤهلة.

اختلافات خطوة Audience

تعمل خطوة Audience مثل القنوات الأخرى: منتقي الوضع نفسه ومنشئ الفلاتر v2 نفسه، مع جزء واحد مخفي:

  • تُخفى بطاقة Sending options. لا يوجد مفهوم اشتراك لرسائل In-app؛ يعرضها SDK بصرف النظر عن حالة قبول Email/SMS/Push.

يستخدم تنبيه "Send to everyone" الكهرماني نصًا مختلفًا: مخاطر In-app هي إرهاق modal واستنزاف حدود التكرار لا قابلية التسليم. وتتغير شرائح الفلاتر المثال إلى last_seen within 7 days وplan = free.

التخصيص باستخدام Liquid

تدعم قوالب In-app صيغة Liquid كاملة.*`:

Hi {{ user.firstName | default: "there" }},

You've earned {{ user.points }} points!

{% if user.plan == 'free' %}
<p>Upgrade to unlock more rewards.</p>
{% else %}
<p>Thanks for being a {{ user.plan }} member!</p>
{% endif %}

Latest order: #{{ entities.order.id }} ({{ entities.order.total | currency }})

تشمل الفلاتر المتاحة date_format وpluralize وcurrency وtruncate وdefault. راجع قوالب Liquid للمرجع الكامل.

تتبع نقرات الروابط

تُتبع نقرات الروابط داخل رسائل In-app تلقائيًا وتُنسب إلى الحملة؛ لا إعداد إضافيًا ولا إعادة كتابة للوسوم من جانبك. تظهر أعداد النقرات في تحليلات الحملة بجوار مرات الظهور، فتقيس click-through وتستخدم النقرات كإشارات تحويل في اختبارات A/B.

اختبار A/B

يدعم In-app تبويبات نسخ A/B نفسها لكل القنوات، بما فيها مجموعات التحكم. يكون تعيين النسخة حتميًا: في أول تقييم للمستخدم يُجزّأ user id إلى bucket وزن ويحفظ التعيين، لذا يرى المستخدم نفسه النسخة نفسها دائمًا.

لا ترى مجموعات التحكم رسالة؛ تُحجب بالكامل، لتتمكن من قياس الرفع الإضافي للحملة مقارنة بعدم فعل شيء عبر مقارنة معدلات التحويل.

Variant A: 45% - Show campaign
Variant B: 45% - Show alternative
Control: 10% - Show nothing

Variant A conversion: 5%
Control conversion: 2%
Lift: +150%

أفضل الممارسات

ابدأ بـ Differential Sync

يجب أن تعمل معظم الحملات في Differential Sync: فهو يقدم أفضل توازن بين الخصائص والأداء.### استخدم Auto Watch mode

دع SDK يكتشف تبعيات السمات. بدّل إلى Always فقط إن احتجت مراقبة سمات لا تُستخدم مباشرة في الاستهداف؛ وبدّل إلى Never فقط لرسائل الترحيب الثابتة.

نفّذ حدود التكرار

امنع إرهاق الرسائل:

  • تفاعل مرتفع: 3 مرات ظهور كل 7 أيام.
  • متوسط: مرتان كل 14 يومًا.
  • تكرار منخفض: مرة كل 30 يومًا.

اختبر نسخ A/B

ضمّن دائمًا مجموعات تحكم عند قياس أثر التحويل. التقسيم الموصى به: 45% / 45% / 10% تحكم.

استكشاف الأخطاء وإصلاحها

الحملة لا تظهر

تحقق بالترتيب:

  1. حالة الحملة active وليست draft.
  2. تشمل الجدولة الوقت الحالي، بين startsAt وexpiresAt.
  3. يطابق المستخدم فلاتر الاستهداف.
  4. لم يتجاوز حد التكرار لهذا المستخدم.
  5. لا توجد حملة أعلى أولوية تحجبها.
  6. ليس المستخدم ضمن مجموعة تحكم.

أخطاء قالب Liquid

  • سمات مفقودة: غلفها بـ | default: "fallback".
  • صيغة خاطئة: تحقق من {% endif %} و{% endfor %} المتطابقين.

مشكلات الأداء

  • بسّط منطق الاستهداف.
  • حسّن قوالب Liquid وتجنب الحلقات الثقيلة.
  • استخدم Session-start only للرسائل الثابتة.

In-app مقابل Push

الميزةIn-appPush
الإذنغير مطلوبمطلوب
وقت الظهورعندما يكون التطبيق مفتوحًافي أي وقت
المحتوى الغنينعممحدود
التفاعلمرتفعمحدود
الوصولالمستخدمون النشطون فقطكل مستخدمي SDK المثبت
الأفضل لـتفاعل سياقيإعادة تفاعل

استخدمهما معًا: Push لدفع فتح التطبيق، وIn-app لتفاعل المستخدمين النشطين.

الخطوات التالية