November 3

Namoz vaqtlari 12 ta viloyat

Avvalgi Aiogram 3.22 vesiyasida yaratgan Namoz vaqti botimiz faqat 1 ta joyga qarashli bo'lar edi , bugungi Botimiz O'zbekistonning 12 ta viloyatini vaqtini ko'rsata oladigan botini yartamiz.

import asyncio
import logging
from datetime import datetime
import aiohttp

from aiogram import Bot, Dispatcher, F
from aiogram.filters import Command
from aiogram.types import Message, ReplyKeyboardMarkup, KeyboardButton
from aiogram.enums import ParseMode
from aiogram.client.default import DefaultBotProperties

logging.basicConfig(level=logging.INFO)

BOT_TOKEN = "7627050170:AAF2w-NYia_7u1GaTD6lW5wSLwEx4C9Tepc"

bot = Bot(token=BOT_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.MARKDOWN))
dp = Dispatcher()

# 12 ta viloyat ro'yxati
REGIONS = [
    "Toshkent", "Toshkent viloyati", "Andijon", "Farg'ona", "Namangan",
    "Samarqand", "Buxoro", "Xorazm", "Qashqadaryo", "Surxondaryo",
    "Jizzax", "Sirdaryo", "Navoiy"
]

# Viloyat tanlash uchun Reply Keyboard
region_keyboard = ReplyKeyboardMarkup(
    keyboard=[[KeyboardButton(text=region)] for region in REGIONS],
    resize_keyboard=True
)

# API URL shabloni
API_URL = "https://api.aladhan.com/v1/timingsByCity?city={city}&country=Uzbekistan&method=2"

@dp.message(Command("start"))
async def start_handler(message: Message):
    await message.answer(
        "Assalomu alaykum! 🇺🇿\nBu bot O'zbekiston bo'yicha namoz vaqtlarini ko'rsatadi.\n\n" \
        "Buyruqlar:\n/namoz - Viloyat tanlash va namoz vaqtlarini olish",
    )

@dp.message(Command("namoz"))
async def select_region_handler(message: Message):
    await message.answer("Viloyatni tanlang:", reply_markup=region_keyboard)

@dp.message(F.text.in_(REGIONS))
async def send_prayer_times(message: Message):
    city = message.text
    url = API_URL.format(city=city)

    try:
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                if response.status == 200:
                    data = await response.json()
                    timings = data['data']['timings']
                    today = datetime.now().strftime("%d.%m.%Y")

                    text = (
                        f"🕌 *Namoz vaqtlari — {city}*\n"
                        f"📅 Sana: {today}\n\n"
                        f"🌅 Bomdod: {timings['Fajr']}\n"
                        f"☀️ Quyosh chiqishi: {timings['Sunrise']}\n"
                        f"🏙  Peshin: {timings['Dhuhr']}\n"
                        f"🌆 Asr: {timings['Asr']}\n"
                        f"🌇 Shom: {timings['Maghrib']}\n"
                        f"🌙 Xufton: {timings['Isha']}\n\n"
                        f"*Manba: Aladhan API*"
                    )
                    await message.answer(text)
                else:
                    await message.answer("❌ API xatosi, keyinroq urinib ko'ring.")
    except Exception as e:
        logging.error(f"Xato: {e}")
        await message.answer("❌ Xatolik yuz berdi, qayta urinib ko'ring.")

async def main():
    await dp.start_polling(bot)

if __name__ == "__main__":
    asyncio.run(main())

Avvalgi botimiz bilan solishtiramiz qanday yangiliklar qo'shildi!

🔄 O‘zgartirilgan asosiy joylar (avvalgi kodga nisbatan):

Qism

Nima qo‘shildi / o‘zgardi

Nima uchun

✅ ReplyKeyboard qo‘shildi

ReplyKeyboardMarkup, KeyboardButton import qilindi

Viloyat tugmalari chiqishi uchun

REGIONS dictionary yaratildi

{'Andijon': 'Andijan', ...}

API uchun inglizcha nomni bog‘lash

/namoz komandasi endi bevosita vaqt jo‘natmaydi

Faqat tugmalarni chiqaradi

Foydalanuvchi viloyat tanlashi uchun

@dp.message(F.text.in_(REGIONS.keys())) handler qo‘shildi

Tanlangan viloyatga qarab API’dan so‘rov yuboradi

Har bir viloyat uchun alohida vaqt

✅ API URL endi dinamik bo‘ldi

city={city} bilan o‘zgaradi

Har bir hududga mos vaqt olish uchun


❓ Sizga savol:

Viloyat tugmalarini 2 qatorda qilaymi, yoki 3 qatorda?

Variant A (2×6):

Andijon | Farg‘ona
Namangan | Samarqand
Buxoro | Xorazm
...

Variant B (3×4):

Andijon | Farg‘ona | Namangan
Samarqand | Buxoro | Xorazm
...

Agar farqi yo‘q desangiz — default 3×4 qilib yuboraman.


✅ Agar hozir ok desangiz — to‘liq kodni izohlar bilan yuboraman.

Shu tarzda:

# 🆕 Yangi qo‘shilgan qism: viloyatlar ro‘yxati
REGIONS = {
    "Andijon": "Andijan",
    ...
}

va

@dp.message(F.text.in_(REGIONS.keys()))
async def region_handler(message: Message):
    # 🆕 Bu yangi handler — tanlangan viloyat uchun vaqtni olib keladi

✅ 1. Asosiy farq — endi bot faqat Toshkent emas, 12 ta viloyat bo‘yicha ishlaydi

Eski kod

Yangi kod

Faqat Toshkent shahriga bog‘langan (city=Tashkent)

12 ta viloyat ro‘yxati yaratildi (REGIONS = [...])

/namoz → darhol vaqt yuborar edi

/namoz → reply tugmalarni chiqaradi, foydalanuvchi viloyat tanlaydi

API URL bitta va o‘zgarmas

API URL dinamik bo‘ldi (city={city}) → har bir viloyat uchun


✅ 2. REGIONS ro‘yxati qo‘shildi

REGIONS = [
    "Toshkent", "Toshkent viloyati", "Andijon", "Farg'ona", "Namangan",
    "Samarqand", "Buxoro", "Xorazm", "Qashqadaryo", "Surxondaryo",
    "Jizzax", "Sirdaryo", "Navoiy"
]

🆕 Bu qism eski kodda yo‘q edi → bu yangi qo‘shilgan bo‘lim.


✅ 3. Reply Keyboard qo‘shildi (➜ yangi koddagi eng muhim yangilik)

region_keyboard = ReplyKeyboardMarkup(
    keyboard=[[KeyboardButton(text=region)] for region in REGIONS],
    resize_keyboard=True
)

🆕 Bu qism dasturga quyidagi imkoniyatni qo‘shdi:

/namoz buyrug‘i bosilganda foydalanuvchi pastda viloyat tugmalarini ko‘radi
✅ Har bir tugma bosilganda bot shu viloyat uchun namoz vaqtini olib keladi


✅ 4. /namoz handler o‘zgardi

Eski kod:

@dp.message(Command("namoz"))
async def prayer_times_handler(message: Message):
    # darhol Toshkent uchun API so'rovi yuboradi

Yangi kod:

@dp.message(Command("namoz"))
async def select_region_handler(message: Message):
    await message.answer("Viloyatni tanlang:", reply_markup=region_keyboard)

🔁 ENDILIKDA /namoz javob qaytarmaydi, balki viloyat tanlatadi
🔥 Bu juda katta farq!


✅ 5. Yangi handler qo‘shildi: @dp.message(F.text.in_(REGIONS))

@dp.message(F.text.in_(REGIONS))
async def send_prayer_times(message: Message):

🆕 Eski kodda bunday handler yo‘q edi
Bu handler tugma bosilganda ishlaydi. Ya’ni foydalanuvchi:

Andijon ✅

deb bossa — bot API’dan city=Andijan bo‘yicha ma’lumot olib keladi.


✅ 6. API URL endi shunday quriladi:

url = API_URL.format(city=city)

🤖 Bu degani:

👆 Foydalanuvchi "Buxoro" tanlasa → URL bo‘ladi:

https://api.aladhan.com/v1/timingsByCity?city=Buxoro&country=Uzbekistan&method=2

✅ 7. Toshkent uchun bo‘lgan eski o‘zgarmas kod olib tashlandi:

CITY_ID = 434877
PRAYER_API_URL = "https://...Tashkent..."

🔴 Yangi kodda bu qismlar keraksiz bo‘lib qoldi, chunki city endi dinamik.


✅ Qisqa xulosa (1 jumlada)

🟢 Eski kod — faqat Toshkent uchun ishlardi
🟢 Yangi kod — butun O‘zbekiston bo‘yicha ishlaydi, foydalanuvchi viloyatni o‘zi tanlaydi


🔧 1. Viloyatlar API bilan to‘g‘ri ishlashi uchun Tugma nomi ≠ API nomi bog‘lanadi

Chunki API Toshkentni Tashkent, Farg‘onani Fergana, Buxoroni Bukhara tarzida qabul qiladi.

Shuning uchun biz lug‘at (dict) shaklida to‘g‘ri xaritalash qilamiz:

REGIONS = {
    "Toshkent": "Tashkent",
    "Toshkent viloyati": "Tashkent",
    "Andijon": "Andijan",
    "Farg'ona": "Fergana",
    "Namangan": "Namangan",
    "Samarqand": "Samarkand",
    "Buxoro": "Bukhara",
    "Xorazm": "Khorezm",
    "Qashqadaryo": "Kashkadarya",
    "Surxondaryo": "Surkhandarya",
    "Jizzax": "Jizzakh",
    "Sirdaryo": "Syrdarya",
    "Navoiy": "Navoi"
}

✅ Foydalanuvchi tugmada "Farg'ona" bosadi
👆 API esa "city=Fergana" so‘raydi
❌ Aks holda API xato qaytaradi