Milliy tanlov uchun Telegram-bot: 250 000 ta ro‘yxatdan o‘tish
«Yoshlar ovozi» boti 300 qatordan kam koddan iborat. U orqali 250 mingdan ortiq ro‘yxatdan o‘tish amalga oshdi. Unda nima yuklamaga chidagani, ma’lumotlarda nima buzilgani va keyingi tanlovlarda hammasini qanday qayta qilganimiz haqida gapirib beraman.
Mirodil OrtiqovBackend dasturchi
Yoshlar ishlari agentligi vazifa bilan kelganida, u oddiy eshitilardi: butun mamlakatdagi yosh ijrochilar «Yoshlar ovozi» vokal tanloviga ariza topshiradigan bot kerak. Ism, manzil, yosh toifasi, yo‘nalish, telefon. Tamom.
Mamlakat miqyosida oddiy vazifalar oddiyligicha qolmaydi. Mana barcha mavsumlar davomida bot bazasida to‘plangan raqamlar:
Oxirgi raqam bizni ham birinchi bo‘lib hayron qoldirdi. Bu haqda quyida.
Nega sayt emas, bot
Tanlov auditoriyasi — 10 yoshdan 30 yoshgacha bo‘lgan yoshlar, jumladan internet sekin va saytlar goh ochilib, goh ochilmaydigan tumanlardan ham. Telegram esa hammada bor. Uni o‘rnatish shart emas, parol o‘ylab topish kerak emas, telefon raqamini bitta tugma bilan yuborish mumkin.
Formali sayt bu yerda uch jihatdan yutqazardi: uni topish kerak, u zaif 3G’da uzoq yuklanadi va telefonda 7 maydonli formani to‘ldirish noqulay. Botda har bir savol alohida xabar bo‘lib keladi va odam unga oddiy yozishmadagidek javob beradi.
Bot qanday tuzilgan edi
Birinchi versiya juda to‘g‘ridan-to‘g‘ri edi: aiogram 2, bitta fayldagi SQLite, long polling’dagi bitta jarayon, Docker. Redis ham, admin panel ham yo‘q. Ro‘yxatdan o‘tish holati to‘g‘ridan-to‘g‘ri arizalar jadvalida, state ustunida saqlanardi.
state = db.get_user_state(user_id) # shu foydalanuvchining oxirgi arizasi
if state == "region":
if message.text in regions:
db.update_user_region(user_id, message.text)
await message.answer("Tuman (shahar)ni tanlang", reply_markup=districts_kb)
elif state == "district":
db.update_user_district(user_id, message.text) # tekshiruvsiz — bu xato
«Boshlash»ning har bir bosilishi yangi qator yaratardi. Buni ataylab qilganmiz: bitta odam ketma-ket bir nechta ishtirokchini ro‘yxatdan o‘tkazishi mumkin edi. Muvaffaqiyatli arizadan keyin bot hatto eslatardi: «Boshqa ishtirokchilar bo‘lsa, Boshlash tugmasini qayta bosing».
Bitta akkauntga o‘rtacha 5,6 ishtirokchi shundan. Biz buni bolaning o‘z Telegram’i bo‘lmagan, arizani ota-onasi yoki to‘garak rahbari topshiradigan holatlar uchun mo‘ljallagan edik. Ammo bunday «guruhli» topshirishning miqyosini oldindan ko‘ra olmagandik.
Bu oddiy stek yuklamaga chidadi. Ro‘yxatdan o‘tishning har bir qadami — bazaga bitta qisqa yozuv, bitta yozuvchili SQLite esa bunday oqimni bemalol ko‘taradi. Tor joy server emas, bir joyda o‘zimiz bo‘lib chiqdik: kanallarga obunani tekshirish.
Avvaliga bot har bir xabardan oldin odam tashkilotchilarning ikkita kanaliga obuna bo‘lganini tekshirardi. Bu har bir bosishga Telegram API’ga ikkita ortiqcha so‘rov degani, barcha mavsumlar davomida esa bunday bosishlar millionlab yig‘ildi. Oxiri tekshiruvni bitta qator bilan o‘chirdik: funksiya boshida return True. Chiroyli emas, lekin halol.
Ma’lumotlar qayerda buzildi
Server ishlab turdi, ma’lumotlar esa unchalik emas. Mavsumni yopib, eksportni to‘liq ko‘rib chiqqanimizda manzara shunday edi:
- «tuman» maydonida 3 385 ta turli qiymat chiqdi, holbuki O‘zbekistonda ikki yuzga yaqin tuman va shahar bor;
- «mahalla» maydonida — qariyb 45 mingta turli yozilish;
- «yo‘nalish» maydonida to‘rtta to‘g‘ri variantdan tashqari katta harfli «Estrada», «16-22 yosh» va hatto «Sport» topildi.
Sababi bitta. Tuman qadamida bot istalgan matnni qabul qilardi, mahallani esa umuman qo‘lda kiritish so‘ralardi. Tugmali klaviaturamiz one_time_keyboard edi: bir bosishdan keyin u yashirinadi va odamlarning bir qismi javobni o‘zi yozib yuborardi. Bot esa itoatkorona saqlardi.
Odamlar ro‘yxatdan o‘tishni qayerda tashlab ketdi
Boshlangan ro‘yxatdan o‘tishlar 274 mingga yaqin, yakunlanganlari — 250 ming. Taxminan 24 ming kishi yarim yo‘lda to‘xtadi. Ular qaysi qadamda qolib ketganini ko‘rib chiqdik:
Eng katta yo‘qotish — birinchi savolning o‘zida. Odam «Boshlash»ni bosdi, «F.I.Sh. kiriting»ni ko‘rdi va chiqib ketdi. Menimcha, ba’zilar shunchaki ichida nima borligini ko‘rmoqchi bo‘lgan. Ikkinchi o‘rinda — telefon: kimdir «Raqamni yuborish» tugmasiga ishonmaydi, kimdir uni bosish kerakligini, raqamni qo‘lda terish emasligini tushunmaydi.
Mahalla to‘rtinchi o‘rinda, garchi bu eng noqulay qadam bo‘lsa ham: rasmiy nomni eslab, yozish kerak. Keyingi botlarda birinchi bo‘lib aynan shuni qayta qildik.
Tashkilotchilarga aslida nima kerak
Tashkilotchilarga chiroyli admin panel kerak emasdi. Ularga ikki narsa kerak edi: bugungi raqamlar va jadval.
Raqamlar uchun /getall buyrug‘i bor edi: bot Toshkent vaqti bo‘yicha joriy holatga hisobot yuborardi — jami arizalar, viloyatlar, yo‘nalishlar va yoshlar kesimida. Uni rahbariyatga to‘g‘ridan-to‘g‘ri chatdan yuborishardi.
Jadval uchun /get buyrug‘i bor edi: pandas arizalarni Excel’ga yig‘ardi va bot faylni yuborardi. Hech qanday login va parol yo‘q, faqat Telegram ID adminlar ro‘yxatida borligini tekshirish.
Taqsimot kutilganidek chiqdi: ishtirokchilarning yarmidan ko‘pi estradani tanladi, keyin an’anaviy ijro (maqom, katta ashula), so‘ng baxshichilik va opera. Eng katta yosh guruhi — 16–22 yosh.
Kitobxon: ikkinchi urinish, endi mahallalar bazasi bilan
«Yosh Kitobxon» va «Kitobxon Oila» kitobxonlik tanlovlari uchun botlar qilganimizda «Yoshlar ovozi» xatolari ko‘z oldimizda turardi. Shuning uchun ikkinchi yondashuv butunlay boshqacha bo‘ldi:
- SQLite o‘rniga Django 4.2 + PostgreSQL va tashkilotchilar matnlar, kanallar va tanlov muddatlarini o‘zlari o‘zgartiradigan admin panel.
- Excel’dan yuklangan 9 442 ta mahalla va qishloq ma’lumotnomasi. Viloyat → tuman → mahalla faqat tugmalar bilan tanlanadi, matn kelsa bot «taklif qilinganlardan birini tanlang» deb javob beradi.
- Arizalar jadvalidagi
stateustuni o‘rniga aiogram FSM: foydalanuvchi profili alohida, aniq tanlovdagi ishtirok alohida. - Tanlangan toifa bo‘yicha emas, tug‘ilgan sana bo‘yicha yosh. «Yosh Kitobxon»da 10 yoshdan 30 yoshgacha qatnashadi va bot mos kelmaganlarni o‘zi ajratadi.
- Bitta botda bir nechta tanlov, har birining ro‘yxatdan o‘tish boshlanishi va tugash sanalari bor.
- Bitta umumiy jadval emas, har bir tanlov bo‘yicha alohida Excel.
9 442 ta variantli kaskad tugmalar ko‘rinishida qo‘rqinchli eshitiladi, lekin bitta tumanda odatda bir necha o‘nta mahalla bo‘ladi, shuning uchun klaviatura me’yorida qoladi. Shundan keyin tashkilotchilarda «„Navbaxor MFY 2-uy“ qanaqa mahalla?» kabi savollar tugadi.
Keyingi milliy tanlovdan oldin nimani tekshirardim
Agar sizga ham shunga o‘xshash vazifa kelsa, mana men endi birinchi kundan yodda tutadigan ro‘yxat:
- Statistika quriladigan maydonlar faqat ma’lumotnomadagi qiymatlarni qabul qiladi
- Viloyat, tuman va mahallalar ma’lumotnomasi «keyin qo‘shamiz» emas, ishga tushirishdan oldin yuklangan
- Eng ko‘p tashlab ketiladigan savol (odatda birinchisi) iloji boricha qisqa va tushunarli
- Telefon faqat
request_contacttugmasi orqali, yonida tushunarli matn bilan qabul qilinadi - Kanallarga obunani tekshirish — har bir xabarda emas, startda bir marta
- Tashkilotchilar uchun «hozirgi holat» raqamlari bilan alohida buyruq yoki admin panel
- Qayta ishlamasdan ochsa bo‘ladigan Excel eksport
- Bitta foydalanuvchi bir nechta ariza topshira oladi va bu hisobotda ko‘rinadi
Bu loyihadagi eng kutilmagan narsa: 300 qatorli bot chorak million ariza ostida yiqilmadi. Muammolar yuklamani ko‘targan kodda emas, javoblarni qabul qilgan kodda edi. Agar siz ham tanlov yoki tadbirga ariza yig‘ayotgan bo‘lsangiz, Telegram-botlarni qanday qilishimizni hamda Yoshlar ovozi va Yosh Kitobxon keyslarini ko‘ring. Agar hali bot va sayt o‘rtasida tanlayotgan bo‘lsangiz, birinchi navbatda nima qilish haqida alohida matnimiz bor.



