Aimpress_site/chatbot-api/rocketchat.py
Vadym Samoilenko a8e8d8a71b Add lead collection form before chat + fix RC bot message delivery
- New ChatLeadForm component: collects name, email, company before chat starts
- GDPR consent checkbox with Privacy Policy link
- Lead info passed to backend and injected as LLM context
- Visitor name from form used in Rocket.Chat room
- RC bot messages: added logging + fallback to livechat/message endpoint
- RC room caching to avoid repeated API calls

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 18:02:08 +00:00

113 lines
4.1 KiB
Python

import httpx
import logging
from config import settings
logger = logging.getLogger("rocketchat")
HEADERS: dict[str, str] = {}
# Cache: session_id -> room_id
_room_cache: dict[str, str] = {}
def _get_headers() -> dict[str, str]:
if not HEADERS:
HEADERS.update({
"X-Auth-Token": settings.rocketchat_auth_token,
"X-User-Id": settings.rocketchat_user_id,
"Content-Type": "application/json",
})
return HEADERS
async def get_or_create_room(session_id: str, visitor_name: str = "Website Visitor") -> str | None:
"""Get or create a Rocket.Chat livechat room for a session."""
if not settings.rocketchat_auth_token:
return None
# Return cached room
if session_id in _room_cache:
return _room_cache[session_id]
try:
async with httpx.AsyncClient() as http:
# Register visitor
resp = await http.post(
f"{settings.rocketchat_url}/api/v1/livechat/visitor",
headers=_get_headers(),
json={
"visitor": {
"token": session_id,
"name": visitor_name,
}
},
timeout=10,
)
resp.raise_for_status()
# Get or create room
resp = await http.get(
f"{settings.rocketchat_url}/api/v1/livechat/room",
headers=_get_headers(),
params={"token": session_id},
timeout=10,
)
resp.raise_for_status()
room_id = resp.json().get("room", {}).get("_id")
if room_id:
_room_cache[session_id] = room_id
return room_id
except Exception as e:
logger.error(f"RC get_or_create_room error: {e}")
return None
async def send_message(room_id: str, session_id: str, text: str, sender: str = "bot") -> None:
"""Send a message to a Rocket.Chat livechat room."""
if not room_id or not settings.rocketchat_auth_token:
return
try:
async with httpx.AsyncClient() as http:
if sender == "visitor":
# Visitor sends via livechat visitor API
resp = await http.post(
f"{settings.rocketchat_url}/api/v1/livechat/message",
headers={"Content-Type": "application/json"},
json={
"token": session_id,
"rid": room_id,
"msg": text,
},
timeout=10,
)
if resp.status_code != 200:
logger.error(f"RC visitor msg error: {resp.status_code} {resp.text}")
else:
# Bot/agent sends via authenticated API
resp = await http.post(
f"{settings.rocketchat_url}/api/v1/chat.sendMessage",
headers=_get_headers(),
json={
"message": {
"rid": room_id,
"msg": f"🤖 {text}",
}
},
timeout=10,
)
if resp.status_code != 200:
logger.error(f"RC bot msg error: {resp.status_code} {resp.text}")
# Fallback: try livechat/message as agent
resp2 = await http.post(
f"{settings.rocketchat_url}/api/v1/livechat/message",
headers=_get_headers(),
json={
"token": session_id,
"rid": room_id,
"msg": f"🤖 {text}",
},
timeout=10,
)
if resp2.status_code != 200:
logger.error(f"RC bot msg fallback error: {resp2.status_code} {resp2.text}")
except Exception as e:
logger.error(f"RC send_message exception: {e}")