Files
IRC-kosmi-relay/FINDINGS.md

219 lines
4.8 KiB
Markdown
Raw Normal View History

2025-10-31 16:17:04 -04:00
# Kosmi API Reverse Engineering Findings
## Key Discovery: HTTP POST Works!
After browser-based investigation, we discovered that Kosmi's GraphQL API works via **HTTP POST**, not just WebSocket!
### Working Endpoint
```
POST https://engine.kosmi.io/
Content-Type: application/json
{
"query": "{ __schema { types { name } } }"
}
```
**Response**: ✅ 200 OK with proper GraphQL response
### WebSocket Issue
The WebSocket endpoint `wss://engine.kosmi.io/gql-ws` returns **403 Forbidden** when connecting directly because:
1. **Missing Cookies**: The browser has session cookies that aren't accessible via `document.cookie` (HTTP-only)
2. **Missing Headers**: Likely needs `Origin: https://app.kosmi.io` header
3. **Session Required**: May need to establish a session first via HTTP
## Implementation Options
### Option 1: HTTP POST with Polling (Recommended for Now)
**Pros**:
- ✅ Works without authentication
- ✅ Simple implementation
- ✅ No WebSocket complexity
**Cons**:
- ❌ Not real-time (need to poll)
- ❌ Higher latency
- ❌ More bandwidth usage
**Implementation**:
```go
// Poll for new messages every 1-2 seconds
func (c *GraphQLClient) PollMessages() {
ticker := time.NewTicker(2 * time.Second)
for range ticker.C {
// Query for messages since last timestamp
messages := c.QueryMessages(lastTimestamp)
// Process new messages
}
}
```
### Option 2: WebSocket with Session Cookies
**Pros**:
- ✅ Real-time updates
- ✅ Efficient (push-based)
- ✅ Lower latency
**Cons**:
- ❌ Requires session establishment
- ❌ Need to handle cookies
- ❌ More complex
**Implementation**:
```go
// 1. First, establish session via HTTP
session := establishSession()
// 2. Then connect WebSocket with cookies
dialer := websocket.Dialer{
Jar: session.CookieJar,
}
conn, _, err := dialer.Dial(wsURL, http.Header{
"Origin": []string{"https://app.kosmi.io"},
"Cookie": []string{session.Cookies},
})
```
### Option 3: Hybrid Approach
**Best of both worlds**:
1. Use HTTP POST for sending messages (mutations)
2. Use HTTP POST polling for receiving messages (queries)
3. Later upgrade to WebSocket when we figure out auth
## Next Steps
### Immediate (HTTP-based)
1. ✅ Update `graphql.go` to use HTTP POST instead of WebSocket
2. ✅ Implement message polling
3. ✅ Test with actual Kosmi room
4. ✅ Verify message sending works
### Future (WebSocket-based)
1. ⏳ Figure out session establishment
2. ⏳ Extract cookies from browser or create session
3. ⏳ Update WebSocket connection to include cookies
4. ⏳ Switch from polling to real-time subscriptions
## GraphQL Schema Discovery
From the introspection query, we found these types:
- `RootQueryType` - For queries
- `RootMutationType` - For mutations
- `Session` - Session management
- `Success` - Success responses
We need to explore the schema more to find:
- Message query fields
- Message mutation fields
- Room/channel structures
## Testing Commands
### Test HTTP Endpoint
```bash
curl -X POST https://engine.kosmi.io/ \
-H "Content-Type: application/json" \
-d '{"query": "{ __schema { types { name } } }"}'
```
### Test with Go
```go
resp, err := http.Post(
"https://engine.kosmi.io/",
"application/json",
strings.NewReader(`{"query": "{ __schema { types { name } } }"}`),
)
```
## Browser Findings
### Cookies Present
```
g_state={...}
```
Plus HTTP-only cookies we can't access.
### User Agent
```
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
```
### Origin
```
https://app.kosmi.io
```
## Recommendations
**For MVP**: Use HTTP POST with polling
- Simpler to implement
- Works without authentication
- Good enough for initial testing
- Can upgrade to WebSocket later
**For Production**: Figure out WebSocket auth
- Better performance
- Real-time updates
- Lower bandwidth
- Better user experience
## Updated Architecture
```
IRC Message
Matterbridge
Kosmi Bridge (HTTP POST)
POST https://engine.kosmi.io/
Kosmi Room
Kosmi Room
Poll https://engine.kosmi.io/ (every 2s)
Kosmi Bridge
Matterbridge
IRC Message
```
## Action Items
1. **Update `graphql.go`**:
- Replace WebSocket with HTTP client
- Implement POST request method
- Add polling loop for messages
2. **Test queries**:
- Find the correct query for fetching messages
- Find the correct mutation for sending messages
- Test with actual room ID
3. **Implement polling**:
- Poll every 1-2 seconds
- Track last message timestamp
- Only fetch new messages
4. **Document limitations**:
- Note the polling delay
- Explain why WebSocket doesn't work yet
- Provide upgrade path
---
**Status**: HTTP POST endpoint discovered and verified ✅
**Next**: Implement HTTP-based client to replace WebSocket