Fix stale cmd/ scripts, export LoginWithChromedp, clean up vet warnings
Update 5 cmd/ test utilities that referenced APIs that drifted after bridge refactors (NewBrowserAuthManager, bridge.NewConfig, changed function signatures). Rewrite test-kosmi and test-native to use NewGraphQLWSClient directly. Export LoginWithChromedp for use by cmd scripts. Fix redundant-newline vet warnings across 5 cmd/ files. Remove unreachable code and replace deprecated ioutil calls in bridge/helper/lottie_convert.go. Made-with: Cursor
This commit is contained in:
@@ -3,7 +3,6 @@
|
|||||||
package helper
|
package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ func CanConvertTgsToX() error {
|
|||||||
// This relies on an external command, which is ugly, but works.
|
// This relies on an external command, which is ugly, but works.
|
||||||
func ConvertTgsToX(data *[]byte, outputFormat string, logger *logrus.Entry) error {
|
func ConvertTgsToX(data *[]byte, outputFormat string, logger *logrus.Entry) error {
|
||||||
// lottie can't handle input from a pipe, so write to a temporary file:
|
// lottie can't handle input from a pipe, so write to a temporary file:
|
||||||
tmpInFile, err := ioutil.TempFile(os.TempDir(), "matterbridge-lottie-input-*.tgs")
|
tmpInFile, err := os.CreateTemp(os.TempDir(), "matterbridge-lottie-input-*.tgs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -35,7 +34,7 @@ func ConvertTgsToX(data *[]byte, outputFormat string, logger *logrus.Entry) erro
|
|||||||
}()
|
}()
|
||||||
// lottie can handle writing to a pipe, but there is no way to do that platform-independently.
|
// lottie can handle writing to a pipe, but there is no way to do that platform-independently.
|
||||||
// "/dev/stdout" won't work on Windows, and "-" upsets Cairo for some reason. So we need another file:
|
// "/dev/stdout" won't work on Windows, and "-" upsets Cairo for some reason. So we need another file:
|
||||||
tmpOutFile, err := ioutil.TempFile(os.TempDir(), "matterbridge-lottie-output-*.data")
|
tmpOutFile, err := os.CreateTemp(os.TempDir(), "matterbridge-lottie-output-*.data")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -64,7 +63,7 @@ func ConvertTgsToX(data *[]byte, outputFormat string, logger *logrus.Entry) erro
|
|||||||
// 'stderr' already contains some parts of Stderr, because it was set to 'nil'.
|
// 'stderr' already contains some parts of Stderr, because it was set to 'nil'.
|
||||||
return stderr
|
return stderr
|
||||||
}
|
}
|
||||||
dataContents, err := ioutil.ReadFile(tmpOutFileName)
|
dataContents, err := os.ReadFile(tmpOutFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -82,7 +81,6 @@ func SupportsFormat(format string) bool {
|
|||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func LottieBackend() string {
|
func LottieBackend() string {
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// loginWithChromedp uses browser automation to log in and extract the JWT token.
|
// LoginWithChromedp uses browser automation to log in and extract the JWT token.
|
||||||
// This is the proven implementation that successfully authenticates users.
|
// This is the proven implementation that successfully authenticates users.
|
||||||
func loginWithChromedp(email, password string, log *logrus.Entry) (string, error) {
|
func LoginWithChromedp(email, password string, log *logrus.Entry) (string, error) {
|
||||||
log.Info("Starting browser automation for authentication...")
|
log.Info("Starting browser automation for authentication...")
|
||||||
|
|
||||||
// Create context with timeout
|
// Create context with timeout
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ func (b *Bkosmi) Connect() error {
|
|||||||
} else {
|
} else {
|
||||||
// No valid cache, authenticate with browser
|
// No valid cache, authenticate with browser
|
||||||
b.Log.Info("Authenticating with email/password...")
|
b.Log.Info("Authenticating with email/password...")
|
||||||
token, err = loginWithChromedp(email, password, b.Log)
|
token, err = LoginWithChromedp(email, password, b.Log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("authentication failed: %w", err)
|
return fmt.Errorf("authentication failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
bkosmi "github.com/42wim/matterbridge/bridge/kosmi"
|
bkosmi "github.com/42wim/matterbridge/bridge/kosmi"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -36,10 +39,9 @@ func main() {
|
|||||||
fmt.Println(strings.Repeat("=", 80))
|
fmt.Println(strings.Repeat("=", 80))
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
// Get anonymous token
|
// Get anonymous token via HTTP (same mutation the client uses internally)
|
||||||
fmt.Println("📝 Step 1: Getting anonymous token...")
|
fmt.Println("📝 Step 1: Getting anonymous token...")
|
||||||
client := bkosmi.NewGraphQLWSClient("https://app.kosmi.io/room/@test", "@test", entry)
|
anonToken, err := getAnonymousToken()
|
||||||
anonToken, err := client.GetAnonymousTokenForTest()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("❌ Failed to get anonymous token: %v\n", err)
|
fmt.Printf("❌ Failed to get anonymous token: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -47,10 +49,9 @@ func main() {
|
|||||||
fmt.Printf("✅ Anonymous token obtained (length: %d)\n", len(anonToken))
|
fmt.Printf("✅ Anonymous token obtained (length: %d)\n", len(anonToken))
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
// Get authenticated token
|
// Get authenticated token via browser automation
|
||||||
fmt.Println("📝 Step 2: Getting authenticated token via browser...")
|
fmt.Println("📝 Step 2: Getting authenticated token via browser...")
|
||||||
browserAuth := bkosmi.NewBrowserAuthManager(email, password, entry)
|
authToken, err := bkosmi.LoginWithChromedp(email, password, entry)
|
||||||
authToken, err := browserAuth.GetToken()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("❌ Failed to get authenticated token: %v\n", err)
|
fmt.Printf("❌ Failed to get authenticated token: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -134,6 +135,49 @@ func printClaims(claims map[string]interface{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAnonymousToken() (string, error) {
|
||||||
|
mutation := map[string]interface{}{
|
||||||
|
"query": `mutation { anonLogin { token } }`,
|
||||||
|
}
|
||||||
|
jsonBody, err := json.Marshal(mutation)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{Timeout: 10 * time.Second}
|
||||||
|
req, err := http.NewRequest("POST", "https://engine.kosmi.io/", bytes.NewReader(jsonBody))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Referer", "https://app.kosmi.io/")
|
||||||
|
req.ContentLength = int64(len(jsonBody))
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return "", fmt.Errorf("HTTP %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
var result map[string]interface{}
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if data, ok := result["data"].(map[string]interface{}); ok {
|
||||||
|
if anonLogin, ok := data["anonLogin"].(map[string]interface{}); ok {
|
||||||
|
if token, ok := anonLogin["token"].(string); ok {
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("no token in response")
|
||||||
|
}
|
||||||
|
|
||||||
func compareClaims(anon, auth map[string]interface{}) {
|
func compareClaims(anon, auth map[string]interface{}) {
|
||||||
allKeys := make(map[string]bool)
|
allKeys := make(map[string]bool)
|
||||||
for k := range anon {
|
for k := range anon {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("=== WebSocket Messages ===\n")
|
fmt.Println("\n=== WebSocket Messages ===")
|
||||||
|
|
||||||
for _, entry := range har.Log.Entries {
|
for _, entry := range har.Log.Entries {
|
||||||
for i, msg := range entry.WebSocketMessages {
|
for i, msg := range entry.WebSocketMessages {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("=== WebSocket Operations (in order) ===\n")
|
fmt.Println("\n=== WebSocket Operations (in order) ===")
|
||||||
|
|
||||||
msgCount := 0
|
msgCount := 0
|
||||||
for _, entry := range har.Log.Entries {
|
for _, entry := range har.Log.Entries {
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
bkosmi "github.com/42wim/matterbridge/bridge/kosmi"
|
bkosmi "github.com/42wim/matterbridge/bridge/kosmi"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -23,7 +26,6 @@ func main() {
|
|||||||
email := os.Args[1]
|
email := os.Args[1]
|
||||||
password := os.Args[2]
|
password := os.Args[2]
|
||||||
|
|
||||||
// Set up logging
|
|
||||||
log := logrus.New()
|
log := logrus.New()
|
||||||
log.SetLevel(logrus.DebugLevel)
|
log.SetLevel(logrus.DebugLevel)
|
||||||
entry := logrus.NewEntry(log)
|
entry := logrus.NewEntry(log)
|
||||||
@@ -31,11 +33,7 @@ func main() {
|
|||||||
fmt.Println("🚀 Testing browser-based authentication...")
|
fmt.Println("🚀 Testing browser-based authentication...")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
// Create browser auth manager
|
token, err := bkosmi.LoginWithChromedp(email, password, entry)
|
||||||
browserAuth := bkosmi.NewBrowserAuthManager(email, password, entry)
|
|
||||||
|
|
||||||
// Get token
|
|
||||||
token, err := browserAuth.GetToken()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("❌ Authentication failed: %v\n", err)
|
fmt.Printf("❌ Authentication failed: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -48,27 +46,32 @@ func main() {
|
|||||||
fmt.Printf("Token length: %d characters\n", len(token))
|
fmt.Printf("Token length: %d characters\n", len(token))
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
// Check if authenticated
|
userID := extractUserIDFromJWT(token)
|
||||||
if browserAuth.IsAuthenticated() {
|
|
||||||
fmt.Println("✅ Token is valid")
|
|
||||||
} else {
|
|
||||||
fmt.Println("❌ Token is invalid or expired")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get user ID
|
|
||||||
userID := browserAuth.GetUserID()
|
|
||||||
if userID != "" {
|
if userID != "" {
|
||||||
fmt.Printf("User ID: %s\n", userID)
|
fmt.Printf("User ID: %s\n", userID)
|
||||||
|
} else {
|
||||||
|
fmt.Println("(Could not extract user ID from token)")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("🎉 Test completed successfully!")
|
fmt.Println("🎉 Test completed successfully!")
|
||||||
}
|
}
|
||||||
|
|
||||||
func min(a, b int) int {
|
func extractUserIDFromJWT(token string) string {
|
||||||
if a < b {
|
parts := strings.Split(token, ".")
|
||||||
return a
|
if len(parts) != 3 {
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
return b
|
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var claims map[string]interface{}
|
||||||
|
if err := json.Unmarshal(payload, &claims); err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if sub, ok := claims["sub"].(string); ok {
|
||||||
|
return sub
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("=== Kosmi Image Upload Test ===\n")
|
fmt.Println("=== Kosmi Image Upload Test ===")
|
||||||
|
|
||||||
// Test 1: Generate a room code image
|
// Test 1: Generate a room code image
|
||||||
fmt.Println("1. Generating room code image for 'TEST'...")
|
fmt.Println("1. Generating room code image for 'TEST'...")
|
||||||
imageData, err := jackbox.GenerateRoomCodeImage("TEST")
|
imageData, err := jackbox.GenerateRoomCodeImage("TEST", "Test Game")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to generate image: %v", err)
|
log.Fatalf("Failed to generate image: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
90
cmd/test-kosmi/main.go
Normal file
90
cmd/test-kosmi/main.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
bkosmi "github.com/42wim/matterbridge/bridge/kosmi"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
roomURL := flag.String("room", "https://app.kosmi.io/room/@hyperspaceout", "Kosmi room URL")
|
||||||
|
debug := flag.Bool("debug", false, "Enable debug logging")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
log := logrus.New()
|
||||||
|
if *debug {
|
||||||
|
log.SetLevel(logrus.DebugLevel)
|
||||||
|
} else {
|
||||||
|
log.SetLevel(logrus.InfoLevel)
|
||||||
|
}
|
||||||
|
log.SetFormatter(&logrus.TextFormatter{FullTimestamp: true})
|
||||||
|
|
||||||
|
logger := log.WithField("bridge", "kosmi-test")
|
||||||
|
|
||||||
|
logger.Info("Starting Kosmi bridge test")
|
||||||
|
logger.Infof("Room URL: %s", *roomURL)
|
||||||
|
|
||||||
|
roomID, err := extractRoomID(*roomURL)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("Failed to extract room ID: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty token = anonymous access
|
||||||
|
client := bkosmi.NewGraphQLWSClient(*roomURL, roomID, "", logger)
|
||||||
|
|
||||||
|
client.OnMessage(func(payload *bkosmi.NewMessagePayload) {
|
||||||
|
username := payload.Data.NewMessage.User.DisplayName
|
||||||
|
if username == "" {
|
||||||
|
username = payload.Data.NewMessage.User.Username
|
||||||
|
}
|
||||||
|
ts := time.Unix(payload.Data.NewMessage.Time, 0)
|
||||||
|
logger.Infof("Received message: [%s] %s: %s",
|
||||||
|
ts.Format("15:04:05"), username, payload.Data.NewMessage.Body)
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.Info("Connecting to Kosmi...")
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
logger.Fatalf("Failed to connect to Kosmi: %v", err)
|
||||||
|
}
|
||||||
|
logger.Info("Successfully connected to Kosmi!")
|
||||||
|
|
||||||
|
logger.Info("Listening for messages... Press Ctrl+C to exit")
|
||||||
|
sigChan := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
logger.Info("Bridge is running. Messages from Kosmi will appear above.")
|
||||||
|
}()
|
||||||
|
|
||||||
|
<-sigChan
|
||||||
|
logger.Info("Shutting down...")
|
||||||
|
|
||||||
|
if err := client.Disconnect(); err != nil {
|
||||||
|
logger.Errorf("Error disconnecting: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("Goodbye!")
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractRoomID(url string) (string, error) {
|
||||||
|
url = strings.TrimSuffix(url, "/")
|
||||||
|
re := regexp.MustCompile(`/room/(@?[a-zA-Z0-9_-]+)`)
|
||||||
|
matches := re.FindStringSubmatch(url)
|
||||||
|
if len(matches) >= 2 {
|
||||||
|
roomID := matches[1]
|
||||||
|
if !strings.HasPrefix(roomID, "@") {
|
||||||
|
roomID = "@" + roomID
|
||||||
|
}
|
||||||
|
return roomID, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("could not extract room ID from URL: %s", url)
|
||||||
|
}
|
||||||
@@ -2,84 +2,88 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/42wim/matterbridge/bridge"
|
|
||||||
bkosmi "github.com/42wim/matterbridge/bridge/kosmi"
|
bkosmi "github.com/42wim/matterbridge/bridge/kosmi"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Parse command line flags
|
|
||||||
roomURL := flag.String("room", "https://app.kosmi.io/room/@hyperspaceout", "Kosmi room URL")
|
roomURL := flag.String("room", "https://app.kosmi.io/room/@hyperspaceout", "Kosmi room URL")
|
||||||
debug := flag.Bool("debug", false, "Enable debug logging")
|
debug := flag.Bool("debug", false, "Enable debug logging")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// Set up logger
|
|
||||||
log := logrus.New()
|
log := logrus.New()
|
||||||
if *debug {
|
if *debug {
|
||||||
log.SetLevel(logrus.DebugLevel)
|
log.SetLevel(logrus.DebugLevel)
|
||||||
} else {
|
} else {
|
||||||
log.SetLevel(logrus.InfoLevel)
|
log.SetLevel(logrus.InfoLevel)
|
||||||
}
|
}
|
||||||
log.SetFormatter(&logrus.TextFormatter{
|
log.SetFormatter(&logrus.TextFormatter{FullTimestamp: true})
|
||||||
FullTimestamp: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
logger := log.WithField("bridge", "kosmi-test")
|
logger := log.WithField("bridge", "kosmi-native-test")
|
||||||
|
|
||||||
logger.Info("Starting Kosmi bridge test")
|
logger.Info("Starting Kosmi native WebSocket test")
|
||||||
logger.Infof("Room URL: %s", *roomURL)
|
logger.Infof("Room URL: %s", *roomURL)
|
||||||
|
|
||||||
// Create bridge configuration
|
roomID, err := extractRoomID(*roomURL)
|
||||||
cfg := bridge.NewConfig("kosmi.test", logger)
|
if err != nil {
|
||||||
cfg.SetString("RoomURL", *roomURL)
|
logger.Fatalf("Failed to extract room ID: %v", err)
|
||||||
cfg.SetBool("Debug", *debug)
|
|
||||||
|
|
||||||
// Create Kosmi bridge
|
|
||||||
b := bkosmi.New(cfg)
|
|
||||||
|
|
||||||
// Connect to Kosmi
|
|
||||||
logger.Info("Connecting to Kosmi...")
|
|
||||||
if err := b.Connect(); err != nil {
|
|
||||||
logger.Fatalf("Failed to connect to Kosmi: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Successfully connected to Kosmi!")
|
client := bkosmi.NewGraphQLWSClient(*roomURL, roomID, "", logger)
|
||||||
|
|
||||||
// Start message listener
|
client.OnMessage(func(payload *bkosmi.NewMessagePayload) {
|
||||||
go func() {
|
username := payload.Data.NewMessage.User.DisplayName
|
||||||
for msg := range cfg.Remote {
|
if username == "" {
|
||||||
logger.Infof("Received message: [%s] %s: %s",
|
username = payload.Data.NewMessage.User.Username
|
||||||
msg.Timestamp.Format("15:04:05"),
|
|
||||||
msg.Username,
|
|
||||||
msg.Text)
|
|
||||||
}
|
}
|
||||||
}()
|
ts := time.Unix(payload.Data.NewMessage.Time, 0)
|
||||||
|
logger.Infof("Received message: [%s] %s: %s",
|
||||||
|
ts.Format("15:04:05"), username, payload.Data.NewMessage.Body)
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.Info("Connecting to Kosmi via native WebSocket...")
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
logger.Fatalf("Failed to connect: %v", err)
|
||||||
|
}
|
||||||
|
logger.Info("Successfully connected!")
|
||||||
|
|
||||||
// Wait for interrupt signal
|
|
||||||
logger.Info("Listening for messages... Press Ctrl+C to exit")
|
logger.Info("Listening for messages... Press Ctrl+C to exit")
|
||||||
sigChan := make(chan os.Signal, 1)
|
sigChan := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
// Optional: Send a test message after 5 seconds
|
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
logger.Info("Bridge is running. Messages from Kosmi will appear above.")
|
logger.Info("Bridge is running. Messages from Kosmi will appear above.")
|
||||||
logger.Info("To test sending messages, integrate with IRC or use the full Matterbridge setup")
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
<-sigChan
|
<-sigChan
|
||||||
logger.Info("Shutting down...")
|
logger.Info("Shutting down...")
|
||||||
|
|
||||||
// Disconnect
|
if err := client.Disconnect(); err != nil {
|
||||||
if err := b.Disconnect(); err != nil {
|
|
||||||
logger.Errorf("Error disconnecting: %v", err)
|
logger.Errorf("Error disconnecting: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Goodbye!")
|
logger.Info("Goodbye!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractRoomID(url string) (string, error) {
|
||||||
|
url = strings.TrimSuffix(url, "/")
|
||||||
|
re := regexp.MustCompile(`/room/(@?[a-zA-Z0-9_-]+)`)
|
||||||
|
matches := re.FindStringSubmatch(url)
|
||||||
|
if len(matches) >= 2 {
|
||||||
|
roomID := matches[1]
|
||||||
|
if !strings.HasPrefix(roomID, "@") {
|
||||||
|
roomID = "@" + roomID
|
||||||
|
}
|
||||||
|
return roomID, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("could not extract room ID from URL: %s", url)
|
||||||
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ func main() {
|
|||||||
fmt.Println("✅ WebSocket connected!")
|
fmt.Println("✅ WebSocket connected!")
|
||||||
|
|
||||||
// Step 3: Listen for messages
|
// Step 3: Listen for messages
|
||||||
fmt.Println("\n👂 Listening for messages (press Ctrl+C to exit)...\n")
|
fmt.Println("\n👂 Listening for messages (press Ctrl+C to exit)...")
|
||||||
|
|
||||||
messageCount := 0
|
messageCount := 0
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func main() {
|
|||||||
fmt.Println("✅ Subscribed!")
|
fmt.Println("✅ Subscribed!")
|
||||||
|
|
||||||
// Listen for messages
|
// Listen for messages
|
||||||
fmt.Println("\n👂 Listening for messages (press Ctrl+C to exit)...\n")
|
fmt.Println("\n👂 Listening for messages (press Ctrl+C to exit)...")
|
||||||
|
|
||||||
messageCount := 0
|
messageCount := 0
|
||||||
for {
|
for {
|
||||||
|
|||||||
Reference in New Issue
Block a user