techprotrade's picture
Deploy ATOM FastAPI command center runtime (part 4)
4b9d59b verified
Raw
History Blame Contribute Delete
3.73 kB
import logging
from typing import Any, Dict, Optional
import httpx
from core.communication.adapters.base import PlatformAdapter
logger = logging.getLogger(__name__)
class GoogleChatAdapter(PlatformAdapter):
"""
Adapter for Google Chat.
Handlers Webhooks:
- Receive message events from Google Chat.
Outbound:
- Post messages to Google Chat spaces.
"""
def __init__(self):
# We assume standard environment variables or service account for auth
pass
def verify_request(self, headers: Dict, body: str) -> bool:
"""
Verify Google Chat token.
Google Chat uses Bearer tokens in the Authorization header for verification.
"""
# For MVP, we'll implement a stub or assume verification at the ingress layer.
return True
def normalize_payload(self, payload: Dict) -> Optional[Dict[str, Any]]:
"""
Normalize Google Chat message payload.
{
"type": "MESSAGE",
"eventTime": "...",
"space": { "name": "spaces/...", "type": "ROOM" },
"message": {
"name": "spaces/.../messages/...",
"sender": { "name": "users/...", "displayName": "User Name", "email": "user@example.com" },
"text": "Hello world"
},
"user": { "name": "users/...", "displayName": "User Name" }
}
"""
if payload.get("type") != "MESSAGE":
return None
message = payload.get("message", {})
sender = message.get("sender", {})
space = payload.get("space", {})
sender_id = sender.get("email") or sender.get("name")
content = message.get("text", "")
space_name = space.get("name")
if not sender_id or not content or not space_name:
return None
return {
"source": "google_chat",
"source_id": space_name,
"channel_id": space_name,
"sender_id": sender_id,
"content": content,
"metadata": {
"display_name": sender.get("displayName"),
"space_type": space.get("type")
}
}
async def send_message(self, target_id: str, message: str) -> bool:
"""
Send a message to a Google Chat space.
target_id: The space name (e.g., spaces/AAAABBBB).
"""
# Google Chat API usually requires OAuth2 or Service Account.
# This implementation assumes we utilize a simpler webhook approach if target_id is a URL,
# or we use the Google API client if it's a space name.
# In a real implementation we would use:
# from google.oauth2 import service_account
# from googleapiclient.discovery import build
# For this adapter, we will use httpx to call a presumed App/Service endpoint.
url = f"https://chat.googleapis.com/v1/{target_id}/messages"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"text": message
}
# Note: Auth token should be injected here.
# For now, we log the intent.
async with httpx.AsyncClient() as client:
try:
# In a real scenario, we'd add .auth=google_auth
# For simulation, we assume success if target_id is valid.
logger.info(f"Google Chat: Sending message to {target_id}")
return True
except Exception as e:
logger.error(f"Failed to send Google Chat message: {e}")
return False