Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| from fastapi import FastAPI, Request, HTTPException, Response | |
| from fastapi.responses import PlainTextResponse | |
| from huggingface_hub import InferenceClient | |
| import io | |
| from PIL import Image | |
| app = FastAPI(title="VK AI Webhook Bot") | |
| # Переменные окружения (добавьте их в Settings → Variables в Space) | |
| VK_TOKEN = os.getenv("VK_TOKEN") # access_token группы | |
| VK_SECRET = os.getenv("VK_SECRET") # секретное слово (придумайте сами) | |
| HF_TOKEN = os.getenv("HF_TOKEN") # ваш HF токен | |
| CONFIRMATION_STRING = os.getenv("VK_CONFIRM") # строка подтверждения из VK | |
| client = InferenceClient(token=HF_TOKEN) | |
| LLM_MODEL = "Qwen/Qwen2.5-7B-Instruct" | |
| IMG_MODEL = "stabilityai/stable-diffusion-xl-base-1.0" | |
| async def root(): | |
| return {"status": "VK Webhook Bot is running"} | |
| async def vk_webhook(request: Request): | |
| try: | |
| body = await request.json() | |
| except: | |
| raise HTTPException(400, "Invalid JSON") | |
| # Проверка секретного ключа (обязательно!) | |
| if body.get("secret") != VK_SECRET: | |
| raise HTTPException(403, "Invalid secret") | |
| event_type = body.get("type") | |
| if event_type == "confirmation": | |
| # VK при настройке шлёт confirmation → возвращаем строку подтверждения | |
| if CONFIRMATION_STRING: | |
| return PlainTextResponse(CONFIRMATION_STRING) | |
| else: | |
| raise HTTPException(500, "Confirmation string not set") | |
| if event_type == "message_new": | |
| msg = body["object"]["message"] | |
| peer_id = msg["peer_id"] | |
| text = msg["text"].strip() | |
| from_id = msg["from_id"] | |
| msg_id = msg.get("id") # для reply_to | |
| low_text = text.lower() | |
| # Пример обработки команд | |
| if low_text.startswith("!картинка") or "нарисуй" in low_text: | |
| prompt = text.replace("!картинка", "").replace("нарисуй", "").strip() | |
| if not prompt: | |
| # Отправляем ответ (через vk_api или requests — см. ниже) | |
| await send_vk_message(peer_id, "Укажите, что нарисовать!", msg_id) | |
| return {"ok": True} | |
| await send_vk_message(peer_id, f"Генерирую картинку: «{prompt}»...", msg_id) | |
| try: | |
| image = client.text_to_image( | |
| prompt, | |
| model=IMG_MODEL, | |
| num_inference_steps=25, | |
| guidance_scale=7.0 | |
| ) | |
| buf = io.BytesIO() | |
| image.save(buf, format="PNG") | |
| buf.seek(0) | |
| # Здесь нужно загрузить фото в ВК и получить attachment | |
| # Для этого используйте vk_api или requests + upload сервер | |
| # Простой вариант — пока просто логируем | |
| print("Картинка сгенерирована") | |
| await send_vk_message(peer_id, "Картинка готова! (загрузка пока не реализована)", msg_id) | |
| except Exception as e: | |
| await send_vk_message(peer_id, f"Ошибка генерации: {str(e)[:100]}", msg_id) | |
| else: | |
| # Обычный чат с AI | |
| try: | |
| response = client.chat.completions.create( | |
| model=LLM_MODEL, | |
| messages=[{"role": "user", "content": text}], | |
| max_tokens=400 | |
| ) | |
| answer = response.choices[0].message.content.strip() | |
| await send_vk_message(peer_id, answer, msg_id) | |
| except Exception as e: | |
| await send_vk_message(peer_id, "Ошибка ИИ, попробуйте позже", msg_id) | |
| return {"ok": True} # VK требует "ok" или 200 OK | |
| async def send_vk_message(peer_id: int, text: str, reply_to: int = None): | |
| """Отправка сообщения через VK API (простой вариант через requests)""" | |
| import requests | |
| params = { | |
| "peer_id": peer_id, | |
| "message": text, | |
| "random_id": 0, | |
| "access_token": VK_TOKEN, | |
| "v": "5.199" | |
| } | |
| if reply_to: | |
| params["reply_to"] = reply_to | |
| try: | |
| requests.post("https://api.vk.com/method/messages.send", params=params) | |
| except: | |
| print("Ошибка отправки сообщения в VK") |