4.8 KiB
4.8 KiB
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:
- Missing Cookies: The browser has session cookies that aren't accessible via
document.cookie(HTTP-only) - Missing Headers: Likely needs
Origin: https://app.kosmi.ioheader - 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:
// 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:
// 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:
- Use HTTP POST for sending messages (mutations)
- Use HTTP POST polling for receiving messages (queries)
- Later upgrade to WebSocket when we figure out auth
Next Steps
Immediate (HTTP-based)
- ✅ Update
graphql.goto use HTTP POST instead of WebSocket - ✅ Implement message polling
- ✅ Test with actual Kosmi room
- ✅ Verify message sending works
Future (WebSocket-based)
- ⏳ Figure out session establishment
- ⏳ Extract cookies from browser or create session
- ⏳ Update WebSocket connection to include cookies
- ⏳ Switch from polling to real-time subscriptions
GraphQL Schema Discovery
From the introspection query, we found these types:
RootQueryType- For queriesRootMutationType- For mutationsSession- Session managementSuccess- 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
curl -X POST https://engine.kosmi.io/ \
-H "Content-Type: application/json" \
-d '{"query": "{ __schema { types { name } } }"}'
Test with 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
-
Update
graphql.go:- Replace WebSocket with HTTP client
- Implement POST request method
- Add polling loop for messages
-
Test queries:
- Find the correct query for fetching messages
- Find the correct mutation for sending messages
- Test with actual room ID
-
Implement polling:
- Poll every 1-2 seconds
- Track last message timestamp
- Only fetch new messages
-
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