prism/service/integration/signal/link.go

75 lines
1.6 KiB
Go

package signal
import (
"encoding/json"
"fmt"
"net/url"
"time"
)
type LinkDevice struct {
client *Client
deviceName string
qrCode string
deviceLinkUri string
generatedAt time.Time
ttl time.Duration
}
func NewLinkDevice(client *Client, deviceName string) *LinkDevice {
return &LinkDevice{
client: client,
deviceName: deviceName,
ttl: 10 * time.Minute,
}
}
type StartLinkResponse struct {
DeviceLinkURI string `json:"deviceLinkUri"`
}
func (l *LinkDevice) GenerateQR() (string, error) {
if l.client == nil {
return "", fmt.Errorf("signal client not initialized")
}
if l.qrCode != "" && time.Since(l.generatedAt) < l.ttl {
return l.qrCode, nil
}
result, err := l.client.Call("startLink", nil)
if err != nil {
return "", fmt.Errorf("failed to start link: %w", err)
}
var response StartLinkResponse
if err := json.Unmarshal(result, &response); err != nil {
return "", fmt.Errorf("failed to parse link response: %w", err)
}
uri := response.DeviceLinkURI
if uri == "" {
return "", fmt.Errorf("empty device link URI")
}
l.deviceLinkUri = uri
qrURL := fmt.Sprintf("https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=%s", url.QueryEscape(uri))
l.qrCode = qrURL
l.generatedAt = time.Now()
go l.finishLink()
return l.qrCode, nil
}
func (l *LinkDevice) finishLink() {
params := map[string]interface{}{
"deviceLinkUri": l.deviceLinkUri,
"deviceName": l.deviceName,
}
_, err := l.client.Call("finishLink", params)
if err == nil {
l.qrCode = ""
l.generatedAt = time.Time{}
}
}