Files
p/garmin.go

94 lines
2.3 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"net/url"
"strings"
)
type garminClient struct {
c *http.Client
mapshareID string
}
type garminResponse struct {
Success bool `json:"success"`
Error *struct {
Code int `json:"code"`
Msg string `json:"msg"`
} `json:"error"`
}
func newGarminClient(mapshareID string) *garminClient {
return &garminClient{
c: &http.Client{},
mapshareID: mapshareID,
}
}
func (gc *garminClient) sendMessage(deviceIDs []string, sender, msg string) error {
for _, deviceID := range deviceIDs {
err := gc.sendToDevice(deviceID, sender, msg)
if err != nil {
return fmt.Errorf("device %s: %w", deviceID, err)
}
}
return nil
}
func (gc *garminClient) sendToDevice(deviceID, sender, msg string) error {
data := url.Values{}
data.Set("deviceIds", deviceID)
data.Set("messageText", msg)
data.Set("fromAddr", sender)
endpoint := fmt.Sprintf("https://share.garmin.com/%s/Map/SendMessageToDevices", gc.mapshareID)
log.Printf("[->garmin] %s %s", endpoint, data.Encode())
req, err := http.NewRequest("POST", endpoint, strings.NewReader(data.Encode()))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
req.Header.Set("Accept", "application/json, text/javascript, */*; q=0.01")
req.Header.Set("Origin", "https://share.garmin.com")
req.Header.Set("Referer", fmt.Sprintf("https://share.garmin.com/%s", gc.mapshareID))
req.Header.Set("X-Requested-With", "XMLHttpRequest")
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15")
resp, err := gc.c.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
log.Printf("[<-garmin] %d %s", resp.StatusCode, string(body))
if resp.StatusCode != 200 {
return fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
}
var grResp garminResponse
err = json.Unmarshal(body, &grResp)
if err != nil {
return fmt.Errorf("parse response: %w", err)
}
if !grResp.Success {
if grResp.Error != nil {
return fmt.Errorf("garmin error %d: %s", grResp.Error.Code, grResp.Error.Msg)
}
return fmt.Errorf("garmin returned success=false")
}
return nil
}