كيفية استقبال رسائل نموذج «اتصل بنا» عبر AWS SES وLambda وAPI Gateway
مقدمة: لماذا تحتاج إلى نموذج تواصل احترافي؟
عند إنشاء صفحة هبوط أو موقع تعريفي، غالباً ما تكون هناك حاجة إلى وسيلة تواصل سهلة تسمح للزوار بإرسال رسائلهم دون عرض البريد الإلكتروني بشكل مباشر. يعتمد كثير من المواقع على رابط mailto داخل الخاصية href، لكنه ليس الحل الأمثل من ناحية الخصوصية وتجربة المستخدم.
في هذا الدليل العملي، ستتعرّف على طريقة بناء نموذج اتصل بنا يرسل الرسائل من الموقع مباشرة باستخدام خدمات AWS SES وAWS Lambda وAPI Gateway. هذه البنية تمنحك مرونة كبيرة، وتقلل التكاليف، وتناسب المواقع الثابتة وصفحات الهبوط بشكل ممتاز.

لماذا لا يُعد mailto كافياً؟
الاعتماد على رابط mailto يبدو بسيطاً، لكنه يسبب عدة مشكلات عملية:
- يفرض على الزائر استخدام تطبيق البريد الافتراضي على جهازه.
- قد لا يكون الزائر مسجلاً الدخول إلى بريده الإلكتروني.
- يكشف البريد الإلكتروني للطرفين، وهو أمر غير مناسب لمن يهتمون بالخصوصية.
- يضيف خطوات إضافية قد تدفع المستخدم إلى ترك العملية وعدم إرسال الرسالة.
لهذا السبب، يُعد نموذج التواصل داخل الموقع خياراً أكثر احترافية، لأنه يسمح للمستخدم بكتابة الرسالة وإرسالها دون مغادرة الصفحة.
نظرة عامة على الحل التقني
سنستخدم ثلاث خدمات رئيسية من AWS:
SES: لإرسال رسائل البريد الإلكتروني.Lambda: لتنفيذ الشيفرة الخلفية دون إدارة خادم.API Gateway: لاستقبال طلبHTTPمن المتصفح وتمريره إلى الدالة.

آلية العمل ستكون كالتالي:
- يرسل المتصفح طلب
POSTيحتوي على بيانات النموذج. - يستقبل
API Gatewayالطلب ويتحقق منه. - يستدعي
Lambdaويمرّر البيانات داخلevent.body. - تقوم الدالة بتحويل البيانات وبناء رسالة البريد.
- يُستخدم
AWS SDKلاستدعاء خدمةSES. - ترسل
SESالرسالة إلى المستلم. - يتلقى المتصفح استجابة نجاح أو فشل.
بناء نموذج HTML بسيط للتواصل
سنبدأ بنموذج أساسي لاختبار الوظيفة فقط، دون تنسيق CSS معقد:
<h2>Contact Us</h2>
<form>
<label for="name">Name:</label>
<input name="name" type="text" />
<br /><br />
<label for="email">Email:</label>
<input name="email" type="email" />
<br /><br />
<label for="name">Message:</label>
<textarea name="message"></textarea>
<br /><br />
<input type="submit" />
<div>
<p id="result-text"></p>
</div>
</form>

التقاط بيانات النموذج باستخدام JavaScript
في البداية، يكفي أن نلتقط البيانات ونعرضها في وحدة التحكم console:
const form = document.querySelector('form')
form.addEventListener('submit', event => {
event.preventDefault()
const { name, email, message } = event.target
console.log('Name: ', name.value)
console.log('email: ', email.value)
console.log('Message: ', message.value)
})
بهذا أصبح لدينا نموذج يجمع البيانات من المستخدم. الآن ننتقل إلى إعداد البنية الخلفية التي تستقبل هذه البيانات ثم ترسلها كبريد إلكتروني.
الخطوة الأولى: إعداد خدمة AWS SES
خدمة Simple Email Service أو SES مسؤولة عن إرسال البريد الإلكتروني. قبل استخدامها، يجب التحقق من عنوان البريد الذي سيظهر كمرسل.
من لوحة تحكم AWS:
- انتقل إلى خدمة
SES. - اختر
Email Addressesمن القائمة الجانبية. - اضغط على
Verify a New Email Address.

أدخل عنوان البريد الذي تريد استخدامه كمرسل:

سترسل AWS رسالة تحقق إلى هذا البريد. بعد النقر على الرابط الموجود داخل الرسالة، تتغير الحالة من pending إلى verified.


يمكنك أيضاً تجربة إرسال رسالة اختبارية من داخل لوحة SES للتأكد من أن الإعداد يعمل كما ينبغي.

الخطوة الثانية: إعداد AWS Lambda
الآن سننشئ دالة خلفية تستقبل بيانات النموذج وتستخدم SES لإرسال البريد. ميزة Lambda أنها تعمل بدون الحاجة إلى إدارة خادم تقليدي، كما أن التكلفة تُحتسب بناءً على عدد مرات التنفيذ ومدة التشغيل فقط.
إنشاء سياسة صلاحيات IAM Policy
قبل كتابة الشيفرة، نحتاج إلى منح الدالة صلاحية استخدام SES. يتم ذلك عبر إنشاء سياسة IAM مخصصة.


في تبويب JSON الصق الصلاحيات التالية:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail"
],
"Resource": "*"
}
]
}
بعد ذلك، امنح السياسة اسماً مناسباً ثم أنشئها.

إنشاء دور IAM Role وربطه بالدالة
بعد إنشاء السياسة، أنشئ دوراً جديداً من نوع Lambda ثم اربطه بالسياسة السابقة:




بعدها، انتقل إلى خدمة Lambda وأنشئ دالة جديدة:

اختر:
Author from scratch- بيئة تشغيل
Node.js - الخيار
Use an existing role - الدور الذي أنشأته في الخطوة السابقة
كتابة الشيفرة الأولية للدالة
افتح الملف index.js داخل المحرر واستبدل محتواه بالشيفرة التالية:
const aws = require("aws-sdk");
const ses = new aws.SES({ region: "us-east-1" });
exports.handler = async function (event) {
console.log('EVENT: ', event)
const params = {
Destination: {
ToAddresses: ["your@email.com"],
},
Message: {
Body: {
Text: {
Data: `Hello from Lambda!`
},
},
Subject: {
Data: `Message from AWS Lambda`
},
},
Source: "your@email.com",
};
return ses.sendEmail(params).promise()
};
تأكد من تعديل عنوان البريد والمنطقة region بما يتوافق مع المنطقة التي فعّلت فيها SES، مثل us-east-1.
اختبار الدالة
بعد الضغط على Deploy، أنشئ حدث اختبار من خلال زر Test واستخدم بيانات تجريبية مثل:
{
"body": {
"senderName": "Namo",
"senderEmail": "namo@trains.com",
"message": "I love trains!"
}
}
عند التشغيل، ستظهر السجلات داخل تبويب التنفيذ، ويمكنك التأكد من وصول البريد إلى صندوق الوارد.


تطوير الدالة لقراءة بيانات النموذج
بدلاً من إرسال رسالة ثابتة، سنقرأ بيانات المرسل من event.body ونبني الرسالة ديناميكياً:
const aws = require("aws-sdk");
const ses = new aws.SES({ region: "us-east-1" });
exports.handler = async function (event) {
console.log('EVENT: ', event)
const { senderEmail, senderName, message } = JSON.parse(event.body)
const params = {
Destination: {
ToAddresses: ["the.benhawy@gmail.com"],
},
Message: {
Body: {
Text: {
Data: `You just got a message from ${senderName} - ${senderEmail} : ${message}`
},
},
Subject: {
Data: `Message from ${senderName}`
},
},
Source: "the.benhawy@gmail.com",
};
return ses.sendEmail(params).promise();
};
لاحظ أننا استخدمنا JSON.parse() لأن API Gateway يمرّر الجسم body كنص، وليس ككائن JSON مباشر. لذلك لا بد من تحويله قبل استخراج القيم.
الخطوة الثالثة: إعداد API Gateway
الآن نحتاج إلى نقطة وصول HTTP يستطيع المتصفح إرسال الطلب إليها.

من صفحة الدالة داخل Lambda:
- افتح قسم
Function overview. - اضغط
Add trigger. - اختر
API Gateway. - اختر
HTTP API. - اجعل الوصول
Open. - فعّل خيار
CORS.


بعد الحفظ، ستظهر لك API endpoint. هذا هو الرابط الذي سيرسل إليه المتصفح بيانات النموذج.
ربط النموذج بالواجهة الخلفية
بعد تجهيز SES وLambda وAPI Gateway، أصبح بإمكاننا تعديل JavaScript في الواجهة الأمامية لإرسال الطلب الحقيقي:
const form = document.querySelector("form");
form.addEventListener("submit", (event) => {
event.preventDefault();
const { name, email, message } = event.target;
const endpoint = "https://5ntvcwwmec.execute-api.us-east-1.amazonaws.com/default/sendContactEmail";
const body = JSON.stringify({
senderName: name.value,
senderEmail: email.value,
message: message.value
});
const requestOptions = {
method: "POST",
body
};
fetch(endpoint, requestOptions)
.then((response) => {
if (!response.ok) throw new Error("Error in fetch");
return response.json();
})
.then(() => {
document.getElementById("result-text").innerText = "Email sent successfully!";
})
.catch(() => {
document.getElementById("result-text").innerText = "An unkown error occured.";
});
});
في هذا الجزء:
- نستخدم
event.preventDefault()لمنع إعادة تحميل الصفحة. - نحوّل البيانات إلى نص عبر
JSON.stringify(). - نرسل الطلب باستخدام
fetch(). - نعرض رسالة نجاح أو خطأ للمستخدم.


مزايا هذا الأسلوب مقارنة بالأدوات الجاهزة
بدلاً من الاعتماد على إضافات خارجية أو خدمات مدفوعة تحمل علامتها التجارية، يمنحك هذا الحل مزايا مهمة:
- تحكم كامل في الشيفرة وسير العمل.
- تكلفة منخفضة جداً عند الاستخدام المحدود.
- ملاءمة ممتازة للمواقع الثابتة وصفحات الهبوط.
- إمكانية التوسع لاحقاً بإضافة التحقق، الحماية من الرسائل المزعجة، أو التخزين.
- تحسين تجربة المستخدم بإرسال الرسالة دون مغادرة الموقع.
نصائح تقنية لتحسين الجودة والأمان
إذا كنت تنوي استخدام هذا الحل في مشروع إنتاجي فعلي، فمن الأفضل إضافة بعض التحسينات:
- التحقق من صحة المدخلات في الواجهة الأمامية والخلفية.
- استخدام
CAPTCHAأو آلية منع الرسائل الآلية. - إضافة ترويسات
Content-Typeبشكل صريح. - تقييد
CORSعلى نطاق موقعك فقط بدلاً من الإعداد المفتوح. - تسجيل الأخطاء في
CloudWatchلمتابعة الأعطال بسرعة. - فصل بريد المرسل عن بريد الاستقبال إذا كانت سياسة المشروع تتطلب ذلك.
متى يكون هذا الحل مناسباً؟
هذا الأسلوب مناسب بشكل خاص في الحالات التالية:
- صفحات الهبوط الخاصة بالشركات الناشئة.
- المواقع التعريفية الشخصية أو التجارية.
- المشاريع التي تعتمد على واجهات أمامية ثابتة.
- الحلول التي تتطلب تقليل التكاليف التشغيلية.
الخلاصة التقنية
الاعتماد على AWS SES مع Lambda وAPI Gateway يوفّر طريقة ذكية وعملية لبناء نموذج اتصل بنا دون خادم تقليدي ودون كشف البريد الإلكتروني للعلن. من الناحية التقنية، هذا الحل ممتاز للمشاريع الخفيفة والمتوسطة، ويتميز بسهولة التوسع وقلة التكلفة. وإذا أضفت إليه التحقق الأمني وتحسينات تجربة المستخدم، فستحصل على نظام مراسلة احترافي مناسب للنشر الفعلي ومتوافق مع متطلبات الجودة التي تهم المستخدم ومحركات البحث معاً.