এক কথায়
এক্সটেনশনটি আসলে একটি টাইমার আর একজন ভদ্র পাহারাদার। টিকিট ছাড়ার ঠিক সেকেন্ড পর্যন্ত অপেক্ষা করে, তারপর টিকিট সাইটকে প্রায় সেকেন্ডে একবার জিজ্ঞেস করে "আমার ট্রেন খুলেছে?" — উত্তর হ্যাঁ হলেই অ্যালার্ম বাজায় আর যে বোতামগুলো চাপতে হবে সেগুলো দেখিয়ে দেয়। নিজে কখনো চাপে না।
এটি মানুষ সাজার চেষ্টা করে না, বট-ধরা ব্যবস্থা থেকে লুকানোরও চেষ্টা করে না। নিরাপদ থাকে কম জিজ্ঞেস করে, অল্প সময়ের জন্য, শুধু দরকারের সময় — আর সাইটের বট-চেক থেকে পুরোপুরি দূরে থেকে।
অংশগুলো
| ফাইল | কোথায় চলে | কাজ |
|---|---|---|
popup.html / popup.js | টুলবারের প্যানেল | ক্যালেন্ডার, রুট/ট্রেন/সিট ফর্ম, ARM, কাউন্টডাউন, সেভ করা ট্রিপ, ইতিহাস, বাংলা/English। |
background.js | সার্ভিস ওয়ার্কার (ব্যাকগ্রাউন্ড) | ছাড়ার সময় হিসাব, chrome.alarms বসানো (মূল + ১ দিন + ১ ঘণ্টা আগের রিমাইন্ডার), ~৭৫ সেকেন্ড আগে সাইটের ট্যাব খোলা, নোটিফিকেশন, অ্যালার্মের আওয়াজ চালু/বন্ধ। |
content.js | eticket.railway.gov.bd পেজের ভেতরে | পাহারাদার: লগইন দেখা, ঘড়ি মেলানো, ধীরে খোঁজা, স্ট্যাটাস বক্স, BOOK NOW জ্বালানো, সিট দাগানো, সিট সোজা না উল্টো তার অনুমান। |
offscreen.html / offscreen.js | লুকানো এক্সটেনশন পেজ | সাইরেন বাজায় (Web Audio)। |
rail-data.js | সব জায়গায় | স্টেশন, ট্রেনের নাম, আর প্রতিটি ট্রেনের ছাড়ার সময় ও জোন (EAST দুপুর ২টা / WEST সকাল ৮টা)। |
i18n.js | প্যানেল | বাংলা ও ইংরেজি লেখা। |
একটি রানের সময়রেখা
ARM চাপা হলো (প্যানেল)
└─ ব্যাকগ্রাউন্ড: ছাড়ার দিন = যাত্রার তারিখ − ১০ দিন
প্রথম খোঁজ = সেদিন সকাল ৮টা (সাধারণ দিনে সব ট্রেন)
দ্বিতীয় খোঁজ = দুপুর ২টা, শুধু পূর্বাঞ্চলের ট্রেনে (ঈদের সময়ের নিয়ম)
অ্যালার্ম বসায়: T−২৪ঘ (রিমাইন্ডার) · T−১ঘ (রিমাইন্ডার) · T−৭৫সে (শুরু), T = প্রথম খোঁজ
প্রথম খোঁজ শুরু → দ্বিতীয়টার অ্যালার্ম বসে; সিট পেলে → দ্বিতীয়টা বাতিল
T−৭৫সে ব্যাকগ্রাউন্ড eticket.railway.gov.bd ট্যাব খোলে (বা আগেরটা নেয়), একটি "mission" সেভ করে
content.js mission দেখে:
১. লগইন আছে? না → অ্যালার্ম + নোটিফিকেশন, থামো
২. এই রানের সময়ের মধ্যে তারিখ ছাড়বে? না → থামো (অকারণে খুঁজবে না)
৩. একটি ছোট ফাইলের জন্য একটি রিকোয়েস্ট → সার্ভারের Date হেডার থেকে
ঘড়ির পার্থক্য বের করে (প্রায় ±০.৫ সেকেন্ড)
T−০.৫সে খোঁজা শুরু: GET /bookings/search-trips-v2 (সাইটের Search বোতাম যে কল করে, সেটাই)
প্রতিবারের মাঝে ৭০০ মিলিসেকেন্ড + এলোমেলো ০–২৫০ মিলিসেকেন্ড (≈ সেকেন্ডে ১বার)
429 "খুব ঘন ঘন" → ২, ৪, ৮, ১৫ সেকেন্ড অপেক্ষা …
401 "লগআউট" → অ্যালার্ম + নোটিফিকেশন, থামো
৫ মিনিট শেষ → হাল ছাড়ো, জানাও
সিট! ছোট একটা "পাওয়া গেছে" নোট সেভ, নোটিফিকেশন,
ওই ট্রেন আর ক্লাসের জন্য সাইটের নিজের রেজাল্ট পেজ খোলা
রিলোড content.js নোট দেখে → অ্যালার্ম চালু, ট্রেনে স্ক্রল, BOOK NOW জ্বালানো
আপনি BOOK NOW চাপেন → সাইট সিট-ম্যাপ আনে (আর নিজের বট-চেক চালায় — এক্সটেনশন ছোঁয় না)
content.js পেজের পরিবর্তন দেখে (MutationObserver) → সেরা খালি সিট দাগায়
আর প্রতিটি সিট কোন দিকে মুখ করা তা অনুমান করে (⬆ / ⬇ / ⬆→⬇)
← এই ধাপে এক্সটেনশন কোনো নেটওয়ার্ক রিকোয়েস্ট করে না
আপনি সিট চাপেন → CONTINUE PURCHASE → OTP → পেমেন্ট
লগইন কোথা থেকে আসে
আপনি সাইটে স্বাভাবিকভাবে লগইন করেন। সাইট আপনার সেশন পেজের localStorage-এ রাখে
(একটি টোকেন আর একটি ডিভাইস আইডি ও কী)। পাহারাদার সেগুলো পড়ে, আর সাইট নিজে যে হেডার ব্যবহার করে
(Authorization, X-Device-Id, X-Device-Key) সেভাবেই খোঁজার সাথে পাঠায়।
এগুলো শুধু রেলের নিজের টিকিট সার্ভারে যায় (eticket.railway.gov.bd যেটা ব্যবহার করে) — এক্সটেনশন জমিয়ে রাখে না, অন্য কোথাও পাঠায় না।
আপনার পাসওয়ার্ড কখনো দেখে না।
অ্যালার্ম কেন লুকানো পেজ থেকে বাজে
আপনি ক্লিক না করা পর্যন্ত ব্রাউজার কোনো পেজকে আওয়াজ করতে দেয় না ("autoplay policy")। টিকিট ছাড়ার সময়ের ট্যাবটা নিজে থেকে খোলা, তাই সেটা আওয়াজ করতে পারে না। এক্সটেনশন একটি offscreen পেজ থেকে আওয়াজ বাজাতে পারে, তাই সাইরেন সেখানে বাজে। টুলস → অ্যালার্ম শুনে দেখুন-ও একই পথে বাজে, তাই পরীক্ষাটা সত্যিকারের।
"এটি কি মানুষের মতো আচরণ করে?" — সত্যি বললে, না
এখানে পরিষ্কার থাকা দরকার, কারণ "মানুষ সাজা" বলতে সাধারণত বট-ধরা ব্যবস্থাকে ধোঁকা দেওয়ার কৌশল বোঝায়। এই এক্সটেনশন ইচ্ছে করেই সেসব করে না।
যা করে
- সাইটের Search বোতাম যে একই খোঁজার কল করে, সেটাই করে — সাইটের নিজের ট্যাব থেকে, আপনার নিজের সেশনে।
- প্রায় সেকেন্ডে একবার খোঁজে — অনেকটা কেউ বারবার রিফ্রেশ চাপার মতো — মাঝে সামান্য এলোমেলো বিরতি (০–২৫০ মিলিসেকেন্ড), যাতে একদম ঘড়ির কাঁটার মতো না হয়।
- শুধু ছাড়ার মুহূর্তে অল্প সময় (বড়জোর কয়েক মিনিট) চলে।
যা করে না
- নকল মাউস নাড়া, নকল টাইপ, ব্রাউজারের পরিচয় (fingerprint/user-agent) বদলানো — কিছুই না।
- বাড়তি অ্যাকাউন্ট, প্রক্সি বা আইপি বদলানো — না।
- সাইটের বট-চেক (Cloudflare Turnstile) সমাধান, এড়ানো, তৈরি বা পুনরায় ব্যবহার — না।
- নিজে লগইন, OTP দেওয়া, সিট আটকানো বা পেমেন্ট — না।
ব্লক এড়াতে এটি কী করে
| ব্যবস্থা | কেন | কোথায় |
|---|---|---|
| ছাড়ার আগে শুরুই করে না | এই রানের সময়ের মধ্যে তারিখ না ছাড়লে খোঁজা অর্থহীন, শুধু রিকোয়েস্ট বাড়ে। বার্তা দিয়ে থেমে যায়। | content.js · runEngine() |
| সার্ভারের ঘড়িতে ছাড়ার ০.৫ সেকেন্ড আগে শুরু | "যদি লাগে" ভেবে আগে খোঁজে না। ঘড়ির পার্থক্য একটি HTTP Date হেডার থেকে। | serverOffsetMs(), startLeadMs |
| সেকেন্ডে ≈ ১বার খোঁজা | ৭০০ মিলিসেকেন্ড + ০–২৫০ এলোমেলো, সাথে রিকোয়েস্টের সময়। বদলানো যায় (কমপক্ষে ৩০০) — কমাবেন না। | pollIntervalMs |
| 429 পেলে পিছিয়ে যায় | সার্ভার "খুব ঘন ঘন" বললে ২ → ৪ → ৮ → ১৫ সেকেন্ড অপেক্ষা। | খোঁজার লুপ |
| প্রথম সিট পেলেই থামে | আপনার ক্লাসে অনলাইন সিট দেখা মাত্র খোঁজা বন্ধ। | খোঁজার লুপ |
| কঠিন সময়সীমা | ৫ মিনিট পর হাল ছাড়ে (সর্বোচ্চ ১৫)। সবচেয়ে খারাপ ক্ষেত্রে ≈ ৩০০ বার খোঁজা। | maxWaitMinutes |
| 401 পেলে থামে | লগআউট হওয়া সেশনে আবার চেষ্টা করে না। | খোঁজার লুপ |
| সিট দাগানো অফলাইন | আগে থেকে লোড হওয়া পেজটাই পড়ে। বগি বদলালেও কোনো রিকোয়েস্ট নেই। সিট সোজা না উল্টো, তা রুট আর ম্যাপ থেকেই বের করে, কিছু খোঁজে না। | suggestSeats() |
| বট-চেকে কখনো হাত দেয় না | সিট-ম্যাপের রিকোয়েস্টে Turnstile টোকেন লাগে। এক্সটেনশন সেটা কখনো কল করে না — সিট-ম্যাপ খোলে আপনার ক্লিকে। | — |
| সব জায়গায় থামানোর বোতাম | প্যানেল আর পেজের স্ট্যাটাস বক্স — দুটোই সাথে সাথে থামায়। | stopRun |
আপনার দিক থেকে: যে তারিখ ছাড়েনি সেটায় বারবার টেস্ট নয়, এক ট্রিপে দুই কম্পিউটারে ARM নয়, আর রানের সময় অনেকগুলো টিকিট সাইটের ট্যাব খোলা নয়।
সীমাবদ্ধতা
- অ্যালার্মের পরে গতি আপনার হাতে। BOOK NOW → সিট-ম্যাপ → সিট → CONTINUE → OTP → পেমেন্ট সব আপনি করেন। এক্সটেনশন শুধু খেয়াল করা আর ট্রেন খোঁজার সেকেন্ডগুলো বাঁচায়। আপনি চাপতে চাপতে সিট চলে যেতে পারে।
- অফিসিয়াল নয় এমন সাইটের ওপর নির্ভর। খোঁজার উত্তরের গঠন আর পেজের CSS ক্লাস
(
.book-now-btn,.btn-seat,seat-available…) যেকোনো সময় বদলাতে পারে। বদলালে জ্বলে ওঠা বা সিট দাগানো চুপচাপ কাজ করা বন্ধ করবে। গুরুত্বপূর্ণ যাত্রার আগে একবার এখনই টেস্ট করুন। - টিকিট ছাড়ার সময় রেলের নিয়মে চলে, যা বদলাতে পারে। সাধারণ দিনে সব ট্রেন সকাল ৮টায়। ঈদে পশ্চিমাঞ্চল সকাল ৮টা, পূর্বাঞ্চল দুপুর ২টা
(রেলের নিজের ডেটা
/all-trains/info-এ এই ঈদের ভাগটাই আছে)। রাত ১২টায় শুধু ক্যালেন্ডারে তারিখ আসে (update_counter_on = 00:00:00), ট্রেন থাকে না। জোনের তালিকাrail-data.js-এ — নিয়ম বদলালে আপডেট করুন, অথবা অ্যাডভান্সড-এ একটি নির্দিষ্ট সময় বসান। - কম্পিউটার চালু থাকতে হবে। ল্যাপটপ স্লিপে বা ব্রাউজার বন্ধ থাকলে অ্যালার্ম দেরিতে বাজবে বা বাজবেই না।
- একবার ARM-এ একটি ট্রিপ। একটি রুট, তারিখ আর ট্রেন। খোঁজার সময় প্রথম ক্লাসটা চাওয়া হয়; তালিকার বাকি ক্লাস একই ফলাফল থেকে বাছা হয়।
- শুধু অনলাইন সিট। সাইটের সংখ্যায় কাউন্টার আর অনলাইন কোটা মেশানো থাকে; গোনা হয় শুধু অনলাইন সিট।
- সিট সোজা না উল্টো, তা প্রচলিত নিয়মে অনুমান, আর পরামর্শও এতে ঠিক হয়।
pickByLayout()সম্ভবত-সোজা অর্ধেকের (forwardHalf()) সিটকে অন্য অর্ধেকের মাঝের কাছের সিটের আগে রাখে।facingGuess()বাংলা ভ্রমণ-সাইটগুলোর একমত নিয়ম ব্যবহার করে: ঢাকা থেকে ছাড়লে বড় নম্বরের অর্ধেক (৩১–৬০) সোজা; ঢাকায় গেলে ছোট নম্বরের অর্ধেক (১–৩০)। বগি ভাগ হয় সিট-ম্যাপের মাঝের ফাঁকে (pickByLayout()), নির্দিষ্ট কোনো নম্বরে নয়। কক্সবাজার লাইনের যাত্রায় চট্টগ্রামে উল্টে যায়। ঢাকা থেকে শুরু বা ঢাকায় শেষ নয় এমন রুটে অনুমান দেখায় না। এর পেছনে অফিসিয়াল কিছু নেই, আর বগি উল্টো করে জোড়া হলে ভুল হবে। - সিট দাগানো একবারে একটি বগি দেখে — যেটা স্ক্রিনে আছে। "বেশি খালি বগি"র তথ্য আসে বগির ড্রপডাউন থেকে।
- ঘড়ির নির্ভুলতা প্রায় আধা সেকেন্ড। এই কাজের জন্য যথেষ্ট, তবে মিলিসেকেন্ড-নিখুঁত নয়।
- শুধু কম্পিউটারে। মোবাইল ব্রাউজারে চলে না।
অসুবিধা ও ঝুঁকি
- ব্লক না হওয়ার নিশ্চয়তা নেই। কয়েক মিনিট ধরে সেকেন্ডে একবার খোঁজা বেশিরভাগ মানুষের চেয়ে দ্রুত। রেলের সিস্টেম সীমা কড়া করলে সাময়িক "requesting too frequently" ব্লক হতে পারে। এই পরিমাণে অ্যাকাউন্টের বিরুদ্ধে ব্যবস্থা নেওয়ার সম্ভাবনা কম, তবে কেউ কথা দিতে পারে না।
- এটি চোখে পড়ে। উপরে যেমন বলা হলো, ধরনটা চেনা যায়। রেল এ ধরনের টুল আটকাতে চাইলে এটি কাজ করা বন্ধ করবে — এর বিরুদ্ধে লড়ার কোনো পরিকল্পনা নেই।
- সেশনে প্রবেশাধিকার। সাইট পড়তে পারে এমন যেকোনো এক্সটেনশনের মতো এটিও আপনার লগইন সেশন দেখতে পারে। এটি সেটা শুধু রেলের টিকিট সার্ভারে পাঠায়। কোড ছোট আর খোলা — ইনস্টলের আগে পড়ে দেখুন।
- নিয়ম। টিকিট সাইটের শর্তাবলি নিজে পড়ে নিন। এটি নিজের টিকিট কেনার জন্য, পুনরায় বিক্রির জন্য নয়।
- সবাই ব্যবহার করলে। সবাই চালালে কারো কোনো সুবিধা থাকবে না, সার্ভারও আরো ব্যস্ত হবে। সেজন্যই এক্সটেনশনটি সংযত, আর ভবিষ্যতের ওয়েব স্টোর লিস্টিংও unlisted রাখার পরিকল্পনা।
কোড নিয়ে কাজ
- রিপো ক্লোন করুন। এক্সটেনশন আছে
shohoz-autobook/ফোল্ডারে। brave://extensions→ Developer mode → Load unpacked → ওই ফোল্ডার।- কোড বদলানোর পর এক্সটেনশন কার্ডে ↻ চাপুন আর টিকিট সাইটের ট্যাব রিলোড করুন।
- এখনই কেনা যায় এমন তারিখে ▶ এখনই টেস্ট করুন দিয়ে পরীক্ষা করুন। লগ দেখতে স্ট্যাটাস বক্সের বিস্তারিত ▾ খুলুন।
দরকারি মানগুলো
| সেটিং | ডিফল্ট | কোথায় |
|---|---|---|
| ছাড়ার কত আগে ট্যাব খোলে | ৭৫ সেকেন্ড | background.js-এ PRELAUNCH_LEAD_MS |
| ছাড়ার কত আগে খোঁজা শুরু | ৫০০ মিলিসেকেন্ড | background.js-এর ডিফল্টে startLeadMs |
| দুই খোঁজার মাঝে বিরতি | ৭০০ + ০–২৫০ মিলিসেকেন্ড | pollIntervalMs (প্যানেল → অ্যাডভান্সড) |
| কতক্ষণ পর হাল ছাড়ে | ৫ মিনিট | maxWaitMinutes (প্যানেল → অ্যাডভান্সড) |
| "সিট খুলেছে" অবস্থা কতক্ষণ থাকে | ১৫ মিনিট | content.js-এ ASSIST_TTL_MS |
| বিক্রির সময়সীমা | ১০ দিন | SALE_WINDOW_DAYS |
অবদান রাখতে চাইলে
Issue আর pull request স্বাগত — বিশেষ করে সাইটের ডিজাইন বদলালে ঠিক করা, ছাড়ার সময় আপডেট আর অনুবাদ ঠিক করা। বট-চেক এড়ানো, লগইন/OTP/পেমেন্ট অটোমেট করা বা রিকোয়েস্টের গতি বাড়ানোর মতো পরিবর্তন নেওয়া হবে না।