Spaces:
Runtime error
Runtime error
File size: 6,886 Bytes
24b43e8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | import os
import json
import logging
import asyncio
from datetime import datetime
from aiogram import Bot, Dispatcher, types
from aiogram.enums import ContentType
from aiogram.filters import CommandStart
from google import genai
from google.oauth2.service_account import Credentials
from googleapiclient.discovery import build
from aiohttp import web
# Настройка логирования
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Токендер мен Кілттер
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN")
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
GOOGLE_SHEETS_ID = os.getenv("GOOGLE_SHEETS_ID")
# Инициализация
bot = Bot(token=TELEGRAM_TOKEN)
dp = Dispatcher()
ai_client = genai.Client(api_key=GEMINI_API_KEY)
# Google Sheets API байланысы
def append_to_sheets(rows):
service_account_info = json.loads(os.getenv("GOOGLE_CREDENTIALS_JSON"))
creds = Credentials.from_service_account_info(
service_account_info,
scopes=['https://www.googleapis.com/auth/spreadsheets']
)
service = build('sheets', 'v4', credentials=creds)
sheet = service.spreadsheets()
body = {'values': rows}
result = sheet.values().append(
spreadsheetId=GOOGLE_SHEETS_ID,
range="Накладные!A2",
valueInputOption="USER_ENTERED",
insertDataOption="INSERT_ROWS",
body=body
).execute()
return result
@dp.message(CommandStart())
async def cmd_start(message: types.Message):
await message.answer(
"👋 Сәлеметсіз бе! Мен накладнойларды есепке алу ботымын.\n\n"
"Маған накладнойдың немесе чектің анық түсірілген суретін жіберіңіз. "
"Мен оны автоматты түрде оқып, Google Sheets кестесіне енгіземін! 📊"
)
@dp.message(lambda message: message.content_type == ContentType.PHOTO)
async def handle_photo(message: types.Message):
status_message = await message.answer("⏳ Сурет қабылданды. Өңделуде, күте тұрыңыз...")
try:
# 1. Суретті Телеграмнан жүктеп алу
photo = message.photo[-1]
file_info = await bot.get_file(photo.file_id)
photo_bytes = await bot.download_file(file_info.file_path)
# 2. Суретті жаңа Gemini API-мен оқу
prompt = (
"Сен накладнойларды танитын көмекшісің. Мына суреттегі накладнойды/чекті мұқият талда. "
"Бұл суреттен келесі мәліметтерді тауып, тек қана валидті JSON форматында қайтар. "
"Ешқандай markdown белгілерін (мысалы ```json) қоспа, тек таза JSON текст болсын. "
"Егер мәлімет жоқ болса, бостой қалдыр (null немесе пустой строка). "
"Формат мынадай болуы керек:\n"
"{\n"
" \"date\": \"Күні (КҮН.АЙ.ЖЫЛ форматында, мысалы: 23.06.2026)\",\n"
" \"supplier\": \"Жіберуші/Дүкен атауы (мысалы: Строй Сити)\",\n"
" \"items\": [\n"
" {\n"
" \"name\": \"Тауар атауы\",\n"
" \"quantity\": \"Саны (өлшем бірлігімен бірге, мысалы: 10.08 м2 немесе 3 уп)\",\n"
" \"price\": \"Бір бірлігінің бағасы (тек сан)\",\n"
" \"total\": \"Жалпы сомасы (тек сан)\"\n"
" }\n"
" ]\n"
"}"
)
# Жаңа SDK форматында суретті жіберу
response = ai_client.models.generate_content(
model='gemini-1.5-flash',
contents=[
genai.types.Part.from_bytes(data=photo_bytes.getvalue(), mime_type='image/jpeg'),
prompt
]
)
raw_text = response.text.strip()
if raw_text.startswith("```json"):
raw_text = raw_text[7:]
if raw_text.endswith("```"):
raw_text = raw_text[:-3]
raw_text = raw_text.strip()
data = json.loads(raw_text)
date_str = data.get("date") or datetime.now().strftime("%d.%m.%Y")
supplier = data.get("supplier") or "Белгісіз"
items = data.get("items", [])
if not items:
await status_message.edit_text("❌ Суреттен тауарлар тізімі табылмады. Қайтадан анық етіп түсіріп көріңіз.")
return
# 3. Google Sheets жолдарын дайындау
rows_to_append = []
for item in items:
rows_to_append.append([
date_str,
supplier,
item.get("name"),
item.get("quantity"),
item.get("price"),
item.get("total")
])
append_to_sheets(rows_to_append)
report = f"✅ Накладной сәтті өңделді және Google Sheets-ке қосылды!\n\n"
report += f"📅 Күні: {date_str}\n"
report += f"🏪 Жіберуші: {supplier}\n"
report += f"📦 Тауар саны: {len(items)} дана\n\n"
report += "Таблицаңызды тексерсеңіз болады! 📈"
await status_message.edit_text(report)
except Exception as e:
logging.error(f"Қате орын алды: {str(e)}")
await status_message.edit_text("❌ Қате орын алды: Жүйе суретті тани алмады немесе Google Sheets-ке қосыла алмады.")
# Render-де Port сканерлеуден өткізу үшін шағын веб-сервер
async def handle_web(request):
return web.Response(text="Bot is running!")
async def start_web_server():
app = web.Application()
app.router.add_get('/', handle_web)
runner = web.AppRunner(app)
await runner.setup()
port = int(os.getenv("PORT", 8000))
site = web.TCPSite(runner, '0.0.0.0', port)
await site.start()
logging.info(f"Веб-сервер {port} портында іске қосылды.")
async def main():
# Веб-сервер мен Телеграм ботты бір уақытта іске қосу
await start_web_server()
await dp.start_polling(bot)
if __name__ == '__main__':
asyncio.run(main()) |