Some checks failed
Build and Deploy Docs / build-and-deploy (push) Has been cancelled
- Created logs/ structure (sessions, operations, incidents) - Added session-start/log/end scripts - Installed Git hooks for auto-logging commits/pushes - Added shell integration for zsh - Created CHANGELOG.md - Documented today's session (2026-01-10)
374 lines
7.9 KiB
Markdown
374 lines
7.9 KiB
Markdown
# DAARION Messaging Service
|
|
|
|
**Matrix-aware messaging service for DAARION**
|
|
|
|
## Overview
|
|
|
|
The messaging-service provides a DAARION-specific API layer over Matrix protocol:
|
|
- Manages channels (mapped to Matrix rooms)
|
|
- Indexes messages (full content stored in Matrix)
|
|
- Handles real-time WebSocket connections
|
|
- Integrates agents into conversations
|
|
- Bridges Matrix ↔ DAARION entity model
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Frontend (React)
|
|
↓
|
|
messaging-service (FastAPI)
|
|
↓
|
|
matrix-gateway (internal)
|
|
↓
|
|
Matrix Homeserver (Synapse)
|
|
```
|
|
|
|
## Features
|
|
|
|
✅ Channel management (create, list, update)
|
|
✅ Message sending/receiving
|
|
✅ Real-time WebSocket subscriptions
|
|
✅ Agent posting to channels
|
|
✅ Member invitations (users + agents)
|
|
✅ Threading/replies support
|
|
✅ Reactions (via Matrix)
|
|
✅ Message editing/deletion (via Matrix redaction)
|
|
|
|
## Setup
|
|
|
|
### 1. Prerequisites
|
|
|
|
- Python 3.11+
|
|
- PostgreSQL (with messenger schema migrated)
|
|
- matrix-gateway service running
|
|
- Matrix homeserver (Synapse/Dendrite)
|
|
|
|
### 2. Install dependencies
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
### 3. Environment variables
|
|
|
|
```bash
|
|
export DATABASE_URL="postgresql://user:pass@localhost:5432/daarion"
|
|
export MATRIX_GATEWAY_URL="http://matrix-gateway:7003"
|
|
export MATRIX_GATEWAY_SECRET="your-shared-secret"
|
|
export NATS_URL="nats://localhost:4222"
|
|
```
|
|
|
|
### 4. Run migrations
|
|
|
|
```bash
|
|
psql -d daarion -f ../../migrations/001_create_messenger_schema.sql
|
|
```
|
|
|
|
### 5. Start service
|
|
|
|
```bash
|
|
uvicorn main:app --host 0.0.0.0 --port 7004 --reload
|
|
```
|
|
|
|
Service will be available at `http://localhost:7004`
|
|
|
|
## API Documentation
|
|
|
|
Interactive API docs: http://localhost:7004/docs
|
|
|
|
### Key endpoints
|
|
|
|
#### Channels
|
|
- `GET /api/messaging/channels` — List channels
|
|
- `POST /api/messaging/channels` — Create channel (creates Matrix room)
|
|
- `GET /api/messaging/channels/{id}` — Get channel details
|
|
|
|
#### Messages
|
|
- `GET /api/messaging/channels/{id}/messages` — List messages (paginated)
|
|
- `POST /api/messaging/channels/{id}/messages` — Send message
|
|
|
|
#### Members
|
|
- `GET /api/messaging/channels/{id}/members` — List members
|
|
- `POST /api/messaging/channels/{id}/members` — Invite member
|
|
|
|
#### WebSocket
|
|
- `WS /ws/messaging/{channel_id}` — Real-time message stream
|
|
|
|
#### Internal (agent integration)
|
|
- `POST /internal/agents/{agent_id}/post-to-channel` — Agent posting
|
|
|
|
## Matrix Integration
|
|
|
|
### Channel → Room mapping
|
|
|
|
Every DAARION channel is backed by a Matrix room:
|
|
|
|
| DAARION | Matrix |
|
|
|---------|--------|
|
|
| `channels.id` | Unique UUID |
|
|
| `channels.matrix_room_id` | `!roomid:daarion.city` |
|
|
| `channels.slug` | Room alias (`#slug:daarion.city`) |
|
|
| `channels.visibility` | Room visibility (`public`/`private`) |
|
|
|
|
### Message → Event mapping
|
|
|
|
DAARION messages are indexed references to Matrix events:
|
|
|
|
| DAARION | Matrix |
|
|
|---------|--------|
|
|
| `messages.id` | Unique UUID |
|
|
| `messages.matrix_event_id` | `$eventid:daarion.city` |
|
|
| `messages.content_preview` | Truncated text (full in Matrix) |
|
|
| `messages.sender_id` | DAARION entity ID (`user:...`, `agent:...`) |
|
|
| `messages.sender_matrix_id` | Matrix user ID (`@user:server`) |
|
|
|
|
### Why index messages?
|
|
|
|
We don't duplicate Matrix events in full, only index them for:
|
|
- Fast listing and pagination
|
|
- MicroDAO context filtering
|
|
- Agent memory integration
|
|
- Task/project linking
|
|
- Analytics and metrics
|
|
|
|
Full message content is always fetched from Matrix when needed.
|
|
|
|
## Database Schema
|
|
|
|
See `../../migrations/001_create_messenger_schema.sql`
|
|
|
|
Key tables:
|
|
- `channels` — Channel metadata + Matrix room mapping
|
|
- `messages` — Message index (not full content)
|
|
- `channel_members` — Membership + permissions
|
|
- `message_reactions` — Reactions index
|
|
- `channel_events` — Audit log
|
|
|
|
## NATS Events
|
|
|
|
Published by messaging-service:
|
|
|
|
### `messaging.message.created`
|
|
```json
|
|
{
|
|
"channel_id": "uuid",
|
|
"matrix_event_id": "$event:server",
|
|
"sender_id": "user:alice",
|
|
"sender_type": "human",
|
|
"preview": "Hello world",
|
|
"created_at": "2025-11-24T10:30:00Z"
|
|
}
|
|
```
|
|
|
|
### `messaging.channel.created`
|
|
```json
|
|
{
|
|
"channel_id": "uuid",
|
|
"microdao_id": "microdao:7",
|
|
"matrix_room_id": "!room:server",
|
|
"created_by": "user:alice"
|
|
}
|
|
```
|
|
|
|
### `messaging.member.invited`
|
|
```json
|
|
{
|
|
"channel_id": "uuid",
|
|
"member_id": "agent:sofia",
|
|
"invited_by": "user:admin",
|
|
"role": "agent"
|
|
}
|
|
```
|
|
|
|
## Agent Integration
|
|
|
|
Agents can post to channels via internal API:
|
|
|
|
```python
|
|
POST /internal/agents/agent:sofia/post-to-channel
|
|
{
|
|
"channel_id": "uuid",
|
|
"text": "Hello from Sofia!"
|
|
}
|
|
```
|
|
|
|
Requirements:
|
|
- Agent must be a member of the channel
|
|
- Agent posts are sent as `m.notice` messages in Matrix
|
|
- Agent messages are indexed with `sender_type="agent"`
|
|
|
|
## WebSocket Protocol
|
|
|
|
Connect to `/ws/messaging/{channel_id}`:
|
|
|
|
**Client → Server:**
|
|
```json
|
|
"ping"
|
|
```
|
|
|
|
**Server → Client:**
|
|
```json
|
|
"pong"
|
|
```
|
|
|
|
**Server → Client (new message):**
|
|
```json
|
|
{
|
|
"type": "message.created",
|
|
"message": {
|
|
"id": "uuid",
|
|
"channel_id": "uuid",
|
|
"sender_id": "user:alice",
|
|
"content_preview": "Hello!",
|
|
"created_at": "2025-11-24T10:30:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Element Compatibility
|
|
|
|
All channels created via messaging-service are **visible in Element**:
|
|
- Same Matrix homeserver
|
|
- Standard Matrix room types
|
|
- Federation enabled (optional)
|
|
- E2EE support (optional, per channel)
|
|
|
|
Users can use Element, DAARION UI, or any Matrix client interchangeably.
|
|
|
|
## Security
|
|
|
|
- **Authentication:** X-User-Id header (TODO: replace with JWT)
|
|
- **Authorization:** Channel membership + permissions checked
|
|
- **Matrix gateway:** Internal service, not exposed to public
|
|
- **Confidential mode:** E2EE channels, content not indexed
|
|
|
|
## Testing
|
|
|
|
### Manual testing with httpx
|
|
|
|
```python
|
|
import httpx
|
|
|
|
# Create channel
|
|
resp = httpx.post(
|
|
"http://localhost:7004/api/messaging/channels",
|
|
headers={"X-User-Id": "user:admin"},
|
|
json={
|
|
"slug": "test",
|
|
"name": "Test Channel",
|
|
"microdao_id": "microdao:daarion",
|
|
"visibility": "public"
|
|
}
|
|
)
|
|
channel = resp.json()
|
|
|
|
# Send message
|
|
resp = httpx.post(
|
|
f"http://localhost:7004/api/messaging/channels/{channel['id']}/messages",
|
|
headers={"X-User-Id": "user:alice"},
|
|
json={
|
|
"text": "Hello from Alice!"
|
|
}
|
|
)
|
|
message = resp.json()
|
|
```
|
|
|
|
### Testing with Element
|
|
|
|
1. Login to Element with Matrix user
|
|
2. Join room by alias: `#test-daarion:daarion.city`
|
|
3. Send message in Element
|
|
4. Check it appears in DAARION UI (via `/api/messaging/channels/.../messages`)
|
|
|
|
## Deployment
|
|
|
|
### Docker
|
|
|
|
```bash
|
|
docker build -t daarion/messaging-service .
|
|
docker run -p 7004:7004 \
|
|
-e DATABASE_URL="postgresql://..." \
|
|
-e MATRIX_GATEWAY_URL="http://matrix-gateway:7003" \
|
|
daarion/messaging-service
|
|
```
|
|
|
|
### Docker Compose
|
|
|
|
See `../../docker-compose.yml` for full stack deployment.
|
|
|
|
### Production checklist
|
|
|
|
- [ ] Enable JWT authentication (replace X-User-Id header)
|
|
- [ ] Add rate limiting (per user, per channel)
|
|
- [ ] Enable NATS event publishing
|
|
- [ ] Configure Matrix webhook subscriptions
|
|
- [ ] Set up monitoring (Prometheus metrics)
|
|
- [ ] Configure logging (structured JSON)
|
|
- [ ] Enable HTTPS/TLS for WebSocket
|
|
- [ ] Set DATABASE_URL from secrets
|
|
- [ ] Set MATRIX_GATEWAY_SECRET from secrets
|
|
|
|
## Roadmap
|
|
|
|
### v1.1
|
|
- [ ] NATS JetStream integration
|
|
- [ ] Matrix webhook subscription (push model)
|
|
- [ ] Message search (full-text via PostgreSQL)
|
|
- [ ] Typing indicators
|
|
- [ ] Read receipts
|
|
|
|
### v1.2
|
|
- [ ] Voice messages
|
|
- [ ] File uploads (via Matrix media API)
|
|
- [ ] Link previews
|
|
- [ ] Message pinning
|
|
|
|
### v2.0
|
|
- [ ] End-to-end encryption (E2EE) support
|
|
- [ ] Voice/video calls (via Matrix VoIP)
|
|
- [ ] Spaces support (channel groups)
|
|
|
|
## Troubleshooting
|
|
|
|
### "Failed to create Matrix room"
|
|
|
|
Check matrix-gateway is running:
|
|
```bash
|
|
curl http://localhost:7003/health
|
|
```
|
|
|
|
### "Database connection failed"
|
|
|
|
Check PostgreSQL is running and migrations applied:
|
|
```bash
|
|
psql -d daarion -c "SELECT COUNT(*) FROM channels;"
|
|
```
|
|
|
|
### WebSocket disconnects immediately
|
|
|
|
Check CORS settings and WebSocket upgrade headers.
|
|
|
|
## License
|
|
|
|
MIT
|
|
|
|
## Maintainer
|
|
|
|
DAARION Platform Team
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|