Writing a rocketchat client to watch channel, initial channel sub (golang)

error:

2025-12-01T01:46:17Z INF Starting RocketChat client channel=#webhook server=wss://chat.redacted.xyz
2025-12-01T01:46:17Z INF Connecting to WebSocket url=wss://chat.redacted.xyz/websocket
2025-12-01T01:46:17Z INF Connected to RocketChat WebSocket
2025-12-01T01:46:17Z INF > Sent Connect
2025-12-01T01:46:17Z INF > Sent token
2025-12-01T01:46:17Z INF Found room channel=#webhook roomId=692cdf069e6f87cec12c8654
2025-12-01T01:46:17Z INF > Sent room subscribe message
2025-12-01T01:46:17Z ERR WebSocket connection lost error="websocket: close 1002 (protocol error)"

code:

func connectAndListen() error {
	wsURL := strings.Replace(serverURL, "https://", "wss://", 1)
	wsURL = strings.Replace(wsURL, "http://", "ws://", 1)
	wsURL = wsURL + "/websocket"

	log.Info().Str("url", wsURL).Msg("Connecting to WebSocket")

	conn, _, err := websocket.DefaultDialer.Dial(wsURL, nil)
	if err != nil {
		return fmt.Errorf("failed to connect to websocket: %w", err)
	}
	defer conn.Close()

	log.Info().Msg("Connected to RocketChat WebSocket")

	// Send connect message
	if err := sendMessage(conn, Message{
		Msg:    "connect",
		ID:     "1",
		Method: "connect",
		Params: []interface{}{"1", false},
	}); err != nil {
		return fmt.Errorf("failed to send connect message: %w", err)
	}

	// Wait for connect response
	//time.Sleep(2000 * time.Millisecond)
	//time.Sleep(500 * time.Millisecond)

	log.Info().Msg("> Sent Connect")

	// Login with token
	if err := sendMessage(conn, Message{
		Msg:    "method",
		ID:     "2",
		Method: "login",
		Params: []interface{}{map[string]string{"resume": token}},
	}); err != nil {
		return fmt.Errorf("failed to send login message: %w", err)
	}

	log.Info().Msg("> Sent token")

	// Get room ID
	roomID, err := getRoomID(conn, channel)
	if err != nil {
		return fmt.Errorf("failed to get room ID: %w", err)
	}

	log.Info().Str("roomId", roomID).Str("channel", channel).Msg("Found room")

	// Subscribe to room messages
	if err := sendMessage(conn, Message{
		Msg:    "sub",
		ID:     "3",
		Method: "stream-room-messages",
		Params: []interface{}{roomID, false},
	}); err != nil {
		return fmt.Errorf("failed to subscribe to room: %w", err)
	}

	log.Info().Msg("> Sent room subscribe message")

	// Listen for messages
	for {
		_, message, err := conn.ReadMessage()
		if err != nil {
			log.Error().Err(err).Msg("WebSocket connection lost")

			mu.Lock()
			if reconnected {
				mu.Unlock()
				return fmt.Errorf("connection lost after reconnect attempt")
			}
			reconnected = true
			mu.Unlock()

			log.Info().Msg("Attempting to reconnect...")
			time.Sleep(2 * time.Second)

			// Close old connection
			conn.Close()

			// Try to reconnect
			return connectAndListen()
		}

		var msg Message
		if err := json.Unmarshal(message, &msg); err != nil {
			log.Debug().Str("raw", string(message)).Msg("Could not parse message")
			continue
		}

		// Handle ping/pong
		if msg.Msg == "ping" {
			if err := sendMessage(conn, Message{Msg: "pong"}); err != nil {
				log.Error().Err(err).Msg("Failed to send pong")
			}
			continue
		}

		// Handle changed messages (new messages in room)
		if msg.Msg == "changed" && len(msg.Fields) > 0 {
			if args, ok := msg.Fields["args"].([]interface{}); ok && len(args) > 0 {
				if msgData, ok := args[0].(map[string]interface{}); ok {
					logRoomMessage(msgData)
				}
			}
		}
	}
}

func sendMessage(conn *websocket.Conn, msg Message) error {
	data, err := json.Marshal(msg)
	if err != nil {
		return err
	}
	return conn.WriteMessage(websocket.TextMessage, data)
}

Read the docs:

:warning: Warning: Deprecated

The DDP methods outlined are deprecated. We are no longer actively testing or maintaining these methods, and their behavior may be unreliable or change without notice.

Use the REST API provided.

Note also. Your reply was again marked as spam.

Rapid copy & paste posts will get canned. Think carefully about how you post.