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())