OpenClaw agent polls for pending messages. Returns all pending messages and marks them as delivered. Also updates openclaw_last_seen for online status tracking.
(
x_api_key: str = Header(..., alias="X-Api-Key"),
db: AsyncSession = Depends(get_db),
)
| 63 | |
| 64 | @router.get("/poll", response_model=GatewayPollResponse) |
| 65 | async def poll_messages( |
| 66 | x_api_key: str = Header(..., alias="X-Api-Key"), |
| 67 | db: AsyncSession = Depends(get_db), |
| 68 | ): |
| 69 | """OpenClaw agent polls for pending messages. |
| 70 | |
| 71 | Returns all pending messages and marks them as delivered. |
| 72 | Also updates openclaw_last_seen for online status tracking. |
| 73 | """ |
| 74 | logger.info(f"[Gateway] poll called, key_prefix={x_api_key[:8]}...") |
| 75 | agent = await _get_agent_by_key(x_api_key, db) |
| 76 | |
| 77 | # Update last seen |
| 78 | agent.openclaw_last_seen = datetime.now(timezone.utc) |
| 79 | agent.status = "running" |
| 80 | |
| 81 | # Fetch pending messages |
| 82 | result = await db.execute( |
| 83 | select(GatewayMessage) |
| 84 | .where(GatewayMessage.agent_id == agent.id, GatewayMessage.status == "pending") |
| 85 | .order_by(GatewayMessage.created_at.asc()) |
| 86 | ) |
| 87 | messages = result.scalars().all() |
| 88 | |
| 89 | # Mark as delivered |
| 90 | now = datetime.now(timezone.utc) |
| 91 | out = [] |
| 92 | for msg in messages: |
| 93 | msg.status = "delivered" |
| 94 | msg.delivered_at = now |
| 95 | |
| 96 | # Resolve sender names |
| 97 | sender_agent_name = None |
| 98 | sender_user_name = None |
| 99 | if msg.sender_agent_id: |
| 100 | r = await db.execute(select(Agent.name).where(Agent.id == msg.sender_agent_id)) |
| 101 | sender_agent_name = r.scalar_one_or_none() |
| 102 | if msg.sender_user_id: |
| 103 | r = await db.execute(select(User.display_name).where(User.id == msg.sender_user_id)) |
| 104 | sender_user_name = r.scalar_one_or_none() |
| 105 | |
| 106 | # Fetch conversation history (last 10 messages) for context |
| 107 | history = [] |
| 108 | if msg.conversation_id: |
| 109 | from app.models.audit import ChatMessage |
| 110 | hist_result = await db.execute( |
| 111 | select(ChatMessage) |
| 112 | .where(ChatMessage.conversation_id == msg.conversation_id) |
| 113 | .order_by(ChatMessage.created_at.desc()) |
| 114 | .limit(10) |
| 115 | ) |
| 116 | hist_msgs = list(reversed(hist_result.scalars().all())) |
| 117 | for h in hist_msgs: |
| 118 | # Resolve sender name for each history message |
| 119 | h_sender = None |
| 120 | if h.role == "user" and h.user_id: |
| 121 | r = await db.execute(select(User.display_name).where(User.id == h.user_id)) |
| 122 | h_sender = r.scalar_one_or_none() |
nothing calls this directly
no test coverage detected