Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Astana Hub Instagram DM AI-бот

AI-бот для автоматических ответов на входящие сообщения (Direct Messages) в Instagram аккаунте Astana Hub.


1. Описание проекта

Бот автоматически отвечает на входящие DM в Instagram, используя контекст аккаунта (биографию и последние посты) и языковую модель Gemini. Бот отвечает только на вопросы, связанные с Astana Hub и технологической экосистемой Казахстана.

Стек:

  • Flask — веб-сервер для приёма webhook-запросов от Meta
  • Instagram Graph API (v25.0) — получение контекста аккаунта и отправка ответов в DM
  • Google Gemini API (gemini-2.5-flash) — генерация ответов на основе контекста
  • Railway — хостинг и деплой

2. Архитектура

Пользователь пишет DM в Instagram
        ↓
Meta отправляет POST-запрос на webhook (Railway URL)
        ↓
app.py — Flask получает POST /webhook
        ↓
Проверка на prompt injection (BLOCKED_PHRASES)
        ↓
Вызов get_answer(message_text) из rag.py
        ↓
rag.py — проверяет кэш контекста (TTL: 1 час)
   ├── Кэш свежий → использует сохранённый контекст
   └── Кэш устарел → GET запросы к Instagram Graph API
            ├── /me?fields=biography,username  (биография)
            └── /me/media?fields=caption&limit=10  (10 постов)
        ↓
Формирование промпта: System Prompt + Контекст + Вопрос
        ↓
Gemini API генерирует ответ
        ↓
app.py — POST на Graph API /messages → ответ отправляется в DM

3. Структура файлов

hubs_bot/
├── app.py              # Основной Flask-сервер, обработка webhook
├── rag.py              # Логика RAG: кэш контекста + вызов Gemini
├── update_context.py   # Утилита для ручного обновления контекста (не используется в проде)
├── subscribe.py        # Одноразовый скрипт подписки на Instagram webhooks
├── requirements.txt    # Python-зависимости
├── Procfile            # Команда запуска для Railway (gunicorn)
├── .env                # Локальные переменные окружения (не коммитить!)
└── .gitignore          # Исключения для git

app.py

Принимает GET-запросы для верификации webhook от Meta и POST-запросы с входящими сообщениями. Парсит sender_id и текст сообщения, проверяет на prompt injection, вызывает get_answer() и отправляет ответ через Graph API. Игнорирует собственные исходящие сообщения (защита от бесконечного цикла).

rag.py

Реализует RAG-логику без векторной базы данных. При первом обращении загружает биографию и последние 10 постов аккаунта через Instagram Graph API и сохраняет в памяти (кэш). Кэш живёт 1 час, затем обновляется автоматически. Формирует промпт с системными инструкциями и контекстом, вызывает Gemini.

requirements.txt

Python-зависимости: flask, requests, python-dotenv, gunicorn, google-generativeai.

Procfile

Команда запуска production-сервера: web: gunicorn app:app -b 0.0.0.0:$PORT.

.env

Файл с секретными переменными окружения для локального запуска. Никогда не коммитить в git.


4. Переменные окружения

Переменная Описание Где взять
VERIFY_TOKEN Произвольная строка для верификации webhook Придумать самостоятельно/meta сам выдает
ACCESS_TOKEN Instagram Page Access Token Meta Developer Dashboard → Instagram → Generate Token
IG_ID ID Instagram бизнес-аккаунта Meta Developer Dashboard или Graph API Explorer: /me?fields=id
GEMINI_API_KEY API ключ Google Gemini aistudio.google.com → Get API Key

5. Настройка Meta Developer Dashboard

Шаг 1: Создать приложение

  1. Зайди на developers.facebook.com
  2. Нажми My AppsCreate App
  3. Выбери тип Business/обычное приложение
  4. Заполни название и контактный email

Шаг 2: Добавить продукт Instagram

  1. В левом меню нажми Add Product
  2. Найди Instagram и нажми Set Up

Шаг 3: Добавить Instagram бизнес-аккаунт

  1. В разделе Instagram перейди в API Setup with Instagram Login или Basic Display
  2. В блоке Instagram Business Account добавь свой аккаунт
  3. Аккаунт должен быть Professional (Business или Creator)

Шаг 4: Сгенерировать Access Token

  1. Перейди в ToolsGraph API Explorer
  2. Выбери своё приложение и нужную Instagram Page
  3. Запроси разрешения: instagram_basic, instagram_manage_messages, pages_manage_metadata
  4. Нажми Generate Access Token и скопируй токен
  5. Для долгоживущего токена (60 дней): обменяй через GET /oauth/access_token?grant_type=fb_exchange_token

Шаг 5: Настроить Webhook

  1. В разделе Instagram перейди во вкладку Webhooks
  2. Нажми Configure
  3. В поле Callback URL введи: https://ВАШ_ДОМЕН_RAILWAY/webhook
  4. В поле Verify Token введи значение из переменной VERIFY_TOKEN
  5. Нажми Verify and Save — сервер должен быть запущен в этот момент!

Шаг 6: Подписаться на поле messages

  1. После сохранения webhook нажми Add Subscriptions для своего аккаунта
  2. Поставь галочку на поле messages
  3. Сохрани

Шаг 7: Добавить тестировщиков (для dev режима)

  1. Перейди в App RolesRoles
  2. Нажми Add PeopleTesters
  3. Добавь Instagram-аккаунты, которые должны получать ответы от бота в dev режиме
  4. Приглашённые пользователи должны принять приглашение на developers.facebook.com/apps

6. Деплой на Railway

Шаг 1: Создать проект из GitHub

  1. Загрузи код в GitHub репозиторий (убедись что .env в .gitignore)
  2. Зайди на railway.appNew ProjectDeploy from GitHub repo
  3. Выбери репозиторий

Шаг 2: Добавить переменные окружения

  1. Открой проект → вкладка Variables
  2. Добавь все переменные из раздела 4:
    • VERIFY_TOKEN
    • ACCESS_TOKEN
    • IG_ID
    • GEMINI_API_KEY
  3. Railway автоматически перезапустит сервис

Шаг 3: Получить домен

  1. Перейди в настройки сервиса → вкладка Networking
  2. Нажми Generate Domain
  3. Скопируй выданный домен вида https://xxx.up.railway.app

Шаг 4: Вставить домен в Meta webhook

  1. Вернись в Meta Developer Dashboard → Instagram → Webhooks
  2. Вставь домен в поле Callback URL: https://xxx.up.railway.app/webhook
  3. Нажми Verify and Save

7. Ограничения

  • 200 DM в сутки — лимит Meta на отправку сообщений через API для большинства типов аккаунтов
  • Бот не может написать первым — Instagram API позволяет отвечать только на входящие сообщения от пользователей, которые уже написали боту
  • Dev режим — пока приложение не прошло модерацию Meta, бот отвечает только пользователям, добавленным как тестировщики в App Roles
  • Кэш сбрасывается при перезапуске — контекст (посты и биография) хранится в памяти процесса. При каждом перезапуске контейнера на Railway кэш очищается и загружается заново при первом запросе (это штатное поведение, задержки нет)

8. Известные проблемы и решения

verify_signature конфликтует с request.get_data()

Проблема: Flask читает тело запроса при проверке подписи HMAC, после чего request.json возвращает None, так как поток уже прочитан.
Решение: Проверка подписи закомментирована в коде. Webhook верификации через VERIFY_TOKEN достаточно для базовой безопасности.

# Временно отключили проверку подписи:
# if not verify_signature(request):
#     return make_response("Unauthorized", 401)

Устаревшая модель Gemini тихо падает в except

Проблема: Старые модели (gemini-2.0-flash и ниже) могут быть недоступны или иметь исчерпанные квоты. Ошибка ResourceExhausted или 404 ловится в except и бот возвращает шаблонный ответ "Извините...".
Решение: Использовать актуальную модель gemini-2.5-flash. Следить за логами Railway на строку [RAG] Error generating answer:.

В dev режиме Meta не шлёт webhook на реальные DM

Проблема: Если приложение в статусе Development, входящие сообщения от пользователей которые не являются тестировщиками приложения — не триггерят webhook.
Решение: Добавить всех нужных пользователей как тестировщиков в Meta Dashboard → App Roles → Roles → Testers. Для публичного бота — подать приложение на модерацию Meta (перевести в Live режим).

Требует доработки !!!

Нужно доделать хранение констекста, можно добавить дополнительные функции. Это тестовый вебхук, MVP.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages