Files
IRC-kosmi-relay/docs/TYPING_INDICATORS.md
cottongin db284d0677 Move troubleshooting and implementation docs to docs/
Relocate 30 non-essential .md files (investigation notes, fix summaries,
implementation details, status reports) from the project root into docs/
to reduce clutter. Core operational docs (README, quickstart guides,
configuration references) remain in the root.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 13:40:46 -05:00

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:

  1. GraphQL Subscription (receiving typing events):

    subscription {
      userTyping(roomId: "...") {
        user {
          id
          displayName
        }
        isTyping
      }
    }
    
  2. GraphQL Mutation (sending typing status):

    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:

{
  "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

  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