كيف ترسل البريد الإلكتروني التفاعلي من Node.js وPython وcURL

أمثلة جاهزة للنسخ لإرسال البريد الإلكتروني عبر واجهة REST من Node.js وPython وPHP وسطر الأوامر، مع مهلات زمنية ومعالجة للأخطاء ودالة مساعدة قابلة لإعادة الاستخدام.

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

يوضّح هذا المقال كيفية إرسالها عبر واجهة REST من Inbixio باللغات الأكثر استخدامًا لدى الفرق، ثم يحوّل الاستدعاء المنفرد إلى دالة مساعدة صغيرة يمكنك إضافتها إلى أي قاعدة شيفرة.

الطلب في مكان واحد

ترسل كل الأمثلة أدناه طلب HTTP نفسه:

  • الطريقة وعنوان URL: POST https://backend.inbixio.com/api/send-email/، بما في ذلك الشرطة المائلة في النهاية
  • المصادقة: ترويسة X-API-Key بمفتاح يملك صلاحية Send (إرسال)
  • الجسم: JSON يتضمن to_email وsubject وmessage (بصيغة HTML)

يُعيد الاستدعاء الناجح 200 مع {"message": "Email queued successfully."}. إن لم تكن قد أنشأت مفتاحًا أو ربطت خادم SMTP بعد، فابدأ بـ دليل البدء السريع في خمس دقائق.

في كل الأمثلة يُقرأ المفتاح من متغيّر بيئة باسم INBIXIO_API_KEY. أبقِه على الخادم؛ ولا تشحنه أبدًا إلى متصفح أو تطبيق جوال.

cURL

مفيد لاختبار مفتاح، أو لتتبّع الأخطاء من خادم، أو للاستدعاء من سكربت shell أو مهمة cron:

curl -sS -X POST https://backend.inbixio.com/api/send-email/ \
  -H "X-API-Key: $INBIXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --max-time 15 \
  -d '{
    "to_email": "ada@example.com",
    "subject": "Your invoice is ready",
    "message": "<p>Hi Ada, your invoice for October is ready.</p>"
  }'

يُخفي الخيار -sS شريط التقدّم مع الاستمرار في طباعة الأخطاء، ويمنع --max-time السكربت من التعليق إن تعطّلت الشبكة.

Node.js

يأتي Node.js 18 والإصدارات الأحدث مع fetch مدمجة، فلا حاجة إلى مكتبة HTTP:

// send-email.js
const INBIXIO_URL = 'https://backend.inbixio.com/api/send-email/';

export async function sendEmail({ to, subject, html }) {
  const res = await fetch(INBIXIO_URL, {
    method: 'POST',
    headers: {
      'X-API-Key': process.env.INBIXIO_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ to_email: to, subject, message: html }),
    signal: AbortSignal.timeout(15_000),
  });

  const body = await res.json().catch(() => ({}));
  if (!res.ok) {
    const reason = body.error || body.detail || res.statusText;
    throw new Error(`Inbixio ${res.status}: ${reason}`);
  }
  return body; // { message: 'Email queued successfully.' }
}

واستخدامها من مسار في Express:

app.post('/signup', async (req, res) => {
  const user = await createUser(req.body);
  await sendEmail({
    to: user.email,
    subject: 'Welcome aboard',
    html: `<h1>Welcome, ${escapeHtml(user.name)}!</h1><p>Your account is ready.</p>`,
  });
  res.status(201).json({ id: user.id });
});

لاحظ escapeHtml. يُعرض الحقل message بصيغة HTML، لذا يجب تهريب (escape) أي شيء كتبه المستخدم، كاسمه مثلًا، قبل وضعه في نص الرسالة.

Python

باستخدام requests:

# send_email.py
import os
import requests

INBIXIO_URL = "https://backend.inbixio.com/api/send-email/"

class EmailError(Exception):
    pass

def send_email(to: str, subject: str, html: str) -> dict:
    res = requests.post(
        INBIXIO_URL,
        headers={"X-API-Key": os.environ["INBIXIO_API_KEY"]},
        json={"to_email": to, "subject": subject, "message": html},
        timeout=15,
    )
    if not res.ok:
        try:
            body = res.json()
        except ValueError:
            body = {}
        reason = body.get("error") or body.get("detail") or res.reason
        raise EmailError(f"Inbixio {res.status_code}: {reason}")
    return res.json()

يضبط تمرير json= الترويسة Content-Type تلقائيًا. واضبط دائمًا timeout: فـ requests تنتظر إلى ما لا نهاية افتراضيًا.

في Django، استدعِها بعد اعتماد معاملة قاعدة البيانات، كي لا ترسل أبدًا بريدًا عن سجل تم التراجع عنه:

from django.db import transaction

transaction.on_commit(lambda: send_email(user.email, "Welcome!", render_welcome(user)))

PHP

<?php
function send_email(string $to, string $subject, string $html): array {
    $ch = curl_init('https://backend.inbixio.com/api/send-email/');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_HTTPHEADER => [
            'X-API-Key: ' . getenv('INBIXIO_API_KEY'),
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode([
            'to_email' => $to,
            'subject'  => $subject,
            'message'  => $html,
        ]),
    ]);
    $body = json_decode(curl_exec($ch), true) ?? [];
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);

    if ($status !== 200) {
        throw new RuntimeException("Inbixio $status: " . ($body['error'] ?? $body['detail'] ?? 'request failed'));
    }
    return $body;
}

الإرسال إلى عدة أشخاص

كل طلب يُسلَّم إلى to_email واحد. ولإشعار قائمة من المستخدمين، أرسل طلبًا لكل مستلم. وهذا ما تريده أصلًا في البريد التفاعلي: يحصل كل مستخدم على رسالته الخاصة، ولا يرى أحد عنوان غيره، ولا يعطّل عنوانٌ خاطئ واحد البقية.

اجعل التزامن معتدلًا كي لا تُثقل خادم SMTP الخاص بك. مجموعة صغيرة من 5–10 طلبات متوازية تكفي لمعظم التطبيقات.

لا ترسل من مسار الطلب

استدعاء الواجهة سريع، لكنه يظل رحلة ذهاب وإياب عبر الشبكة. لكل ما ليس حرجًا من حيث الوقت، ضع الإرسال في مهمة خلفية (BullMQ أو Celery أو Sidekiq أو طابور سحابي)، كي:

  • تُحمَّل صفحة المستخدم دون انتظار البريد،
  • ويمكن إعادة محاولة الخطأ المؤقت دون أن يلاحظ المستخدم،
  • وتُصرَّف القفزة المفاجئة، كعملية استيراد كبيرة تطلق آلاف رسائل الترحيب، بمعدّل ثابت.

أما رموز OTP وإعادة تعيين كلمة المرور، فالمستخدمون ينتظرونها فعليًا، لذا أرسلها فورًا واعرض رسالة خطأ ودّية إن فشل الإرسال. يشرح دليل معالجة أخطاء واجهة برمجة البريد الإلكتروني وحدودها الأخطاء التي تُعاد محاولتها وتلك التي يجب إظهارها.

قائمة تحقق قبل الإطلاق

  • يأتي مفتاح API من متغيّر بيئة أو مدير أسرار، ولا يملك المفتاح إلا صلاحية Send.
  • كل قيمة يُدخلها المستخدم في HTML مُهرَّبة.
  • للطلبات مهلة زمنية من 10–15 ثانية.
  • تُسجَّل الاستجابات غير 200 مع جسم الاستجابة، كي لا تضيع رسائل error وdetail.
  • نطاق الإرسال لديك مُعدّ بـ SPF وDKIM وDMARC، لتصل الرسائل إلى صندوق الوارد.

أرسلها عبر Inbixio

اربط خادم SMTP الخاص بك، وأنشئ مفتاح API بصلاحيات محدّدة، وأرسل من أي لغة برمجة بطلب HTTPS واحد.

إنشاء حساب عرض الأسعار