Kasi operates as a multi-tenant messaging router. Each merchant account maintains isolated product catalogs, conversation histories, and automation rules while sharing a unified API layer and webhook infrastructure.
Component
Technology
Purpose
Backend API
Flask + SQLAlchemy
REST API, webhook handlers, AI orchestration
Frontend Dashboard
React + Vite
Merchant portal, settings, analytics
Database
PostgreSQL (prod) / SQLite (dev)
Users, products, invoices, integrations
Task Queue
Celery + Redis
Background jobs, scheduled tasks
Deployment
Docker Compose
Containerized production stack on VPS
8 min read
AdvancedUpdated Jun 2026
Social Media Integrations
Technical guide for how Kasi connects, authorizes, and handles multi-tenant messaging across WhatsApp, Telegram, Instagram, and Facebook Messenger.
1. Data Model
Core DB Model: Integration
Every connected channel is stored in the integrations table:
Column
Type
Description
user_id
Integer FK
Links integration to a specific merchant
platform
String
'whatsapp', 'telegram', 'instagram', or 'facebook'
Audio Transcription: Voice notes are fetched via media API, transcribed by OpenAI Whisper or Groq Whisper, prepended with π€ [Voice Note]:.
Rider Interceptor: If sender matches a vendor's saved logistics rider and confirms, the invoice is marked "In Transit" with automatic notifications.
AI Processing: Routes text to SalesAI.process and images to SalesAI.process_image.
π΅ Channel B β Telegram Bots
Telegram integrations use dedicated bots created via @BotFather.
Connection Flow
Credential Entry: Merchant creates a Telegram bot, obtains the Bot Token, and inputs it in Kasi Settings.
Webhook Registration: Kasi registers the webhook: POST https://api.telegram.org/bot{token}/setWebhook?url={BASE_URL}/api/telegram/webhook/{token}
Database Save: Integration saved with platform 'telegram', access_token = token.
Webhook Message Flow
POST /api/telegram/webhook/<token>
Routing: Bot token from URL β Integration.query.filter_by(access_token=token) β identifies merchant.
Processing: Text passed to SalesAI.process.
Dispatch: Reply via POST https://api.telegram.org/bot{token}/sendMessage.
π£ Channel C β Instagram DM & Facebook Messenger
Meta messaging channels use a single Meta Developer App with Graph API and OAuth.
Frictionless OAuth: Vendors click "Connect", authorize via Facebook Dialog, select their page/IG account, and are connected automatically. No manual tokens needed.
Connection Flow (OAuth)
Authorization Request: Frontend redirects to Facebook's OAuth URL: https://www.facebook.com/v21.0/dialog/oauth?client_id={APP_ID}&redirect_uri={FRONTEND_URL}/settings&scope=pages_show_list,pages_messaging,instagram_basic,instagram_manage_messages,pages_read_engagement&response_type=code&state={platform}
Facebook Redirect: After authorization, Facebook redirects back: https://usekasi.com/settings?code={auth_code}&state={instagram|facebook}
Code Exchange: Frontend sends code to backend: POST /api/meta/oauth/callback
Token Exchange: Backend exchanges auth code for User Access Token via Meta API.
Page List Query: Backend calls /me/accounts to fetch Page IDs and Page Access Tokens.
Account Resolution:
Facebook: First Page's ID β instance_name, Page Access Token β access_token.
Instagram: Queries each page for instagram_business_account. If found, IG Account ID β instance_name, Page Access Token β access_token.
Webhook Message Flow
POST /api/meta/webhook
Signature Verification: Validates x-hub-signature-256 using HMAC-SHA256 with META_APP_SECRET.
Routing: Inspects entry.messaging.recipient.id β queries Integration by instance_name.
Image Support: CDN URLs fetched, converted to base64, passed to SalesAI.process_image.
Response Dispatch: POST https://graph.facebook.com/v21.0/me/messages?access_token={page_access_token}
# Meta Graph API configuration
META_APP_ID=**********************
META_APP_SECRET=********************************
META_VERIFY_TOKEN=********************************
# Evolution API (WhatsApp) configuration
EVOLUTION_API_URL=http://localhost:8080
EVOLUTION_GLOBAL_API_KEY=************************
# General config
BASE_URL=https://api.usekasi.com
Security: Never commit real API secrets to version control. Use environment variables and .env files excluded from Git via .gitignore.
4. Troubleshooting
Meta Webhook Handshake Failing:
Ensure META_VERIFY_TOKEN matches exactly between the Meta Developer portal and backend .env.
Instagram Webhooks Not Delivering:
Verify the Instagram account is set to Business type (Creator type has restrictions).
Verify the IG account is linked to the Facebook Page in Settings.
Confirm the PAT was granted instagram_manage_messages permission.
WhatsApp Pairing Code Failing:
Check Evolution API container health: docker ps | grep evolution. Ensure the global API key matches.
5 min read
IntermediateUpdated Jun 2026
VPS Production Deployment
Command-by-command guide for staging, pushing, deploying, and rebuilding Kasi on a Hostinger VPS with Docker Compose.
1. Architecture Overview
The production VPS uses a containerized Docker network. The database container (kasi_db) runs PostgreSQL on port 5432 with no public port exposure, fully isolated inside the private Docker network (kasi-network).
Development runs on SQLite locally. Production uses PostgreSQL. Schema changes are synchronized via Alembic migration scripts.
2. Git Staging & Pushing (Local)
# Check modified files
git status
# Stage all files
git add .
# Commit with semantic message
git commit -m "feat: complete meta integration webhook"
# Push to GitHub
git push origin main
3. Deploy on VPS
# SSH into VPS
ssh root@***.***.*.*
# Navigate to backend
cd ~/kasi-backend
# Pull latest
git pull origin main
# Force-rebuild and recreate all containers
docker compose up -d --build --force-recreate
Flags:--build recompiles Dockerfiles to pull new packages. --force-recreate ensures .env variables are fully reloaded.
Migrations run inside the Flask container via docker compose exec:
# Standard upgrade
docker compose exec kasi-backend flask db upgrade
# Check current migration version
docker compose exec kasi-backend flask db current
# Stamp database to specific revision (if diverged)
docker compose exec kasi-backend flask db stamp <revision_id>
Alembic Divergence: If you get "Target database not up-to-date", stamp the database at the correct revision first, then run flask db upgrade.