mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-02 19:55:18 +02:00
feat(gateway): expose Baileys pairing endpoints
This commit is contained in:
parent
3b529a3ab2
commit
63f9fe61b5
1 changed files with 99 additions and 0 deletions
|
|
@ -0,0 +1,99 @@
|
|||
"""Routes for the self-hosted WhatsApp Baileys bridge."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import UTC, datetime
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.config import config
|
||||
from app.db import (
|
||||
ExternalChatAccount,
|
||||
ExternalChatAccountMode,
|
||||
ExternalChatHealthStatus,
|
||||
ExternalChatPlatform,
|
||||
User,
|
||||
get_async_session,
|
||||
)
|
||||
from app.gateway.whatsapp.adapter_baileys import WhatsAppBaileysAdapter
|
||||
from app.users import current_active_user
|
||||
|
||||
router = APIRouter(prefix="/gateway/whatsapp/baileys", tags=["gateway"])
|
||||
|
||||
|
||||
class BaileysPairRequest(BaseModel):
|
||||
search_space_id: int
|
||||
phone_number: str
|
||||
|
||||
|
||||
def _ensure_baileys_enabled() -> None:
|
||||
if config.GATEWAY_WHATSAPP_INTAKE_MODE != "baileys":
|
||||
raise HTTPException(status_code=404, detail="WhatsApp Baileys gateway is disabled")
|
||||
if config.is_cloud():
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail="Baileys is only available for self-hosted SurfSense installs",
|
||||
)
|
||||
|
||||
|
||||
async def _get_user_whatsapp_account(
|
||||
session: AsyncSession,
|
||||
user: User,
|
||||
) -> ExternalChatAccount | None:
|
||||
result = await session.execute(
|
||||
select(ExternalChatAccount).where(
|
||||
ExternalChatAccount.owner_user_id == user.id,
|
||||
ExternalChatAccount.platform == ExternalChatPlatform.WHATSAPP,
|
||||
ExternalChatAccount.is_system_account.is_(False),
|
||||
)
|
||||
)
|
||||
return result.scalars().first()
|
||||
|
||||
|
||||
@router.post("/pair")
|
||||
async def request_pairing_code(
|
||||
body: BaileysPairRequest,
|
||||
user: User = Depends(current_active_user),
|
||||
session: AsyncSession = Depends(get_async_session),
|
||||
) -> dict[str, Any]:
|
||||
_ensure_baileys_enabled()
|
||||
adapter = WhatsAppBaileysAdapter()
|
||||
try:
|
||||
pairing = await adapter.request_pairing_code(phone_number=body.phone_number)
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=502, detail=str(exc)) from exc
|
||||
|
||||
account = await _get_user_whatsapp_account(session, user)
|
||||
if account is None:
|
||||
account = ExternalChatAccount(
|
||||
platform=ExternalChatPlatform.WHATSAPP,
|
||||
mode=ExternalChatAccountMode.SELF_HOST_BYO,
|
||||
owner_user_id=user.id,
|
||||
owner_search_space_id=body.search_space_id,
|
||||
is_system_account=False,
|
||||
cursor_state={},
|
||||
health_status=ExternalChatHealthStatus.UNKNOWN,
|
||||
)
|
||||
session.add(account)
|
||||
else:
|
||||
account.mode = ExternalChatAccountMode.SELF_HOST_BYO
|
||||
account.owner_search_space_id = body.search_space_id
|
||||
account.health_status = ExternalChatHealthStatus.UNKNOWN
|
||||
account.last_health_check_at = datetime.now(UTC)
|
||||
await session.commit()
|
||||
await session.refresh(account)
|
||||
return {"account_id": account.id, **pairing}
|
||||
|
||||
|
||||
@router.get("/health")
|
||||
async def bridge_health() -> dict[str, Any]:
|
||||
_ensure_baileys_enabled()
|
||||
adapter = WhatsAppBaileysAdapter()
|
||||
try:
|
||||
return await adapter.validate_credentials()
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=502, detail=str(exc)) from exc
|
||||
Loading…
Add table
Add a link
Reference in a new issue