Files
IRC-kosmi-relay/TYPING_INDICATORS.md

284 lines
6.4 KiB
Markdown
Raw Normal View History

2025-11-01 21:00:16 -04:00
# 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