first commit
This commit is contained in:
190
client/client.go
Normal file
190
client/client.go
Normal file
@@ -0,0 +1,190 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.savin.nyc/alex/go-iar-notificator/config"
|
||||
resty "resty.dev/v3"
|
||||
)
|
||||
|
||||
const (
|
||||
GET = "GET"
|
||||
POST = "POST"
|
||||
)
|
||||
|
||||
// Config holds the API configuration
|
||||
// type Config struct {
|
||||
// URL string
|
||||
// SecretKey string
|
||||
// AuthToken string
|
||||
// SubscriberID int
|
||||
// PagerGroupID string
|
||||
// }
|
||||
|
||||
// Client represents a MySubaru API client that interacts with the MySubaru API.
|
||||
type Client struct {
|
||||
credentials *config.Credentials
|
||||
IAR IaR
|
||||
HTTPClient *resty.Client
|
||||
isAlive bool
|
||||
logger *slog.Logger
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
type IaR struct {
|
||||
PagerGroupID string
|
||||
PagerGroupName string
|
||||
Type string
|
||||
}
|
||||
|
||||
// New function creates a New MySubaru API client
|
||||
func New(credentials *config.Credentials, logger *slog.Logger) (*Client, error) {
|
||||
|
||||
client := &Client{
|
||||
credentials: credentials,
|
||||
IAR: IaR{
|
||||
PagerGroupID: "",
|
||||
PagerGroupName: "",
|
||||
Type: "",
|
||||
},
|
||||
isAlive: false,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
httpClient := resty.New()
|
||||
httpClient.
|
||||
SetBaseURL("https://ttd.iamresponding.com/ttd").
|
||||
SetHeaders(map[string]string{
|
||||
"User-Agent": "python-requests/2.22.0",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept": "*/*",
|
||||
"Connection": "keep-alive",
|
||||
"Content-Type": "application/json",
|
||||
"SecretKey": client.credentials.SecretKey,
|
||||
"Authorization": "TTDApiKey " + client.credentials.TTDApiKey,
|
||||
},
|
||||
)
|
||||
|
||||
client.HTTPClient = httpClient
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *Client) KeepAlive() error {
|
||||
query := `query {getMutualPagerGroupsList {_id subscriberId name type tone_tolerance gaplength ignore_after record_delay record_seconds release_time playback_during_record post_email_command alert_command atone btone atonelength btonelength longtone longtonelength createDate},getTTDSetting(keySetting: "pollingSeconds"){keySetting keyValue}}`
|
||||
resp, err := c.execute(POST, "", map[string]string{"query": query})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp != nil && len(resp.Data.GetMutualPagerGroupsList) > 0 {
|
||||
pg := resp.Data.GetMutualPagerGroupsList[0]
|
||||
c.IAR.PagerGroupID = pg.ID
|
||||
c.IAR.PagerGroupName = pg.Name
|
||||
c.IAR.Type = pg.Type
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) PreAlert() (string, error) {
|
||||
ttdReceivedDate := time.Now().UTC().Format(time.RFC3339)
|
||||
query := `mutation {addAlert(ttdReceivedDate: "` + ttdReceivedDate + `", pagerGroup: ["` + c.IAR.PagerGroupID + `"]){_id textAlert pagerGroup subscriberId}}`
|
||||
resp, err := c.execute(POST, "", map[string]string{"query": query})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return resp.Data.AddAlert.ID, nil
|
||||
}
|
||||
|
||||
func (c *Client) Alert(audioBase64 string) error {
|
||||
var err error
|
||||
var alertID string
|
||||
ttdReceivedDate := time.Now().UTC().Format(time.RFC3339)
|
||||
if alertID, err = c.PreAlert(); err != nil {
|
||||
return errors.New("failed to create pre-alert")
|
||||
}
|
||||
query := `mutation {addAlert(_id: "` + alertID + `", ttdReceivedDate: "` + ttdReceivedDate + `", pagerGroup: ["` + c.IAR.PagerGroupID + `"], audio: "` + audioBase64 + `"){_id textAlert pagerGroup audioUrl subscriberId}}`
|
||||
resp, err := c.execute(POST, "", map[string]string{"query": query})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.logger.Info("Alert sent successfully", "alertID", resp.Data.AddAlert.ID, "audioURL", resp.Data.AddAlert.AudioUrl)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ServeKeepAlive starts a goroutine that sends keep-alive requests at the specified interval.
|
||||
func (c *Client) ServeKeepAlive(ctx context.Context, interval time.Duration) {
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
slog.Info("Starting keep-alive sender", "interval", interval)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
slog.Info("Stopping keep-alive sender")
|
||||
return
|
||||
case <-ticker.C:
|
||||
if err := c.KeepAlive(); err != nil {
|
||||
slog.Error("Failed to send keep-alive", "error", err)
|
||||
} else {
|
||||
slog.Info("Sent keep-alive successfully")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IsAlive checks if the Client instance is alive
|
||||
func (c *Client) IsAlive() bool {
|
||||
return c.isAlive
|
||||
}
|
||||
|
||||
// execute executes an HTTP request based on the method, URL, and parameters provided.
|
||||
func (c *Client) execute(method string, url string, params map[string]string) (*Response, error) {
|
||||
c.Lock()
|
||||
var resp *resty.Response
|
||||
var err error
|
||||
c.logger.Debug("executing http request", "method", method, "url", url, "params", params)
|
||||
|
||||
// POST Requests
|
||||
if method == POST {
|
||||
resp, err = c.HTTPClient.
|
||||
R().
|
||||
SetBody(params).
|
||||
Post(url)
|
||||
if err != nil {
|
||||
c.logger.Error("error while executing POST request", "request", "execute", "method", method, "url", url, "error", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
c.logger.Debug("executed POST request", "method", method, "url", url, "params", params)
|
||||
}
|
||||
|
||||
if resp.IsSuccess() {
|
||||
resBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
c.logger.Error("error while getting body", "error", err.Error())
|
||||
}
|
||||
c.logger.Debug("parsed http request output", "data", string(resBytes))
|
||||
|
||||
c.HTTPClient.SetCookies(resp.Cookies())
|
||||
|
||||
var r Response
|
||||
if err := json.Unmarshal(resBytes, &r); err != nil {
|
||||
c.logger.Error("error while unmarshalling response", "error", err.Error())
|
||||
c.isAlive = false
|
||||
c.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
c.isAlive = true
|
||||
c.Unlock()
|
||||
return &r, nil
|
||||
}
|
||||
c.isAlive = false
|
||||
c.Unlock()
|
||||
return nil, errors.New("request is not successfull, HTTP code: " + resp.Status())
|
||||
}
|
Reference in New Issue
Block a user