# Typing Indicators Investigation ## Overview This document outlines how to investigate and implement typing indicators for the Kosmi bridge. Typing indicators show when users are actively typing messages. ## Monitoring Approach ### Using the Auth Monitoring Script The `cmd/monitor-auth/main.go` script already captures all WebSocket traffic. To investigate typing indicators: ```bash # Run the monitoring script ./bin/monitor-auth -room "https://app.kosmi.io/room/@hyperspaceout" # In the Kosmi room, start typing (but don't send) # Watch the console output for WebSocket messages ``` ### What to Look For Typing indicators are typically implemented as: 1. **GraphQL Subscription** (receiving typing events): ```graphql subscription { userTyping(roomId: "...") { user { id displayName } isTyping } } ``` 2. **GraphQL Mutation** (sending typing status): ```graphql mutation { setTyping(roomId: "...", isTyping: true) } ``` 3. **WebSocket Message Format**: - Look for messages with type `"next"` or `"data"` - Payload might contain `userTyping`, `typing`, `isTyping`, or similar fields - Usually sent when user starts/stops typing ### Expected Message Patterns **When user starts typing:** ```json { "type": "next", "id": "typing-subscription", "payload": { "data": { "userTyping": { "user": { "id": "user-123", "displayName": "Alice" }, "isTyping": true } } } } ``` **When user stops typing:** ```json { "type": "next", "id": "typing-subscription", "payload": { "data": { "userTyping": { "user": { "id": "user-123", "displayName": "Alice" }, "isTyping": false } } } } ``` ## Implementation Plan Once typing indicators are discovered: ### 1. Add Subscription to GraphQL Client In `bridge/kosmi/graphql_ws_client.go`, add a typing subscription: ```go func (c *GraphQLWSClient) subscribeToTyping() error { typingMsg := WSMessage{ ID: "subscribe-typing", Type: messageTypeSubscribe, Payload: map[string]interface{}{ "query": `subscription OnUserTyping($roomId: String!) { userTyping(roomId: $roomId) { user { id displayName username } isTyping } }`, "variables": map[string]interface{}{ "roomId": c.roomID, }, }, } return c.conn.WriteJSON(typingMsg) } ``` ### 2. Handle Typing Events Add a callback for typing events: ```go type TypingPayload struct { Data struct { UserTyping struct { User struct { ID string `json:"id"` DisplayName string `json:"displayName"` Username string `json:"username"` } `json:"user"` IsTyping bool `json:"isTyping"` } `json:"userTyping"` } `json:"data"` } func (c *GraphQLWSClient) OnTyping(callback func(*TypingPayload)) { c.typingCallback = callback } ``` ### 3. Send Typing Status Add a method to send typing status: ```go func (c *GraphQLWSClient) SendTyping(isTyping bool) error { msg := WSMessage{ ID: fmt.Sprintf("set-typing-%d", time.Now().Unix()), Type: messageTypeSubscribe, Payload: map[string]interface{}{ "query": `mutation SetTyping($roomId: String!, $isTyping: Boolean!) { setTyping(roomId: $roomId, isTyping: $isTyping) { ok } }`, "variables": map[string]interface{}{ "roomId": c.roomID, "isTyping": isTyping, }, }, } return c.conn.WriteJSON(msg) } ``` ### 4. Integrate with Matterbridge In `bridge/kosmi/kosmi.go`, map typing events to Matterbridge: ```go func (b *Bkosmi) handleTypingEvent(payload *TypingPayload) { username := payload.Data.UserTyping.User.DisplayName if username == "" { username = payload.Data.UserTyping.User.Username } rmsg := config.Message{ Username: username, Channel: "main", Account: b.Account, Event: config.EventUserTyping, Protocol: "kosmi", } if payload.Data.UserTyping.IsTyping { b.Remote <- rmsg } } ``` ### 5. Send Typing from IRC When IRC users type, send typing indicator to Kosmi: ```go func (b *Bkosmi) Send(msg config.Message) (string, error) { // Handle typing indicators if msg.Event == config.EventUserTyping { if b.client != nil { b.client.SendTyping(true) // Set a timer to send false after 5 seconds time.AfterFunc(5*time.Second, func() { b.client.SendTyping(false) }) } return "", nil } // ... rest of Send implementation } ``` ## Use Cases ### 1. Show Typing in IRC When Kosmi users type, show in IRC: ``` *** Alice is typing... ``` ### 2. Show Typing in Kosmi When IRC users type, send typing indicator to Kosmi. ### 3. Fake Typing During Image Generation When generating room code images (which takes ~2-3 seconds), send typing indicator: ```go func (b *Bkosmi) sendRoomCodeImage(roomCode string) error { // Send typing indicator if b.client != nil { b.client.SendTyping(true) defer b.client.SendTyping(false) } // Generate and send image // ... } ``` This makes the bot appear more responsive while processing. ## Testing 1. **Manual Testing**: - Run monitoring script - Type in Kosmi (don't send) - Observe WebSocket traffic - Document the message format 2. **Integration Testing**: - Implement typing support - Test bidirectional typing indicators - Verify timing (typing should stop after inactivity) 3. **Edge Cases**: - Multiple users typing simultaneously - Typing indicator timeout - Connection loss during typing ## Status - ✅ Monitoring script created (`cmd/monitor-auth/main.go`) - ⏳ **TODO**: Run monitoring script and capture typing events - ⏳ **TODO**: Document actual message format - ⏳ **TODO**: Implement typing support (optional) ## Notes - Typing indicators are a "nice to have" feature - Implementation depends on Kosmi actually supporting them - If not supported, this can be skipped - The monitoring script is ready to capture the traffic when needed