6.4 KiB
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:
# 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:
-
GraphQL Subscription (receiving typing events):
subscription { userTyping(roomId: "...") { user { id displayName } isTyping } } -
GraphQL Mutation (sending typing status):
mutation { setTyping(roomId: "...", isTyping: true) } -
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
- Look for messages with type
Expected Message Patterns
When user starts typing:
{
"type": "next",
"id": "typing-subscription",
"payload": {
"data": {
"userTyping": {
"user": {
"id": "user-123",
"displayName": "Alice"
},
"isTyping": true
}
}
}
}
When user stops typing:
{
"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:
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:
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:
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:
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:
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:
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
-
Manual Testing:
- Run monitoring script
- Type in Kosmi (don't send)
- Observe WebSocket traffic
- Document the message format
-
Integration Testing:
- Implement typing support
- Test bidirectional typing indicators
- Verify timing (typing should stop after inactivity)
-
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