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>
284 lines
6.4 KiB
Markdown
284 lines
6.4 KiB
Markdown
# 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
|
|
|