قوالب البريد الإلكتروني المتقدمة

طائر

25‏/03‏/2016

البريد الإلكتروني

1 min read

قوالب البريد الإلكتروني المتقدمة

النقاط الرئيسية

    • تدعم قوالب SparkPost تأليف البريد الإلكتروني البسيط والمتقدم، بما في ذلك HTML والنص والمنطق الشرطي والحلقات، بالإضافة إلى بيانات ديناميكية لكل مستلم عبر متغيرات الاستبدال.

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

    • تسمح الأقواس الثلاثية {{{ }}} بإدخال HTML خام وغير مشفر، وهو أمر ضروري عندما تحتوي بيانات الاستبدال بالفعل على علامات.

    • يمكن إرسال المرفقات بسهولة عند استخدام نقطة نهاية النقل (content.attachments)، التي تستخلص الحدود والترميز MIME لك.

    • تعمل الصور المضمنة بشكل مشابه للمرفقات ولكن يتم عرضها في المحتوى باستخدام cid: مراجع.

    • القوالب نفسها لا تدعم المرفقات بطبيعتها، ولكن يمكنك لا يزال تضمينها عن طريق إعداد بريد إلكتروني كامل وفقاً لمعيار RFC 5322 مع أجزاء MIME وتخزينه كقالب email_rfc822.

    • عند بناء قوالب RFC 5322 خام، لا تزال الاستبدالات تعمل - ولكن فقط في الرؤوس، وأجزاء HTML والنص MIME الأولى.

    • يقدم استخدام عميل بريد لغة البرمجة الخاصة بك (مثل JavaMail) مساراً آخر: قم بإنشاء بريد MIME كامل بشكل برمجي وإرساله عبر واجهة برمجة تطبيقات نقل SparkPost.

    • للحفاظ على الصيانة، احتفظ بالعلامات والبيانات متباعدة كلما كان ذلك ممكناً - خاصة عند بناء قوالب تتضمن حلقات أو أقسام MIME متعددة.

    • تسمح ميزات القوالب المتقدمة (الشروط والتعبيرات وتكرار المصفوفات) للمطورين ببناء رسائل بريد إلكتروني متطورة ومخصصة دون إعادة كتابة القوالب بالكامل لكل حالة استخدام.

أهم النقاط في الأسئلة والأجوبة

  • هل يمكن لقوالب SparkPost التعامل مع الحلقات والمصفوفات؟

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

  • ما هي استخدامات الأقواس المعقوفة الثلاثية؟

    {{{ variable }}} يُدرج HTML الخام دون الهروب. هذا مطلوب عندما تتضمن بيانات الاستبدال بالفعل ترميز HTML.

  • هل يمكنني إرسال مرفقات مع القوالب؟

    ليس مباشرةً من خلال حقول القوالب - لكن يمكنك ذلك عن طريق تخزين قالب email_rfc822 الذي يتضمن أجزاء مرفقات MIME.

  • هل لا يزال الاستبدال يعمل في قوالب RFC 5322؟

    نعم، ولكن فقط ضمن العناوين وأجزاء HTML + نص MIME الأولى.

  • متى يجب علي استخدام نقطة النهاية للنقل بدلاً من القوالب؟

    عند إرسال المرفقات الديناميكية، أو الصور المضمنة، أو عندما تحتاج إلى أن يقوم SparkPost بالتعامل مع MIME تلقائيًا.

  • هل من الأفضل تضمين منطق العرض أم الاحتفاظ به منفصلًا؟

    أفضل الممارسات هي الحفاظ على فصل عرضك التقديمي عن البيانات. استخدم القوالب لعرض البيانات ومرر بيانات بديلة نظيفة ومنظمة.

  • هل يمكنني إنشاء بريد إلكتروني كامل بتنسيق MIME باستخدام مكتبة برمجية؟

    نعم. تتيح لك المكتبات مثل JavaMail إنشاء رسائل RFC 5322 برمجيًا وإرسالها عبر واجهة برمجة تطبيقات النقل الخاصة بـ SparkPost.

  • هل تُستخدم ميزات النموذج المتقدمة على نطاق واسع؟

    المفاجئ أن عدد قليل من المطورين يستخدمونها، لكنها تفتح إمكانيات تخصيص قوية: حلقات، وشروط، ومنطق داخلي، وهياكل MIME مخصصة.

  • لماذا أحتاج إلى قوالب RFC 5322؟

    فقط عند إرسال رسائل بريد إلكتروني معقدة متعددة الأجزاء (المرفقات، أنواع MIME المخصصة) التي لا تدعمها تجريدات القالب القياسية لـ SparkPost.

هذه المقالة موجهة إلى المطور الذي يريد الاستفادة القصوى من قدرات نموذج البريد الإلكتروني لـ SparkPost. يُفترض أنك مرتاح لقراءة محتوى JSON واتباع تدفق البرمجة الأساسي. حيث يتم إدخال مصطلحات قد تكون جديدة عليك مثل RFC 5322، النص مرتبط بمراجعته المصدرية.

مع هذا خارج الطريق، دعنا نبدأ مباشرة.

تجعل نموذج و قدرات الإرسال لـ SparkPost إرسال البريد الإلكتروني أمرًا مباشرًا. توفر تلك القدرات تجريدًا لمحتوى النص وHTML مما يعني في معظم الأوقات لا حاجة لترميز تنسيق البريد الإلكتروني الخام مباشرة، والذي تم تحديده في RFC 5322 المعروف سابقًا باسم (RFC 822). ولكن في بعض الأحيان قد ترغب في إنشاء رسائل أكثر تعقيدًا تحتوي على أجزاء أخرى من امتدادات البريد الإلكتروني المتعددة الأغراض (MIME) غير المكشوفة مباشرة عبر واجهة SparkPost الأكثر راحة.

هذه المقالة موجهة إلى المطور الذي يريد الاستفادة القصوى من قدرات نموذج البريد الإلكتروني لـ SparkPost. يُفترض أنك مرتاح لقراءة محتوى JSON واتباع تدفق البرمجة الأساسي. حيث يتم إدخال مصطلحات قد تكون جديدة عليك مثل RFC 5322، النص مرتبط بمراجعته المصدرية.

مع هذا خارج الطريق، دعنا نبدأ مباشرة.

تجعل نموذج و قدرات الإرسال لـ SparkPost إرسال البريد الإلكتروني أمرًا مباشرًا. توفر تلك القدرات تجريدًا لمحتوى النص وHTML مما يعني في معظم الأوقات لا حاجة لترميز تنسيق البريد الإلكتروني الخام مباشرة، والذي تم تحديده في RFC 5322 المعروف سابقًا باسم (RFC 822). ولكن في بعض الأحيان قد ترغب في إنشاء رسائل أكثر تعقيدًا تحتوي على أجزاء أخرى من امتدادات البريد الإلكتروني المتعددة الأغراض (MIME) غير المكشوفة مباشرة عبر واجهة SparkPost الأكثر راحة.

هذه المقالة موجهة إلى المطور الذي يريد الاستفادة القصوى من قدرات نموذج البريد الإلكتروني لـ SparkPost. يُفترض أنك مرتاح لقراءة محتوى JSON واتباع تدفق البرمجة الأساسي. حيث يتم إدخال مصطلحات قد تكون جديدة عليك مثل RFC 5322، النص مرتبط بمراجعته المصدرية.

مع هذا خارج الطريق، دعنا نبدأ مباشرة.

تجعل نموذج و قدرات الإرسال لـ SparkPost إرسال البريد الإلكتروني أمرًا مباشرًا. توفر تلك القدرات تجريدًا لمحتوى النص وHTML مما يعني في معظم الأوقات لا حاجة لترميز تنسيق البريد الإلكتروني الخام مباشرة، والذي تم تحديده في RFC 5322 المعروف سابقًا باسم (RFC 822). ولكن في بعض الأحيان قد ترغب في إنشاء رسائل أكثر تعقيدًا تحتوي على أجزاء أخرى من امتدادات البريد الإلكتروني المتعددة الأغراض (MIME) غير المكشوفة مباشرة عبر واجهة SparkPost الأكثر راحة.

إرسال القالب

الأخبار السارة هي أن إنشاء محتوى RFC 5322 كان الجزء الصعب. من هنا فصاعدًا، إرسال هذا النموذج باستخدام SparkPost هو تمامًا مثل إرسال أي نموذج آخر.

إليك كيف نرسل هذا النموذج ونقوم بملء بيانات الاستبدال:

{
  "campaign_id": "MyCampaign",
  "return_path": "myReturnPath@yourdomain.com",
  "substitution_data": {
    "replyto": "myReplyToh@yourdomain.com",
    "from": "MyFrom@yourdomain.com",
    "subject": "my subject",
    "body1": "Extra content for the HTML part",
    "body2": "Extra content for the text part"
  },
  "recipients": [
    {
      "substitution_data": {},
      "address": {
        "email": "test1@domain.com",
        "name": "test1"
      }
    }
  ],
  "content": {
    "template_id": "xxxxxxx",
    "use_draft_template": true
  }
}

الأخبار السارة هي أن إنشاء محتوى RFC 5322 كان الجزء الصعب. من هنا فصاعدًا، إرسال هذا النموذج باستخدام SparkPost هو تمامًا مثل إرسال أي نموذج آخر.

إليك كيف نرسل هذا النموذج ونقوم بملء بيانات الاستبدال:

{
  "campaign_id": "MyCampaign",
  "return_path": "myReturnPath@yourdomain.com",
  "substitution_data": {
    "replyto": "myReplyToh@yourdomain.com",
    "from": "MyFrom@yourdomain.com",
    "subject": "my subject",
    "body1": "Extra content for the HTML part",
    "body2": "Extra content for the text part"
  },
  "recipients": [
    {
      "substitution_data": {},
      "address": {
        "email": "test1@domain.com",
        "name": "test1"
      }
    }
  ],
  "content": {
    "template_id": "xxxxxxx",
    "use_draft_template": true
  }
}

الأخبار السارة هي أن إنشاء محتوى RFC 5322 كان الجزء الصعب. من هنا فصاعدًا، إرسال هذا النموذج باستخدام SparkPost هو تمامًا مثل إرسال أي نموذج آخر.

إليك كيف نرسل هذا النموذج ونقوم بملء بيانات الاستبدال:

{
  "campaign_id": "MyCampaign",
  "return_path": "myReturnPath@yourdomain.com",
  "substitution_data": {
    "replyto": "myReplyToh@yourdomain.com",
    "from": "MyFrom@yourdomain.com",
    "subject": "my subject",
    "body1": "Extra content for the HTML part",
    "body2": "Extra content for the text part"
  },
  "recipients": [
    {
      "substitution_data": {},
      "address": {
        "email": "test1@domain.com",
        "name": "test1"
      }
    }
  ],
  "content": {
    "template_id": "xxxxxxx",
    "use_draft_template": true
  }
}

تبسيط كتابة البريد الإلكتروني

أولاً، دعونا نستعرض سيناريو يوم مشمس لإرسال بريد إلكتروني. استخدم نقطة نهاية الإرسال لتوفير النص و المحتوى HTML. في الخلفية، تتولى SparkPost مسؤولية تأليف بريد إلكتروني صالح وفقاً لمعيار RFC 5322. ستقوم SparkPost بإدراج متغيرات الاستبدال من substitution_data في النص ومحتوى HTML. هذه طريقة قوية لتوليد محتوى مخصص لكل مستلم ضمن قالب مشترك.

إليك مثال على الإرسال مع محتوى HTML والنص مع substitution_data.

{
  "options": {
    "open_tracking": true,
    "click_tracking": true
  },
  "campaign_id": "christmas_campaign",
  "return_path": "bounces-christmas-campaign@domain.com",
  "metadata": {
    "user_type": "students"
  },
  "substitution_data": {
    "sender": "Big Store Team"
  },
  "recipients": [
    {
      "return_path": "123@bounces.domain.com",
      "address": {
        "email": "wilma@domain.com",
        "name": "Wilma Flintstone"
      },
      "tags": [
        "greeting",
        "prehistoric",
        "fred",
        "flintstone"
      ],
      "metadata": {
        "place": "Bedrock"
      },
      "substitution_data": {
        "customer_type": "Platinum"
      }
    }
  ],
  "content": {
    "from": {
      "name": "Fred Flintstone",
      "email": "fred@domain.com"
    },
    "subject": "Big Christmas savings!",
    "reply_to": "Christmas Sales <sales@domain.com>",
    "headers": {
      "X-Customer-Campaign-ID": "christmas_campaign"
    },
    "text": "Hi {{address.name}} \nSave big this Christmas in your area {{place}}! \nClick http://www.mysite.com and get huge discount\n Hurry, this offer is only to {{user_type}}\n {{sender}}",
    "html": "<p>Hi {{address.name}} <br>Save big this Christmas in your area {{place}}! <br>Click <a href=\"http://www.mysite.com\">here</a> and get huge discount</p><p>Hurry, this offer is only to {{user_type}}</p><p>{{sender}}</p>"
  }
}


نظرة عامة على قدرات الاستبدال

القدرة

الوصف

استبدال المتغيرات الأساسية

إدراج قيم ديناميكية فردية في محتوى النص أو HTML

المنطق الشرطي

يقدم محتوى مختلف بناءً على تقييم منطقي أو تعبير

تكرار المصفوحات

يحلقة خلال المصفوفات (مثل: قوائم الملفات) لتوليد محتوى مكرر

إدراج HTML الخام ({{{ }}})

يسمح بـ HTML غير المعالج في الحالات التي يأتي فيها التعليمات البرمجية من مصدر البيانات

تخصيص لكل مستلم

يدعم محتوى فريد بالكامل لكل مستلم


أولاً، دعونا نستعرض سيناريو يوم مشمس لإرسال بريد إلكتروني. استخدم نقطة نهاية الإرسال لتوفير النص و المحتوى HTML. في الخلفية، تتولى SparkPost مسؤولية تأليف بريد إلكتروني صالح وفقاً لمعيار RFC 5322. ستقوم SparkPost بإدراج متغيرات الاستبدال من substitution_data في النص ومحتوى HTML. هذه طريقة قوية لتوليد محتوى مخصص لكل مستلم ضمن قالب مشترك.

إليك مثال على الإرسال مع محتوى HTML والنص مع substitution_data.

{
  "options": {
    "open_tracking": true,
    "click_tracking": true
  },
  "campaign_id": "christmas_campaign",
  "return_path": "bounces-christmas-campaign@domain.com",
  "metadata": {
    "user_type": "students"
  },
  "substitution_data": {
    "sender": "Big Store Team"
  },
  "recipients": [
    {
      "return_path": "123@bounces.domain.com",
      "address": {
        "email": "wilma@domain.com",
        "name": "Wilma Flintstone"
      },
      "tags": [
        "greeting",
        "prehistoric",
        "fred",
        "flintstone"
      ],
      "metadata": {
        "place": "Bedrock"
      },
      "substitution_data": {
        "customer_type": "Platinum"
      }
    }
  ],
  "content": {
    "from": {
      "name": "Fred Flintstone",
      "email": "fred@domain.com"
    },
    "subject": "Big Christmas savings!",
    "reply_to": "Christmas Sales <sales@domain.com>",
    "headers": {
      "X-Customer-Campaign-ID": "christmas_campaign"
    },
    "text": "Hi {{address.name}} \nSave big this Christmas in your area {{place}}! \nClick http://www.mysite.com and get huge discount\n Hurry, this offer is only to {{user_type}}\n {{sender}}",
    "html": "<p>Hi {{address.name}} <br>Save big this Christmas in your area {{place}}! <br>Click <a href=\"http://www.mysite.com\">here</a> and get huge discount</p><p>Hurry, this offer is only to {{user_type}}</p><p>{{sender}}</p>"
  }
}


نظرة عامة على قدرات الاستبدال

القدرة

الوصف

استبدال المتغيرات الأساسية

إدراج قيم ديناميكية فردية في محتوى النص أو HTML

المنطق الشرطي

يقدم محتوى مختلف بناءً على تقييم منطقي أو تعبير

تكرار المصفوحات

يحلقة خلال المصفوفات (مثل: قوائم الملفات) لتوليد محتوى مكرر

إدراج HTML الخام ({{{ }}})

يسمح بـ HTML غير المعالج في الحالات التي يأتي فيها التعليمات البرمجية من مصدر البيانات

تخصيص لكل مستلم

يدعم محتوى فريد بالكامل لكل مستلم


أولاً، دعونا نستعرض سيناريو يوم مشمس لإرسال بريد إلكتروني. استخدم نقطة نهاية الإرسال لتوفير النص و المحتوى HTML. في الخلفية، تتولى SparkPost مسؤولية تأليف بريد إلكتروني صالح وفقاً لمعيار RFC 5322. ستقوم SparkPost بإدراج متغيرات الاستبدال من substitution_data في النص ومحتوى HTML. هذه طريقة قوية لتوليد محتوى مخصص لكل مستلم ضمن قالب مشترك.

إليك مثال على الإرسال مع محتوى HTML والنص مع substitution_data.

{
  "options": {
    "open_tracking": true,
    "click_tracking": true
  },
  "campaign_id": "christmas_campaign",
  "return_path": "bounces-christmas-campaign@domain.com",
  "metadata": {
    "user_type": "students"
  },
  "substitution_data": {
    "sender": "Big Store Team"
  },
  "recipients": [
    {
      "return_path": "123@bounces.domain.com",
      "address": {
        "email": "wilma@domain.com",
        "name": "Wilma Flintstone"
      },
      "tags": [
        "greeting",
        "prehistoric",
        "fred",
        "flintstone"
      ],
      "metadata": {
        "place": "Bedrock"
      },
      "substitution_data": {
        "customer_type": "Platinum"
      }
    }
  ],
  "content": {
    "from": {
      "name": "Fred Flintstone",
      "email": "fred@domain.com"
    },
    "subject": "Big Christmas savings!",
    "reply_to": "Christmas Sales <sales@domain.com>",
    "headers": {
      "X-Customer-Campaign-ID": "christmas_campaign"
    },
    "text": "Hi {{address.name}} \nSave big this Christmas in your area {{place}}! \nClick http://www.mysite.com and get huge discount\n Hurry, this offer is only to {{user_type}}\n {{sender}}",
    "html": "<p>Hi {{address.name}} <br>Save big this Christmas in your area {{place}}! <br>Click <a href=\"http://www.mysite.com\">here</a> and get huge discount</p><p>Hurry, this offer is only to {{user_type}}</p><p>{{sender}}</p>"
  }
}


نظرة عامة على قدرات الاستبدال

القدرة

الوصف

استبدال المتغيرات الأساسية

إدراج قيم ديناميكية فردية في محتوى النص أو HTML

المنطق الشرطي

يقدم محتوى مختلف بناءً على تقييم منطقي أو تعبير

تكرار المصفوحات

يحلقة خلال المصفوفات (مثل: قوائم الملفات) لتوليد محتوى مكرر

إدراج HTML الخام ({{{ }}})

يسمح بـ HTML غير المعالج في الحالات التي يأتي فيها التعليمات البرمجية من مصدر البيانات

تخصيص لكل مستلم

يدعم محتوى فريد بالكامل لكل مستلم


استبدال مصفوفات البيانات

يدرك الكثيرون أن نقاط نقل وتنسيق SparkPost يمكن أن تقوم بعملية استبدال بسيطة للمحتوى في رؤوس البريد الإلكتروني وأجسام البريد الإلكتروني. ولكن العديد يتجاهلون القدرة على توفير محتوى شرطي أو مجموعات من البيانات يمكن استبدالها أيضًا. يمكنك أيضًا تقديم محتوى فريد لكل مستلم. في هذا المثال، نرسل مجموعة من الروابط الفريدة إلى كل مستلم.

يتم الوصول إلى ذلك من خلال توفير مصفوفة JSON من البيانات التي ستتم تعبئتها في جسم البريد الإلكتروني. بمجرد تقديم البيانات، ستستخدم SparkPost منطقًا في النموذج لملءها.

في هذا المثال، ستبحث SparkPost عن بيانات الاستبدال المسماة “files_html” وتقوم بعملية “for each” على كل عنصر في المصفوفة. ستقوم بإنشاء صف بقيمة “file” في عنصر “files_html”. لاحظ الأقواس الثلاثة حول “loop_var.file“. هذا لأنه يحتوي كل عنصر في المصفوفة على HTML ونحتاج إلى إخبار الخادم باستخدامها كما هي وليس الهروب منها. سيكون الجزء النصي عبارة عن تسمية نصية بسيطة ورابط الملف.

<table>
  {{each files_html}}
    <tr>
      <td>{{{loop_var.file}}}</td>
    </tr>
  {{ end }}
</table>


إليك مثال العمل المكتمل:

{
  "recipients": [
    {
      "address": {
        "email": "recipient1@domain.com"
      },
      "substitution_data": {
        "files_html": [
          {
            "file": "<a href=\"http://domain.com/file1a.txt\">File 1a Description</a>"
          },
          {
            "file": "<a href=\"http://domain.com/file2a.txt\">File 2a Description</a>"
          }
        ],
        "files_plain": [
          {
            "file": "File 1a -- http://domain.com/file1a.txt"
          },
          {
            "file": "File 2a -- http://domain.com/file2a.txt"
          }
        ]
      }
    },
    {
      "address": {
        "email": "recipient2@domain.com"
      },
      "substitution_data": {
        "files_html": [
          {
            "file": "<a href=\"http://domain.com/file1b.txt\">File 1b Description</a>"
          },
          {
            "file": "<a href=\"http://domain.com/file2b.txt\">File 2b Description</a>"
          }
        ],
        "files_plain": [
          {
            "file": "File 1b -- http://domain.com/file1b.txt"
          },
          {
            "file": "File 2b -- http://domain.com/file2b.txt"
          }
        ]
      }
    }
  ],
  "return_path": "chris@test.domain.com",
  "content": {
    "from": {
      "name": "chris@test.domain.com",
      "email": "chris@test.domain.com"
    },
    "subject": "Sending with SparkPost is Fun",
    "html": "<b>Your Files:</b><br>\n<table>\n  {{each files_html}}\n    <tr><td>{{{loop_var.file}}}</td></tr>\n  {{ end }}\n</table>\n",
    "text": "Your Files:\n{{each files_plain}} {{loop_var.file}}\n{{ end }}\n"
  }
}

يدرك الكثيرون أن نقاط نقل وتنسيق SparkPost يمكن أن تقوم بعملية استبدال بسيطة للمحتوى في رؤوس البريد الإلكتروني وأجسام البريد الإلكتروني. ولكن العديد يتجاهلون القدرة على توفير محتوى شرطي أو مجموعات من البيانات يمكن استبدالها أيضًا. يمكنك أيضًا تقديم محتوى فريد لكل مستلم. في هذا المثال، نرسل مجموعة من الروابط الفريدة إلى كل مستلم.

يتم الوصول إلى ذلك من خلال توفير مصفوفة JSON من البيانات التي ستتم تعبئتها في جسم البريد الإلكتروني. بمجرد تقديم البيانات، ستستخدم SparkPost منطقًا في النموذج لملءها.

في هذا المثال، ستبحث SparkPost عن بيانات الاستبدال المسماة “files_html” وتقوم بعملية “for each” على كل عنصر في المصفوفة. ستقوم بإنشاء صف بقيمة “file” في عنصر “files_html”. لاحظ الأقواس الثلاثة حول “loop_var.file“. هذا لأنه يحتوي كل عنصر في المصفوفة على HTML ونحتاج إلى إخبار الخادم باستخدامها كما هي وليس الهروب منها. سيكون الجزء النصي عبارة عن تسمية نصية بسيطة ورابط الملف.

<table>
  {{each files_html}}
    <tr>
      <td>{{{loop_var.file}}}</td>
    </tr>
  {{ end }}
</table>


إليك مثال العمل المكتمل:

{
  "recipients": [
    {
      "address": {
        "email": "recipient1@domain.com"
      },
      "substitution_data": {
        "files_html": [
          {
            "file": "<a href=\"http://domain.com/file1a.txt\">File 1a Description</a>"
          },
          {
            "file": "<a href=\"http://domain.com/file2a.txt\">File 2a Description</a>"
          }
        ],
        "files_plain": [
          {
            "file": "File 1a -- http://domain.com/file1a.txt"
          },
          {
            "file": "File 2a -- http://domain.com/file2a.txt"
          }
        ]
      }
    },
    {
      "address": {
        "email": "recipient2@domain.com"
      },
      "substitution_data": {
        "files_html": [
          {
            "file": "<a href=\"http://domain.com/file1b.txt\">File 1b Description</a>"
          },
          {
            "file": "<a href=\"http://domain.com/file2b.txt\">File 2b Description</a>"
          }
        ],
        "files_plain": [
          {
            "file": "File 1b -- http://domain.com/file1b.txt"
          },
          {
            "file": "File 2b -- http://domain.com/file2b.txt"
          }
        ]
      }
    }
  ],
  "return_path": "chris@test.domain.com",
  "content": {
    "from": {
      "name": "chris@test.domain.com",
      "email": "chris@test.domain.com"
    },
    "subject": "Sending with SparkPost is Fun",
    "html": "<b>Your Files:</b><br>\n<table>\n  {{each files_html}}\n    <tr><td>{{{loop_var.file}}}</td></tr>\n  {{ end }}\n</table>\n",
    "text": "Your Files:\n{{each files_plain}} {{loop_var.file}}\n{{ end }}\n"
  }
}

يدرك الكثيرون أن نقاط نقل وتنسيق SparkPost يمكن أن تقوم بعملية استبدال بسيطة للمحتوى في رؤوس البريد الإلكتروني وأجسام البريد الإلكتروني. ولكن العديد يتجاهلون القدرة على توفير محتوى شرطي أو مجموعات من البيانات يمكن استبدالها أيضًا. يمكنك أيضًا تقديم محتوى فريد لكل مستلم. في هذا المثال، نرسل مجموعة من الروابط الفريدة إلى كل مستلم.

يتم الوصول إلى ذلك من خلال توفير مصفوفة JSON من البيانات التي ستتم تعبئتها في جسم البريد الإلكتروني. بمجرد تقديم البيانات، ستستخدم SparkPost منطقًا في النموذج لملءها.

في هذا المثال، ستبحث SparkPost عن بيانات الاستبدال المسماة “files_html” وتقوم بعملية “for each” على كل عنصر في المصفوفة. ستقوم بإنشاء صف بقيمة “file” في عنصر “files_html”. لاحظ الأقواس الثلاثة حول “loop_var.file“. هذا لأنه يحتوي كل عنصر في المصفوفة على HTML ونحتاج إلى إخبار الخادم باستخدامها كما هي وليس الهروب منها. سيكون الجزء النصي عبارة عن تسمية نصية بسيطة ورابط الملف.

<table>
  {{each files_html}}
    <tr>
      <td>{{{loop_var.file}}}</td>
    </tr>
  {{ end }}
</table>


إليك مثال العمل المكتمل:

{
  "recipients": [
    {
      "address": {
        "email": "recipient1@domain.com"
      },
      "substitution_data": {
        "files_html": [
          {
            "file": "<a href=\"http://domain.com/file1a.txt\">File 1a Description</a>"
          },
          {
            "file": "<a href=\"http://domain.com/file2a.txt\">File 2a Description</a>"
          }
        ],
        "files_plain": [
          {
            "file": "File 1a -- http://domain.com/file1a.txt"
          },
          {
            "file": "File 2a -- http://domain.com/file2a.txt"
          }
        ]
      }
    },
    {
      "address": {
        "email": "recipient2@domain.com"
      },
      "substitution_data": {
        "files_html": [
          {
            "file": "<a href=\"http://domain.com/file1b.txt\">File 1b Description</a>"
          },
          {
            "file": "<a href=\"http://domain.com/file2b.txt\">File 2b Description</a>"
          }
        ],
        "files_plain": [
          {
            "file": "File 1b -- http://domain.com/file1b.txt"
          },
          {
            "file": "File 2b -- http://domain.com/file2b.txt"
          }
        ]
      }
    }
  ],
  "return_path": "chris@test.domain.com",
  "content": {
    "from": {
      "name": "chris@test.domain.com",
      "email": "chris@test.domain.com"
    },
    "subject": "Sending with SparkPost is Fun",
    "html": "<b>Your Files:</b><br>\n<table>\n  {{each files_html}}\n    <tr><td>{{{loop_var.file}}}</td></tr>\n  {{ end }}\n</table>\n",
    "text": "Your Files:\n{{each files_plain}} {{loop_var.file}}\n{{ end }}\n"
  }
}

المرفقات في قدرات الإرسال

نقطة النهاية الخاصة بالنقل تقدم أيضًا تجريدًا لإرسال المرفقات. سترى أدناه أن المرفقات محددة في content.attachments المصفوفة حيث يصف كل كائن في المصفوفة عنصر مرفق فردي. تمامًا مثلما كان الأمر سابقًا، سيتولى SparkPost مهمة ترميز النص، HTML، الاستبدالات والتكرار عبر مصفوفة المرفقات لترميز رسالة بريد إلكتروني بشكل صحيح.

تحدد أفضل الممارسات أن إرسال المرفقات يجب أن يتم تجنبه إلا إذا كان مطلوبًا صراحة كجزء من خدمتكم.

فيما يلي الحقول المطلوبة للمرفق:

  • النوع: نوع MIME للمرفق

  • الاسم: اسم ملف المرفق

  • البيانات: بيانات الملف مشفرة بـ Base64

الحقول المطلوبة للمرفقات

الحقول

المعنى

النوع

نوع MIME للمرفق

الاسم

اسم الملف كما سيظهر للمستلم

البيانات

حمولة الملف مشفرة بـ Base64


هذه هي الشكل الذي يبدو عليه المرفق داخل مضمون نقل المحتوى:

"content": {
  "attachments": [
    {
      "type": "audio/mp3",
      "name": "voicemail.mp3",
      "data": "TVAzIERhdGEK"
    }
  ]
}

يمكنك أيضًا إرسال "صور مدمجة" داخل النقل. هذه مشابهة جدًا للمرفقات ومحددة في مصفوفة content.inline_images حيث أن كل كائن من كائنات inline_image مشابه للكائن المرفق الموضح أعلاه.

نقطة النهاية الخاصة بالنقل تقدم أيضًا تجريدًا لإرسال المرفقات. سترى أدناه أن المرفقات محددة في content.attachments المصفوفة حيث يصف كل كائن في المصفوفة عنصر مرفق فردي. تمامًا مثلما كان الأمر سابقًا، سيتولى SparkPost مهمة ترميز النص، HTML، الاستبدالات والتكرار عبر مصفوفة المرفقات لترميز رسالة بريد إلكتروني بشكل صحيح.

تحدد أفضل الممارسات أن إرسال المرفقات يجب أن يتم تجنبه إلا إذا كان مطلوبًا صراحة كجزء من خدمتكم.

فيما يلي الحقول المطلوبة للمرفق:

  • النوع: نوع MIME للمرفق

  • الاسم: اسم ملف المرفق

  • البيانات: بيانات الملف مشفرة بـ Base64

الحقول المطلوبة للمرفقات

الحقول

المعنى

النوع

نوع MIME للمرفق

الاسم

اسم الملف كما سيظهر للمستلم

البيانات

حمولة الملف مشفرة بـ Base64


هذه هي الشكل الذي يبدو عليه المرفق داخل مضمون نقل المحتوى:

"content": {
  "attachments": [
    {
      "type": "audio/mp3",
      "name": "voicemail.mp3",
      "data": "TVAzIERhdGEK"
    }
  ]
}

يمكنك أيضًا إرسال "صور مدمجة" داخل النقل. هذه مشابهة جدًا للمرفقات ومحددة في مصفوفة content.inline_images حيث أن كل كائن من كائنات inline_image مشابه للكائن المرفق الموضح أعلاه.

نقطة النهاية الخاصة بالنقل تقدم أيضًا تجريدًا لإرسال المرفقات. سترى أدناه أن المرفقات محددة في content.attachments المصفوفة حيث يصف كل كائن في المصفوفة عنصر مرفق فردي. تمامًا مثلما كان الأمر سابقًا، سيتولى SparkPost مهمة ترميز النص، HTML، الاستبدالات والتكرار عبر مصفوفة المرفقات لترميز رسالة بريد إلكتروني بشكل صحيح.

تحدد أفضل الممارسات أن إرسال المرفقات يجب أن يتم تجنبه إلا إذا كان مطلوبًا صراحة كجزء من خدمتكم.

فيما يلي الحقول المطلوبة للمرفق:

  • النوع: نوع MIME للمرفق

  • الاسم: اسم ملف المرفق

  • البيانات: بيانات الملف مشفرة بـ Base64

الحقول المطلوبة للمرفقات

الحقول

المعنى

النوع

نوع MIME للمرفق

الاسم

اسم الملف كما سيظهر للمستلم

البيانات

حمولة الملف مشفرة بـ Base64


هذه هي الشكل الذي يبدو عليه المرفق داخل مضمون نقل المحتوى:

"content": {
  "attachments": [
    {
      "type": "audio/mp3",
      "name": "voicemail.mp3",
      "data": "TVAzIERhdGEK"
    }
  ]
}

يمكنك أيضًا إرسال "صور مدمجة" داخل النقل. هذه مشابهة جدًا للمرفقات ومحددة في مصفوفة content.inline_images حيث أن كل كائن من كائنات inline_image مشابه للكائن المرفق الموضح أعلاه.

المرفقات في القوالب

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

يمكنك تحقيق المرفقات في القوالب عن طريق ترميز محتوى RFC 5322 بنفسك، والذي يتضمن المرفقات. الخبر الجيد هو أنك لن تفقد القدرة على استخدام بيانات الاستبدال في رؤوس البريد الإلكتروني وHTML والنص الأجزاء. كن على علم أن هذا النوع من القالب يحدد الاستبدالات في الرؤوس والجزء الأول من HTML والجزء الأول من النص.


قيود قالب RFC 5322

القيود

الوصف

الاستبدالات مقيدة

تنطبق فقط على الرؤوس، الجزء الأول من HTML، والجزء الأول من النص

معالجة MIME يدوية

يجب على المطور بناء جميع حدود MIME وأجزاء المرفقات

عبء صيانة أعلى

أصعب في التحديث، والتدقيق، وإصدار النسخ

غير مناسب للتجريد

يتجاوز راحة نظام القوالب الخاص بـ SparkPost


إليك مثال على كيفية القيام بذلك.

بريد RFC822

أنشئ بريدك الإلكتروني RFC 5322 مع بيانات الاستبدال التي تريدها. لقد أنشأت هذا في عميل البريد الإلكتروني الخاص بي وأرسلته لنفسي. بمجرد استلامي له، قمت بنسخ المصدر واستبدال الحقول التي أريد استبدالها ديناميكيًا.

MIME-Version: 1.0
Reply-To: {{replyto}}
Subject: {{subject}}
From: {{from}}
To: {{address.email}}
Content-Type: multipart/mixed; boundary="001a113c48b0b89d92052d3051da"
--001a113c48b0b89d92052d3051da
Content-Type: multipart/alternative; boundary="001a113c48b0b89d89052d3051d8"
--001a113c48b0b89d89052d3051d8
Content-Type: text/plain; charset=UTF-8
Email with a *text attachment*.
{{body2}}
--001a113c48b0b89d89052d3051d8
Content-Type: text/html; charset=UTF-8
<div dir="ltr">
  <div>Email with a <i>text attachment</i>.</div>
  {{body1}}
<

سترى في الجزء الأخير من الرسالة MIME Content-Disposition: attachment; filename=myfile.txt”. هناك حيث يتم تعريف اسم الملف. من المؤكد أن محتوى المرفق سيكون أكثر تعقيدًا، لكن هذا المثال يحاول الحفاظ على البساطة.

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

يمكنك تحقيق المرفقات في القوالب عن طريق ترميز محتوى RFC 5322 بنفسك، والذي يتضمن المرفقات. الخبر الجيد هو أنك لن تفقد القدرة على استخدام بيانات الاستبدال في رؤوس البريد الإلكتروني وHTML والنص الأجزاء. كن على علم أن هذا النوع من القالب يحدد الاستبدالات في الرؤوس والجزء الأول من HTML والجزء الأول من النص.


قيود قالب RFC 5322

القيود

الوصف

الاستبدالات مقيدة

تنطبق فقط على الرؤوس، الجزء الأول من HTML، والجزء الأول من النص

معالجة MIME يدوية

يجب على المطور بناء جميع حدود MIME وأجزاء المرفقات

عبء صيانة أعلى

أصعب في التحديث، والتدقيق، وإصدار النسخ

غير مناسب للتجريد

يتجاوز راحة نظام القوالب الخاص بـ SparkPost


إليك مثال على كيفية القيام بذلك.

بريد RFC822

أنشئ بريدك الإلكتروني RFC 5322 مع بيانات الاستبدال التي تريدها. لقد أنشأت هذا في عميل البريد الإلكتروني الخاص بي وأرسلته لنفسي. بمجرد استلامي له، قمت بنسخ المصدر واستبدال الحقول التي أريد استبدالها ديناميكيًا.

MIME-Version: 1.0
Reply-To: {{replyto}}
Subject: {{subject}}
From: {{from}}
To: {{address.email}}
Content-Type: multipart/mixed; boundary="001a113c48b0b89d92052d3051da"
--001a113c48b0b89d92052d3051da
Content-Type: multipart/alternative; boundary="001a113c48b0b89d89052d3051d8"
--001a113c48b0b89d89052d3051d8
Content-Type: text/plain; charset=UTF-8
Email with a *text attachment*.
{{body2}}
--001a113c48b0b89d89052d3051d8
Content-Type: text/html; charset=UTF-8
<div dir="ltr">
  <div>Email with a <i>text attachment</i>.</div>
  {{body1}}
<

سترى في الجزء الأخير من الرسالة MIME Content-Disposition: attachment; filename=myfile.txt”. هناك حيث يتم تعريف اسم الملف. من المؤكد أن محتوى المرفق سيكون أكثر تعقيدًا، لكن هذا المثال يحاول الحفاظ على البساطة.

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

يمكنك تحقيق المرفقات في القوالب عن طريق ترميز محتوى RFC 5322 بنفسك، والذي يتضمن المرفقات. الخبر الجيد هو أنك لن تفقد القدرة على استخدام بيانات الاستبدال في رؤوس البريد الإلكتروني وHTML والنص الأجزاء. كن على علم أن هذا النوع من القالب يحدد الاستبدالات في الرؤوس والجزء الأول من HTML والجزء الأول من النص.


قيود قالب RFC 5322

القيود

الوصف

الاستبدالات مقيدة

تنطبق فقط على الرؤوس، الجزء الأول من HTML، والجزء الأول من النص

معالجة MIME يدوية

يجب على المطور بناء جميع حدود MIME وأجزاء المرفقات

عبء صيانة أعلى

أصعب في التحديث، والتدقيق، وإصدار النسخ

غير مناسب للتجريد

يتجاوز راحة نظام القوالب الخاص بـ SparkPost


إليك مثال على كيفية القيام بذلك.

بريد RFC822

أنشئ بريدك الإلكتروني RFC 5322 مع بيانات الاستبدال التي تريدها. لقد أنشأت هذا في عميل البريد الإلكتروني الخاص بي وأرسلته لنفسي. بمجرد استلامي له، قمت بنسخ المصدر واستبدال الحقول التي أريد استبدالها ديناميكيًا.

MIME-Version: 1.0
Reply-To: {{replyto}}
Subject: {{subject}}
From: {{from}}
To: {{address.email}}
Content-Type: multipart/mixed; boundary="001a113c48b0b89d92052d3051da"
--001a113c48b0b89d92052d3051da
Content-Type: multipart/alternative; boundary="001a113c48b0b89d89052d3051d8"
--001a113c48b0b89d89052d3051d8
Content-Type: text/plain; charset=UTF-8
Email with a *text attachment*.
{{body2}}
--001a113c48b0b89d89052d3051d8
Content-Type: text/html; charset=UTF-8
<div dir="ltr">
  <div>Email with a <i>text attachment</i>.</div>
  {{body1}}
<

سترى في الجزء الأخير من الرسالة MIME Content-Disposition: attachment; filename=myfile.txt”. هناك حيث يتم تعريف اسم الملف. من المؤكد أن محتوى المرفق سيكون أكثر تعقيدًا، لكن هذا المثال يحاول الحفاظ على البساطة.

القالب المخزن

بمجرد أن يكون لديك عنوان بريد إلكتروني صالح وفقًا لمعيار RFC 5322، قم بتخزينه باستخدام النموذج email_rfc822 من نقطة نهاية القالب بدلاً من استخدام text و HTML الحقول. إليك مثال على ما يبدو عليه المحتوى لتلك الرسالة:

{
  "content": {
    "email_rfc822": "MIME-Version: 1.0\nReply-To: {{replyto}}\nSubject: {{subject}}\nFrom: {{from}}\nTo: {{address.email}}\nContent-Type: multipart/mixed; boundary=001a113c48b0b89d92052d3051da\n\n--001a113c48b0b89d92052d3051da\nContent-Type: multipart/alternative; boundary=001a113c48b0b89d89052d3051d8\n\n--001a113c48b0b89d89052d3051d8\nContent-Type: text/plain; charset=UTF-8\n\nEmail with a *text attachment*.\n\n{{body2}}\n\n--001a113c48b0b89d89052d3051d8\nContent-Type: text/html; charset=UTF-8\n\n<div dir=\"ltr\"><div>Email with a <i>text attachment</i>.</div>\n\n{{body1}}\n</div>\n\n--001a113c48b0b89d89052d3051d8--\n--001a113c48b0b89d92052d3051da\nContent-Type: text/plain; charset=US-ASCII; name=\"myfile.txt\"\nContent-Disposition: attachment; filename=\"myfile.txt\"\nContent-Transfer-Encoding: base64\nX-Attachment-Id: f_ild455ce0\n\nVGhpcyBpcyBteSBzaW1wbGUgdGV4dCBmaWxlLgo=\n--001a113c48b0b89d92052d3051da--"
  },
  "name": "_TMP_TEMPLATE_TEST"
}

عند اكتمال الطلب، سترد SparkPost بمعرف فريد للقالب الجديد الخاص بك. على سبيل المثال xxxxxxx.

بمجرد أن يكون لديك عنوان بريد إلكتروني صالح وفقًا لمعيار RFC 5322، قم بتخزينه باستخدام النموذج email_rfc822 من نقطة نهاية القالب بدلاً من استخدام text و HTML الحقول. إليك مثال على ما يبدو عليه المحتوى لتلك الرسالة:

{
  "content": {
    "email_rfc822": "MIME-Version: 1.0\nReply-To: {{replyto}}\nSubject: {{subject}}\nFrom: {{from}}\nTo: {{address.email}}\nContent-Type: multipart/mixed; boundary=001a113c48b0b89d92052d3051da\n\n--001a113c48b0b89d92052d3051da\nContent-Type: multipart/alternative; boundary=001a113c48b0b89d89052d3051d8\n\n--001a113c48b0b89d89052d3051d8\nContent-Type: text/plain; charset=UTF-8\n\nEmail with a *text attachment*.\n\n{{body2}}\n\n--001a113c48b0b89d89052d3051d8\nContent-Type: text/html; charset=UTF-8\n\n<div dir=\"ltr\"><div>Email with a <i>text attachment</i>.</div>\n\n{{body1}}\n</div>\n\n--001a113c48b0b89d89052d3051d8--\n--001a113c48b0b89d92052d3051da\nContent-Type: text/plain; charset=US-ASCII; name=\"myfile.txt\"\nContent-Disposition: attachment; filename=\"myfile.txt\"\nContent-Transfer-Encoding: base64\nX-Attachment-Id: f_ild455ce0\n\nVGhpcyBpcyBteSBzaW1wbGUgdGV4dCBmaWxlLgo=\n--001a113c48b0b89d92052d3051da--"
  },
  "name": "_TMP_TEMPLATE_TEST"
}

عند اكتمال الطلب، سترد SparkPost بمعرف فريد للقالب الجديد الخاص بك. على سبيل المثال xxxxxxx.

بمجرد أن يكون لديك عنوان بريد إلكتروني صالح وفقًا لمعيار RFC 5322، قم بتخزينه باستخدام النموذج email_rfc822 من نقطة نهاية القالب بدلاً من استخدام text و HTML الحقول. إليك مثال على ما يبدو عليه المحتوى لتلك الرسالة:

{
  "content": {
    "email_rfc822": "MIME-Version: 1.0\nReply-To: {{replyto}}\nSubject: {{subject}}\nFrom: {{from}}\nTo: {{address.email}}\nContent-Type: multipart/mixed; boundary=001a113c48b0b89d92052d3051da\n\n--001a113c48b0b89d92052d3051da\nContent-Type: multipart/alternative; boundary=001a113c48b0b89d89052d3051d8\n\n--001a113c48b0b89d89052d3051d8\nContent-Type: text/plain; charset=UTF-8\n\nEmail with a *text attachment*.\n\n{{body2}}\n\n--001a113c48b0b89d89052d3051d8\nContent-Type: text/html; charset=UTF-8\n\n<div dir=\"ltr\"><div>Email with a <i>text attachment</i>.</div>\n\n{{body1}}\n</div>\n\n--001a113c48b0b89d89052d3051d8--\n--001a113c48b0b89d92052d3051da\nContent-Type: text/plain; charset=US-ASCII; name=\"myfile.txt\"\nContent-Disposition: attachment; filename=\"myfile.txt\"\nContent-Transfer-Encoding: base64\nX-Attachment-Id: f_ild455ce0\n\nVGhpcyBpcyBteSBzaW1wbGUgdGV4dCBmaWxlLgo=\n--001a113c48b0b89d92052d3051da--"
  },
  "name": "_TMP_TEMPLATE_TEST"
}

عند اكتمال الطلب، سترد SparkPost بمعرف فريد للقالب الجديد الخاص بك. على سبيل المثال xxxxxxx.

استنتاج

الآن بعد أن ترى كيف يمكن استخدام SparkPost لإرسال البريد الإلكتروني بمعظم التعقيد الذي قد ترغب فيه، قد ترغب في إلقاء نظرة على “يدعم SparkPost إرسال البريد الإلكتروني على ساعة آبل” أو إلقاء نظرة على بناء الجمل البديلة لترى كيف يمكن استخدامه مع “if then else”، “التعبيرات في الشروط” أو “تكرار المصفوفة” مباشرة داخل المحتوى الخاص بنموذجك أو إرسال المحتوى.

الآن بعد أن ترى كيف يمكن استخدام SparkPost لإرسال البريد الإلكتروني بمعظم التعقيد الذي قد ترغب فيه، قد ترغب في إلقاء نظرة على “يدعم SparkPost إرسال البريد الإلكتروني على ساعة آبل” أو إلقاء نظرة على بناء الجمل البديلة لترى كيف يمكن استخدامه مع “if then else”، “التعبيرات في الشروط” أو “تكرار المصفوفة” مباشرة داخل المحتوى الخاص بنموذجك أو إرسال المحتوى.

الآن بعد أن ترى كيف يمكن استخدام SparkPost لإرسال البريد الإلكتروني بمعظم التعقيد الذي قد ترغب فيه، قد ترغب في إلقاء نظرة على “يدعم SparkPost إرسال البريد الإلكتروني على ساعة آبل” أو إلقاء نظرة على بناء الجمل البديلة لترى كيف يمكن استخدامه مع “if then else”، “التعبيرات في الشروط” أو “تكرار المصفوفة” مباشرة داخل المحتوى الخاص بنموذجك أو إرسال المحتوى.

أخبار أخرى

اقرأ المزيد من هذه الفئة

A person is standing at a desk while typing on a laptop.

المنصة الكاملة المدعومة بالذكاء الاصطناعي التي تتوسع مع أعمالك.

A person is standing at a desk while typing on a laptop.

المنصة الكاملة المدعومة بالذكاء الاصطناعي التي تتوسع مع أعمالك.

A person is standing at a desk while typing on a laptop.

المنصة الكاملة المدعومة بالذكاء الاصطناعي التي تتوسع مع أعمالك.