Skip to main content
The Melody device can request an OTP directly over its active WebSocket connection to the Haptics server. This is an alternative to the WiFi API startOtp service command and does not require a separate HTTP call.

Frame Types

Frame TypeValueDirectionProtobuf Message
OTP_REQUEST19Device → ServerOTPRequest
OTP_RESPONSE20Server → DeviceOTPResponse

Message Definitions

OTPRequest (device → server):
message OTPRequest {
  bool reserved = 1; // reserved for future fields (e.g. scope)
}
OTPResponse (server → device):
message OTPResponse {
  string otp = 1;           // The OTP code
  uint64 expires_at_ms = 2; // Expiration timestamp in milliseconds (Unix)
  string error = 3;         // Non-empty if the request failed
}

Flow

  1. Device sends an OTP_REQUEST frame with a serialized (empty) OTPRequest message over the existing WebSocket connection.
  2. Server generates the OTP and replies with an OTP_RESPONSE frame on the same connection.
  3. If generation fails, error is non-empty — otp should be ignored in this case.

Code Example

// --- Request ---

otpReq := &entities.OTPRequest{}
data, err := proto.Marshal(otpReq)
if err != nil {
    return err
}

frame := protocol.NewHapticFrame(entities.FrameType_OTP_REQUEST, data)
if err := frame.WriteFrame(stream); err != nil {
    return err
}

// --- Response ---

respFrame, err := protocol.ReadNextFrame(stream)
if err != nil {
    return err
}

if respFrame.Type != entities.FrameType_OTP_RESPONSE {
    return fmt.Errorf("unexpected frame type: %v", respFrame.Type)
}

otpResp := &entities.OTPResponse{}
if err := proto.Unmarshal(respFrame.Data, otpResp); err != nil {
    return err
}

if otpResp.Error != "" {
    return fmt.Errorf("OTP generation failed: %s", otpResp.Error)
}

fmt.Printf("OTP: %s, expires at: %d ms\n", otpResp.Otp, otpResp.ExpiresAtMs)

Notes

  • The OTP is scoped to the requesting device’s connection — it is not broadcast to other subscribers.
  • Maximum response time is 10 seconds (proxy timeout to the session manager).
  • The startOtp WiFi API service command remains available as an alternative for devices that need OTP without an active WebSocket connection.