كيفية بناء بوت دردشة Rocket.Chat باستخدام TypeScript
إذا كنت تريد إنشاء بوت مخصص لخادم Rocket.Chat لإدارة المحادثات أو تنفيذ أوامر تلقائية، فهذا الدليل العملي يشرح لك الخطوات كاملة بدءاً من تشغيل الخادم محلياً، مروراً بإنشاء حساب للبوت، وصولاً إلى كتابة الكود باستخدام TypeScript وبناء نظام أوامر قابل للتوسع.
الهدف هنا ليس مجرد تشغيل مثال بسيط، بل إنشاء أساس تقني منظم يمكنك الاعتماد عليه لاحقاً في مشاريع أكبر أو في بيئة إنتاج فعلية.
إعداد خادم Rocket.Chat محلياً
قبل كتابة البوت، تحتاج أولاً إلى تشغيل نسخة محلية من Rocket.Chat حتى تتمكن من اختبار الوظائف دون التأثير على أي بيئة حية. أسهل طريقة هي استخدام Docker مع إعداد جاهز يتولى تشغيل كل من Rocket.Chat وMongoDB معاً.
إذا لم يكن Docker مثبتاً لديك، فقم بتثبيته أولاً بحسب نظام التشغيل الذي تستخدمه. في بعض الأجهزة، قد تحتاج أيضاً إلى تفعيل hardware virtualization من إعدادات BIOS.
إنشاء ملف .env للخادم المحلي
داخل مجلد مشروع Rocket.Chat، أنشئ ملفاً باسم .env ثم أضف القيم التالية:
COMPOSE_FILE=docker-compose.dev.yml
PORT=3000
ROOT_URL=http://localhost:3000
ROCKETCHAT_VERSION=latest
تشغيل الحاويات عبر docker-compose
بعد ذلك افتح الطرفية داخل نفس المجلد ونفّذ الأمر التالي:
docker-compose up -d
عند نجاح التشغيل، من المفترض أن تظهر رسائل تؤكد إنشاء الحاويات المطلوبة.

الآن افتح المتصفح وانتقل إلى localhost:3000. ستظهر لك واجهة الإعداد الأولى الخاصة بمنصة Rocket.Chat.
إكمال معالج الإعداد الأولي
أول شاشة ستعرض عليك إنشاء حساب المدير Admin. هذا الحساب يمنحك صلاحيات كاملة لإدارة الخادم وإعداد المستخدمين والقنوات.

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

في الخطوة الأخيرة يمكنك تجاهل خدمات التسجيل المدفوعة واختيار الوضع المستقل Keep standalone. بعد إنهاء المعالج ستصبح مساحة العمل جاهزة، وستجد القناة الافتراضية general قد أُنشئت تلقائياً.

إنشاء حساب بوت داخل Rocket.Chat
بعد تشغيل الخادم، تحتاج إلى إنشاء مستخدم مخصص للبوت حتى يتمكن الكود من تسجيل الدخول والتفاعل مع الرسائل.
من القائمة الجانبية، افتح Administration ثم انتقل إلى Users واضغط على +New لإنشاء مستخدم جديد.
أثناء إدخال بيانات الحساب، راعِ النقاط التالية:
- أوقف خيار
Require password change. - أوقف خيار
Set random password and send by email. - أوقف خيار
Send welcome email. - اختر الدور
botمن قائمةRoles.

بعد الحفظ، دوّن اسم المستخدم وكلمة المرور، لأنك ستحتاج إليهما داخل ملف الإعدادات الخاص بالمشروع.
تهيئة مشروع البوت باستخدام TypeScript
أنشئ مجلداً جديداً وفارغاً لمشروع البوت. بعدها ابدأ بتهيئة مشروع Node.js، سواء باستخدام npm init أو عبر إنشاء ملف package.json يدوياً.
إضافة أوامر التشغيل في package.json
داخل قسم scripts أضف القيم التالية:
"scripts": {
"prebuild": "rm -rf ./prod",
"build": "tsc",
"start": "node ./prod/bot.js"
}
تثبيت الاعتمادات المطلوبة
ثبّت أولاً حزم التطوير:
npm install --save-dev typescript @types/node
ثم ثبّت الحزم الأساسية للمشروع:
npm install @rocket.chat/sdk dotenv
إعداد ملف tsconfig.json
إذا كان TypeScript مثبتاً لديك بشكل عام، يمكنك توليد الملف باستخدام tsc --init. وإلا فأنشئ الملف يدوياً داخل جذر المشروع، ثم استخدم الإعداد التالي:
{
"compilerOptions": {
"target": "ES5",
"module": "CommonJS",
"rootDir": "./src",
"outDir": "./prod",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"noImplicitAny": false
}
}
إعداد ملف .gitignore
إذا كنت تستخدم git، فاحرص على تجاهل الملفات والمجلدات التي لا يجب رفعها إلى المستودع، مثل الوحدات المثبتة والملفات المترجمة والبيانات السرية:
/node_modules/
/prod/
.env
حفظ بيانات الاتصال في .env
أنشئ الآن ملف .env داخل مشروع البوت، وأضف القيم التالية مع استبدال بيانات الاعتماد بما يناسبك:
ROCKETCHAT_URL="localhost:3000"
ROCKETCHAT_USER="tutorial-bot"
ROCKETCHAT_PASSWORD="********"
ROCKETCHAT_USE_SSL=""
كتابة الكود الأساسي لبوت Rocket.Chat
داخل المشروع، أنشئ مجلداً باسم src ثم ملفاً باسم bot.ts. سيكون هذا الملف هو نقطة الدخول الرئيسية لتشغيل البوت.

الاستيراد وتهيئة المتغيرات البيئية
import { api, driver } from "@rocket.chat/sdk";
import dotenv from "dotenv";
لأن Node.js لا يحمّل متغيرات البيئة تلقائياً، يجب تفعيلها عبر dotenv:
dotenv.config();
ثم اسحب القيم المطلوبة من process.env:
const {
ROCKETCHAT_URL,
ROCKETCHAT_USER,
ROCKETCHAT_PASSWORD,
ROCKETCHAT_USE_SSL,
} = process.env;
التحقق من القيم الأساسية
من الأفضل التحقق مبكراً من وجود المتغيرات المهمة حتى لا يفشل التطبيق لاحقاً بشكل مبهم:
if (!ROCKETCHAT_URL || !ROCKETCHAT_USER || !ROCKETCHAT_PASSWORD) {
console.error("Missing required environment variables.");
process.exit(1);
}
إنشاء الدالة الرئيسية غير المتزامنة
بما أن الاتصال بالخادم وتسجيل الدخول يتطلبان استخدام async/await، فيمكنك الاستفادة من تعبير التنفيذ الفوري IIFE:
(async () => {
// سيتم وضع منطق التشغيل هنا
})();
الاتصال بالخادم وتسجيل الدخول
داخل هذه الدالة، حدّد أولاً ما إذا كان الاتصال سيستخدم SSL:
const ssl = !!ROCKETCHAT_USE_SSL;
ثم اتصل بالخادم وسجّل الدخول باستخدام حساب البوت:
await driver.connect({ host: ROCKETCHAT_URL, useSsl: ssl });
await driver.login({
username: ROCKETCHAT_USER,
password: ROCKETCHAT_PASSWORD,
});
await api.login({
username: ROCKETCHAT_USER,
password: ROCKETCHAT_PASSWORD,
});
الانضمام إلى الغرفة والاشتراك في الرسائل
بعد نجاح الاتصال، اجعل البوت ينضم إلى قناة general ويبدأ الاستماع إلى الرسائل:
await driver.joinRooms(["general"]);
await driver.subscribeToMessages();
وللتأكد من أن البوت يعمل فعلاً، أرسل رسالة تأكيد عند بدء التشغيل:
await driver.sendToRoom("I am alive!", "general");
بناء المشروع وتشغيله
شغّل الأوامر التالية من الطرفية:
npm run build
npm run start
إذا سار كل شيء كما يجب، سترى رسالة البوت داخل الغرفة.

بناء نظام لمعالجة الأوامر
حتى الآن، البوت متصل بالخادم ويستمع للرسائل، لكنه لا يعرف كيف يتعامل معها. لذلك سنضيف طبقة منظمة لمعالجة الأوامر.
ربط الاستجابة للرسائل
بعد سطر subscribeToMessages() أضف السطر التالي:
driver.reactToMessages();
لكن هذه الدالة تحتاج إلى callback، والأفضل هنا هو فصل منطق المعالجة في ملف مستقل لسهولة التوسعة والصيانة.
إنشاء ملفات الأوامر
داخل src أنشئ مجلداً باسم commands، ثم أضف ملفين:
CommandHandler.tsCommandList.ts
في ملف CommandList.ts ابدأ بهذا السطر البسيط:
export const CommandList = [];
كتابة معالج الأوامر
داخل ملف CommandHandler.ts أضف الواردات التالية:
import { driver } from "@rocket.chat/sdk";
import { IMessage } from "@rocket.chat/sdk/dist/config/messageInterfaces";
import { CommandList } from "./CommandList";
ثم عرّف الدالة المسؤولة عن تحليل الرسائل:
export const CommandHandler = async (
err: unknown,
messages: IMessage[]
): Promise<void> => {
// المنطق هنا
};
إضافة التحقق الأساسي من الرسائل
if (err) {
console.error(err);
return;
}
const message = messages[0];
if (!message.msg || !message.rid) {
return;
}
هذا الجزء يمنع استمرار التنفيذ إذا حدث خطأ، كما يتحقق من وجود نص الرسالة ومعرّف الغرفة.
تحليل الأمر والبادئة
const roomName = await driver.getRoomName(message.rid);
const [prefix, commandName] = message.msg.split(" ");
هنا يتم استخراج اسم الغرفة، ثم تقسيم الرسالة إلى جزأين: بادئة الأمر واسم الأمر نفسه. على سبيل المثال، في الرسالة !fCC ping ستكون البادئة !fCC والأمر ping.
التنقل بين الأوامر المتاحة
if (prefix === "!fCC") {
for (const Command of CommandList) {
if (commandName === Command.name) {
await Command.command(message, roomName);
return;
}
}
await driver.sendToRoom(
`I am sorry, but \`${commandName}\` is not a valid command.`,
roomName
);
}
المنطق هنا بسيط وفعال:
- إذا لم تبدأ الرسالة بالبادئة الصحيحة، يتجاهلها البوت.
- إذا وُجدت البادئة، يبحث البوت عن الأمر داخل قائمة الأوامر.
- إذا عثر عليه، يشغّل الدالة الخاصة به.
- إذا لم يعثر عليه، يرسل رسالة توضيحية للمستخدم.
ربط المعالج بالملف الرئيسي
عد الآن إلى ملف bot.ts وأضف الاستيراد التالي:
import { CommandHandler } from "./commands/CommandHandler";
ثم مرّر المعالج إلى الدالة:
driver.reactToMessages(CommandHandler);
تعريف بنية الأوامر باستخدام interface
من مزايا TypeScript أنك تستطيع فرض شكل موحّد لكل أمر داخل البوت. هذا يجعل الكود أكثر وضوحاً ويمنع الأخطاء الناتجة عن إضافة أوامر ناقصة البنية.
داخل مجلد src أنشئ مجلداً باسم interfaces ثم ملفاً باسم CommandInt.ts.
أضف إليه التعريف التالي:
import { IMessage } from "@rocket.chat/sdk/dist/config/messageInterfaces";
export interface CommandInt {
name: string;
description: string;
command: (message: IMessage, room: string) => Promise<void>;
}
إنشاء أول أمر: ping
الآن أصبح كل شيء جاهزاً لإضافة أول أمر فعلي للبوت.
داخل المجلد src/commands أنشئ ملفاً باسم ping.ts ثم أضف الكود التالي:
import { driver } from "@rocket.chat/sdk";
import { CommandInt } from "../interfaces/CommandInt";
export const ping: CommandInt = {
name: "ping",
description: "Pings the bot.",
command: async (message, room) => {
await driver.sendToRoom("Pong!", room);
}
};
هذه البنية تعني أن الأمر اسمه ping، وعند استدعائه يرسل البوت الرد Pong!.
إضافة الأمر إلى القائمة
افتح ملف CommandList.ts وعدّله ليصبح بالشكل التالي:
import { CommandInt } from "../interfaces/CommandInt";
import { ping } from "./ping";
export const CommandList: CommandInt[] = [ping];
إضافة النوع CommandInt[] تمنحك مستوى إضافياً من الأمان، لأن TypeScript سيتحقق من أن جميع العناصر داخل القائمة تتبع البنية المطلوبة فعلاً.
اختبار البوت والأوامر
أعد بناء المشروع ثم شغّله من جديد:
npm run build
npm run start
بعد ذلك، افتح غرفة المحادثة وأرسل الأمر التالي:
!fCC ping
إذا كان كل شيء مضبوطاً، فسيظهر رد البوت مباشرة:

أما إذا أرسلت أمراً غير موجود مثل:
!fCC pong
فسيخبرك البوت أن الأمر غير صالح:

أفضل ممارسات لتطوير بوت قابل للتوسع
بعد نجاح النسخة الأولية، من المفيد اعتماد بعض الممارسات التي تجعل مشروعك أكثر احترافية:
- افصل كل أمر في ملف مستقل ليسهل اختباره وتطويره.
- استخدم متغيرات البيئة لكل البيانات الحساسة مثل كلمات المرور وروابط الخوادم.
- أضف سجلات
loggingواضحة لتتبّع الأخطاء وسلوك البوت. - تحقق من صلاحيات المستخدم قبل تنفيذ الأوامر الإدارية.
- فكّر في إضافة أوامر مساعدة مثل
helpوaboutلتحسين تجربة الاستخدام.
أفكار لتطوير البوت لاحقاً
بعد بناء الهيكل الأساسي، يمكنك التوسع في العديد من الاتجاهات:
- إضافة أوامر إدارة للمشرفين.
- إنشاء أوامر تربط البوت بواجهات
APIخارجية. - تنفيذ نظام ردود تلقائية للكلمات المفتاحية.
- إضافة سجل للعقوبات أو التنبيهات داخل المجتمعات الكبيرة.
- ربط البوت بقاعدة بيانات لحفظ الإعدادات وسجل التفاعلات.
الخلاصة التقنية
بناء بوت على منصة Rocket.Chat باستخدام TypeScript يمنحك مزيجاً ممتازاً من المرونة والتنظيم والأمان البرمجي. الفائدة الحقيقية لا تكمن فقط في تشغيل البوت، بل في تصميم بنية أوامر نظيفة وقابلة للتوسع منذ البداية. إذا بدأت بهذا الأساس الصحيح، فسيصبح من السهل لاحقاً تحويل البوت من مشروع تجريبي بسيط إلى أداة عملية تدير مجتمعاً كاملاً بكفاءة.