working v1
This commit is contained in:
276
README.md
Normal file
276
README.md
Normal file
@@ -0,0 +1,276 @@
|
||||
# Kosmi-IRC Relay via Matterbridge
|
||||
|
||||
A Matterbridge plugin that bridges Kosmi chat rooms with IRC channels, enabling bidirectional message relay.
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ Real-time message relay between Kosmi and IRC
|
||||
- ✅ Headless Chrome automation for reliable Kosmi connection
|
||||
- ✅ WebSocket interception using Chrome DevTools Protocol
|
||||
- ✅ Anonymous Kosmi access (no authentication required)
|
||||
- ✅ Message formatting with source indicators
|
||||
- ✅ Automatic reconnection handling
|
||||
- ✅ Support for any Kosmi room via URL configuration
|
||||
|
||||
## Architecture
|
||||
|
||||
This implementation extends Matterbridge with a custom Kosmi bridge that:
|
||||
|
||||
1. Launches a headless Chrome instance using `chromedp`
|
||||
2. Navigates to the Kosmi room and injects a WebSocket interceptor **before page load**
|
||||
3. Captures GraphQL WebSocket messages (`wss://engine.kosmi.io/gql-ws`) from the page
|
||||
4. Relays messages bidirectionally with proper formatting:
|
||||
- **Kosmi → IRC**: `[Kosmi] <username> message`
|
||||
- **IRC → Kosmi**: `[IRC] <username> message`
|
||||
|
||||
### Why Headless Chrome?
|
||||
|
||||
Kosmi's WebSocket API requires browser session cookies and context that are difficult to replicate with a native WebSocket client. Using headless Chrome automation ensures:
|
||||
- ✅ Automatic session management
|
||||
- ✅ Proper cookie handling
|
||||
- ✅ Reliable WebSocket connection
|
||||
- ✅ No authentication complexity
|
||||
|
||||
## Installation
|
||||
|
||||
### Option 1: Docker (Recommended) 🐳
|
||||
|
||||
The easiest way to run the bridge:
|
||||
|
||||
```bash
|
||||
# 1. Edit configuration
|
||||
nano matterbridge.toml
|
||||
|
||||
# 2. Build and run
|
||||
docker-compose up -d
|
||||
|
||||
# 3. View logs
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
**See**: `DOCKER_QUICKSTART.md` for 5-minute setup guide
|
||||
|
||||
### Option 2: Build from Source
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- Go 1.21 or higher
|
||||
- Chrome or Chromium browser installed
|
||||
- Access to an IRC server
|
||||
- A Kosmi room URL
|
||||
|
||||
#### Building
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone <repository-url>
|
||||
cd irc-kosmi-relay
|
||||
|
||||
# Download dependencies
|
||||
go mod download
|
||||
|
||||
# Build the bridge
|
||||
go build -o matterbridge
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `matterbridge.toml` to configure your bridge:
|
||||
|
||||
```toml
|
||||
# Kosmi configuration
|
||||
[kosmi.hyperspaceout]
|
||||
RoomURL="https://app.kosmi.io/room/@hyperspaceout"
|
||||
|
||||
# IRC configuration
|
||||
[irc.libera]
|
||||
Server="irc.libera.chat:6667"
|
||||
Nick="kosmi-relay"
|
||||
UseTLS=false
|
||||
|
||||
# Gateway to connect Kosmi and IRC
|
||||
[[gateway]]
|
||||
name="kosmi-irc-gateway"
|
||||
enable=true
|
||||
|
||||
[[gateway.inout]]
|
||||
account="kosmi.hyperspaceout"
|
||||
channel="main"
|
||||
|
||||
[[gateway.inout]]
|
||||
account="irc.libera"
|
||||
channel="#your-channel"
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
|
||||
#### Kosmi Settings
|
||||
|
||||
- `RoomURL` (required): Full URL to the Kosmi room
|
||||
- Format: `https://app.kosmi.io/room/@roomname` or `https://app.kosmi.io/room/roomid`
|
||||
- `Server` (optional): WebSocket endpoint (default: `wss://engine.kosmi.io/gql-ws`)
|
||||
- `Debug` (optional): Enable debug logging
|
||||
|
||||
#### IRC Settings
|
||||
|
||||
See [Matterbridge IRC documentation](https://github.com/42wim/matterbridge/wiki/Section-IRC-(basic)) for full IRC configuration options.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Run the bridge
|
||||
./matterbridge -conf matterbridge.toml
|
||||
|
||||
# Run with debug logging
|
||||
./matterbridge -conf matterbridge.toml -debug
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
### Kosmi Connection
|
||||
|
||||
The bridge connects to Kosmi using headless Chrome automation:
|
||||
|
||||
1. **Launch Chrome**: Starts a headless Chrome instance via `chromedp`
|
||||
2. **Inject Hook**: Uses `Page.addScriptToEvaluateOnNewDocument` to inject a WebSocket interceptor **before any page scripts run**
|
||||
3. **Navigate**: Loads the Kosmi room URL
|
||||
4. **Intercept**: The injected script hooks `window.WebSocket` constructor to capture all WebSocket messages
|
||||
5. **Poll**: Continuously polls the message queue populated by the interceptor
|
||||
6. **Process**: Extracts chat messages from GraphQL subscription data
|
||||
|
||||
### Critical Implementation Detail
|
||||
|
||||
The WebSocket hook **must** be injected before page load using `Page.addScriptToEvaluateOnNewDocument`. This ensures the hook is active when Kosmi's JavaScript creates the WebSocket connection. If injected after page load, the WebSocket will already be established and messages won't be captured.
|
||||
|
||||
### Message Flow
|
||||
|
||||
```
|
||||
IRC User → IRC Server → Matterbridge → Headless Chrome → Kosmi Room
|
||||
Kosmi User → Kosmi Room → WebSocket → Chrome Interceptor → Matterbridge → IRC Server → IRC Channel
|
||||
```
|
||||
|
||||
### Message Filtering
|
||||
|
||||
- The bridge ignores its own messages by checking for the `[IRC]` prefix
|
||||
- This prevents message loops between Kosmi and IRC
|
||||
|
||||
## Technical Details
|
||||
|
||||
### GraphQL API
|
||||
|
||||
The Kosmi bridge uses the following GraphQL operations:
|
||||
|
||||
**Subscription** (receiving messages):
|
||||
```graphql
|
||||
subscription {
|
||||
newMessage(roomId: "roomId") {
|
||||
body
|
||||
time
|
||||
user {
|
||||
displayName
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Mutation** (sending messages):
|
||||
```graphql
|
||||
mutation {
|
||||
sendMessage(roomId: "roomId", body: "message text") {
|
||||
id
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
bridge/kosmi/
|
||||
├── kosmi.go # Main bridge implementation
|
||||
├── chromedp_client.go # Headless Chrome client with WebSocket interception
|
||||
└── graphql.go # GraphQL message structures (deprecated native client)
|
||||
|
||||
gateway/bridgemap/
|
||||
└── bkosmi.go # Bridge registration
|
||||
|
||||
cmd/test-kosmi/
|
||||
└── main.go # Standalone test program
|
||||
|
||||
matterbridge.toml # Configuration file
|
||||
go.mod # Go module dependencies
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connection Issues
|
||||
|
||||
**Problem**: Bridge fails to connect to Kosmi
|
||||
|
||||
**Solutions**:
|
||||
- Verify Chrome/Chromium is installed: `which google-chrome chromium chromium-browser`
|
||||
- Verify the room URL is correct
|
||||
- Check network connectivity to `app.kosmi.io`
|
||||
- Enable debug logging to see detailed connection logs
|
||||
- Look for "✓ WebSocket hook confirmed installed" in logs
|
||||
- Look for "Status: WebSocket connection intercepted" in logs
|
||||
|
||||
### Message Not Relaying
|
||||
|
||||
**Problem**: Messages aren't being relayed between Kosmi and IRC
|
||||
|
||||
**Solutions**:
|
||||
- Verify both Kosmi and IRC connections are established
|
||||
- Check the gateway configuration in `matterbridge.toml`
|
||||
- Ensure channel names match in the gateway configuration
|
||||
- Check logs for errors
|
||||
|
||||
### Authentication Errors
|
||||
|
||||
**Problem**: Kosmi connection fails with authentication error
|
||||
|
||||
**Note**: Kosmi doesn't require authentication. If you see auth errors, verify:
|
||||
- The WebSocket URL is correct
|
||||
- The room ID is valid
|
||||
- Network isn't blocking WebSocket connections
|
||||
|
||||
## Development
|
||||
|
||||
### Adding Features
|
||||
|
||||
The bridge follows Matterbridge's bridge interface:
|
||||
|
||||
```go
|
||||
type Bridger interface {
|
||||
Send(msg config.Message) (string, error)
|
||||
Connect() error
|
||||
JoinChannel(channel config.ChannelInfo) error
|
||||
Disconnect() error
|
||||
}
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
To test the bridge:
|
||||
|
||||
1. Start the bridge with debug logging
|
||||
2. Send a message in the Kosmi room
|
||||
3. Verify it appears in IRC with `[Kosmi]` prefix
|
||||
4. Send a message in IRC
|
||||
5. Verify it appears in Kosmi with `[IRC]` prefix
|
||||
|
||||
## Known Limitations
|
||||
|
||||
1. **Anonymous Access**: The bridge connects anonymously to Kosmi, so it will have a randomly assigned username
|
||||
2. **Message Sending**: The GraphQL mutation for sending messages may need adjustment based on Kosmi's actual API
|
||||
3. **Room Discovery**: The bridge connects to a specific room; it doesn't support room discovery or listing
|
||||
|
||||
## Credits
|
||||
|
||||
- Based on [Matterbridge](https://github.com/42wim/matterbridge) by 42wim
|
||||
- Kosmi API reverse engineering from chrome extension analysis
|
||||
|
||||
## License
|
||||
|
||||
Same as Matterbridge (Apache 2.0)
|
||||
|
||||
Reference in New Issue
Block a user