کنترل ریکوئست‌های تگرام به سرور هوک

تصویر منتشر شده برای جایزه بزرگ بات‌های تلگرام سال ۲۰۱۷
تصویر منتشر شده برای جایزه بزرگ بات‌های تلگرام سال ۲۰۱۷

شروع

تلگرام در آگوست ۲۰۱۳، حدود ۴ سال پیش نسخه اولیه خودش را منتشر کرد، از همان روزهای ابتدایی سامان سلطانی، جواد عوض زاده کاکرودی و من به دلیل محدودیت‌هایی که دیگر پیام‌رسان‌ها در پلتفرم‌های خود داشتند، برای یک رابطه کاری وارد تلگرام شدیم؛ در آن روزهای ابتدایی هنوز کاربران ایرانی از این پیام‌رسان خارق‌العاده و آینده روشن، رو به رشد و قدرمتندش خبر نداشتند.

تلگرام از همان ابتدا اول با کاربران عادی رفیق شد، بعد با توسعه‌دهنده‌های نرم افزاری و بعد در آپدیت ۲۴ ژوئن ۲۰۱۵ از نسخه اولیه ربات خود به اسم «بات» رونمایی کرد؛ سیاست تلگرام از همان اول با این دانش که «انحصارطلبی نه تنها مفید نیست، بلکه انزوا آور است» با توسعه‌دهندگان رابطه خوبی برقرار کرد و سیاست‌های مدون و برنامه‌ریزی شده‌ای نسبت به این عملکرد داشت، تا جایی که اگر خط زمان بروزرسانی‌های تلگرام را دنبال کنیم به این نتیجه می‌رسیم که تلگرام یک پلتفرم جدید بر بستر وبِ بدون مرورگر می‌باشد، یعنی قرار است که کاربران در آینده‌ای نه چندان دور، در تلگرام همان‌گونه که در مرورگر وب‌گردی می‌کردند، وب‌گردی کنند، خرید کنند، بازی کنند و حتی پورتال کاری خود را در تگلرام داشته باشند...

اصل مطلب

توسعه‌دهنده
توسعه‌دهنده

طبق وظیفه کاری که در ارمایل داشتم، موظف شدم بات تلگرامی سرشمار را طرح ریزی و اجرا کنم، که در روزهای اول فروردین سال ۱۳۹۶ رونمایی شد.(بنا به دلایلی این بات موقتا غیر فعال است)

در همان شب اول تاحدی استقبال زیاد بود که سرورهای قدرتمند شرکت جواب‌گو نبود و مجبور شدیم سرور مجازی خودمان که بر روی سرویس‌دهنده دیجیتال‌اوشن بود را به آخرین پلن تغییر دهیم. اما باز کاربران ما با مشکل مواجه بودند؛ مشکل آن‌جایی بود که تلگرام نهایتا ۱۰۰ ریکوئست به سرور ارسال می‌کرد و بعد از پاسخ‌دادن سرور، ریکوئست‌های بعدی را می‌فرستاد، که حدود ۸۰۰۰ ریکوئست در صف تلگرام داشتیم.

از یک طرف ماه‌ها زمان صرف طراحی بات شده بود و از طرف دیگر PHP قادر نبود که در زمان کوتاه به ما کمک کند تا این مشکل را برطرف کنیم. در همان لحظه فکری به سرمان زد که سرور دریافت کننده ریکوئست‌ها را از apache/PHP به Node.js تغییر دهیم. وظیفه Node.js این بود که ریکوئست‌های ارسالی از طرف تلگرام را دریافت کرده، در همان خط اولیه ریکوئست، ارتباط را برای تلگرام تمام شده در نظر می‌گرفت و خودش شروع به صف بندی و ارسال منظم ریکوئست‌ها به سرور apache/PHP می‌کرد، این کار باعث شد در روزهای بعدی که حتی درخواست‌های زیادتری نسبت به روز اول به سرور ارسال می‌شد نه تنها مشکلی با تلگرام نداشته باشیم، بلگه منابع استفاده کننده سرور را کاهش دهیم و با سرعت باورنکردنی به درخواست کاربران پاسخ دهیم، در زیر نمونه کد ساده‌ای که آن‌شب کار کردیم را مشاهده می‌کنید:

const requestService = (request, response) => {
	response.end("We get it!\nGo and drink coffee:))")
	if (request.method == 'POST') {
		let body = '';
		request.on('data', (data) => {
			body += data;
		})
		request.on('end', () => {
			try {
				let data = JSON.parse(body)
				new queue(data)
			} catch (e) {
				console.error("JSON PARSE");
				console.log(e)
			}
		})
	}
}

در این کد، همانگونه که می‌بینید، در خط دوم یا همان خط اول درخواست، پاسخ کلاینت را تمام می‌کنیم و از خط سوم به بعد خودمان شروع به صف‌بندی و پاسخ‌دهی می‌کنیم.

باید توجه داشته باشید پاسخ‌ها در صفی قرار گیرند که همگام‌شده/سینک‌شده باشند تا مثلا کاربری که به بات دو پیام مجزای «سلام» «چه‌خبر» می‌فرستند، پاسخ جواب «سلام» قبل از جواب «چه‌خبر» ارسال شود.
در روزهای اخیر فرصد شد و یک پروژه متن باز برای کنترل بات‌های تلگرام در گیت‌هاب و npmjs به زبان Node.js منتشر کردم که از همین منطق و معماری استفاده می‌کند و قصد دارم با کمک دوستان به توسعه بهتر آن ادامه دهم.
اگر احساس می‌کنید می‌توانید به ما کمک کنید، می‌توانید به ما خبر دهید و ما را خوشحال کنید :))