Beta version
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 24s
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 24s
This commit is contained in:
96
client.go
96
client.go
@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -60,11 +61,11 @@ func New(config *config.Config) (*Client, error) {
|
|||||||
// client.logger.Debug("unmarshaled json data", "request", "auth", "type", "sessionData", "body", sd)
|
// client.logger.Debug("unmarshaled json data", "request", "auth", "type", "sessionData", "body", sd)
|
||||||
|
|
||||||
if sd.DeviceRegistered && sd.RegisteredDevicePermanent {
|
if sd.DeviceRegistered && sd.RegisteredDevicePermanent {
|
||||||
client.logger.Debug("client authentication successful")
|
// client.logger.Debug("client authentication successful")
|
||||||
client.isAuthenticated = true
|
client.isAuthenticated = true
|
||||||
client.isRegistered = true
|
client.isRegistered = true
|
||||||
} else {
|
} else {
|
||||||
client.logger.Debug("client authentication successful, but devices is not registered")
|
// client.logger.Debug("client authentication successful, but devices is not registered")
|
||||||
client.registerDevice()
|
client.registerDevice()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +141,7 @@ func (c *Client) GetVehicles() []*Vehicle {
|
|||||||
// GetVehicleByVIN .
|
// GetVehicleByVIN .
|
||||||
func (c *Client) GetVehicleByVIN(vin string) *Vehicle {
|
func (c *Client) GetVehicleByVIN(vin string) *Vehicle {
|
||||||
var vehicle *Vehicle
|
var vehicle *Vehicle
|
||||||
if contains(c.listOfVins, vin) {
|
if slices.Contains(c.listOfVins, vin) {
|
||||||
params := map[string]string{
|
params := map[string]string{
|
||||||
"vin": vin,
|
"vin": vin,
|
||||||
"_": timestamp()}
|
"_": timestamp()}
|
||||||
@ -212,7 +213,7 @@ func (c *Client) GetVehicleByVIN(vin string) *Vehicle {
|
|||||||
|
|
||||||
// Exec method executes a Client instance with the API URL
|
// Exec method executes a Client instance with the API URL
|
||||||
func (c *Client) execute(requestUrl string, method string, params map[string]string, pollingUrl string, j bool, attempts ...int) []byte {
|
func (c *Client) execute(requestUrl string, method string, params map[string]string, pollingUrl string, j bool, attempts ...int) []byte {
|
||||||
defer timeTrack("[TIMETRK] Executing HTTP Request")
|
// defer timeTrack("[TIMETRK] Executing HTTP Request")
|
||||||
var resp *resty.Response
|
var resp *resty.Response
|
||||||
|
|
||||||
// GET Requests
|
// GET Requests
|
||||||
@ -290,35 +291,6 @@ func (c *Client) execute(requestUrl string, method string, params map[string]str
|
|||||||
return resBytes
|
return resBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
// // isResponseSuccessfull .
|
|
||||||
// func (c *Client) isResponseSuccessfull(resp []byte) bool {
|
|
||||||
// respParsed, err := gabs.ParseJSON(resp)
|
|
||||||
// if err != nil {
|
|
||||||
// c.logger.Debug("error while parsing json response", "error", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// success, ok := respParsed.Path("success").Data().(bool)
|
|
||||||
// if !ok {
|
|
||||||
// c.logger.Debug("response is not successful", "error", resp)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // ERRORS FROM CLIENT CREATION AFTER AUTH
|
|
||||||
// // error, _ := respParsed.Path("errorCode").Data().(string)
|
|
||||||
// // switch {
|
|
||||||
// // case error == apiErrors["ERROR_INVALID_ACCOUNT"]:
|
|
||||||
// // fmt.Println("Invalid account")
|
|
||||||
// // case error == apiErrors["ERROR_INVALID_CREDENTIALS"]:
|
|
||||||
// // {"success":false,"errorCode":"InvalidCredentials","dataName":"remoteServiceStatus","data":{"serviceRequestId":null,"success":false,"cancelled":false,"remoteServiceType":null,"remoteServiceState":null,"subState":null,"errorCode":null,"result":null,"updateTime":null,"vin":null,"errorDescription":"The credentials supplied are invalid, tries left 2"}}
|
|
||||||
// // fmt.Println("Client authentication failed")
|
|
||||||
// // case error == apiErrors["ERROR_PASSWORD_WARNING"]:
|
|
||||||
// // fmt.Println("Multiple Password Failures.")
|
|
||||||
// // default:
|
|
||||||
// // fmt.Println("Uknown error")
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// return success
|
|
||||||
// }
|
|
||||||
|
|
||||||
// auth .
|
// auth .
|
||||||
func (c *Client) auth() []byte {
|
func (c *Client) auth() []byte {
|
||||||
params := map[string]string{
|
params := map[string]string{
|
||||||
@ -347,46 +319,28 @@ func (c *Client) parseResponse(b []byte) (Response, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// validateSession .
|
// validateSession .
|
||||||
func (c *Client) validateSession() bool {
|
// func (c *Client) validateSession() bool {
|
||||||
// {
|
// // {
|
||||||
// "success": true,
|
// // "success": true,
|
||||||
// "errorCode": null,
|
// // "errorCode": null,
|
||||||
// "dataName": null,
|
// // "dataName": null,
|
||||||
// "data": null
|
// // "data": null
|
||||||
|
// // }
|
||||||
|
// reqURL := MOBILE_API_VERSION + apiURLs["API_VALIDATE_SESSION"]
|
||||||
|
// resp := c.execute(reqURL, GET, map[string]string{}, "", false)
|
||||||
|
// c.logger.Debug("http request output", "request", "validateSession", "body", resp)
|
||||||
|
|
||||||
|
// var r Response
|
||||||
|
// err := json.Unmarshal(resp, &r)
|
||||||
|
// if err != nil {
|
||||||
|
// c.logger.Error("error while parsing json", "request", "validateSession", "error", err.Error())
|
||||||
// }
|
// }
|
||||||
reqURL := MOBILE_API_VERSION + apiURLs["API_VALIDATE_SESSION"]
|
|
||||||
resp := c.execute(reqURL, GET, map[string]string{}, "", false)
|
|
||||||
c.logger.Debug("http request output", "request", "validateSession", "body", resp)
|
|
||||||
|
|
||||||
var r Response
|
// if r.Success {
|
||||||
err := json.Unmarshal(resp, &r)
|
// return true
|
||||||
if err != nil {
|
// }
|
||||||
c.logger.Error("error while parsing json", "request", "validateSession", "error", err.Error())
|
// return false
|
||||||
}
|
// }
|
||||||
|
|
||||||
if r.Success {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
|
|
||||||
// result = False
|
|
||||||
// js_resp = await self.__open(API_VALIDATE_SESSION, GET)
|
|
||||||
// _LOGGER.debug(pprint.pformat(js_resp))
|
|
||||||
// if js_resp["success"]:
|
|
||||||
// if vin != self._current_vin:
|
|
||||||
// # API call for VIN that is not the current remote context.
|
|
||||||
// _LOGGER.debug("Switching Subaru API vehicle context to: %s", vin)
|
|
||||||
// if await self._select_vehicle(vin):
|
|
||||||
// result = True
|
|
||||||
// else:
|
|
||||||
// result = True
|
|
||||||
|
|
||||||
// if result is False:
|
|
||||||
// await self._authenticate(vin)
|
|
||||||
// # New session cookie. Must call selectVehicle.json before any other API call.
|
|
||||||
// if await self._select_vehicle(vin):
|
|
||||||
// result = True
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET
|
// GET
|
||||||
// https://www.mysubaru.com/profile/verifyDeviceName.json?clientId=2574212&deviceName=Alex%20Google%20Pixel%204%20XL
|
// https://www.mysubaru.com/profile/verifyDeviceName.json?clientId=2574212&deviceName=Alex%20Google%20Pixel%204%20XL
|
||||||
|
@ -281,6 +281,7 @@ type ServiceRequest struct {
|
|||||||
// "dataName":"errorResponse"
|
// "dataName":"errorResponse"
|
||||||
// {"success":false,"errorCode":"404-soa-unableToParseResponseBody","dataName":"errorResponse","data":{"errorLabel":"404-soa-unableToParseResponseBody","errorDescription":null}}
|
// {"success":false,"errorCode":"404-soa-unableToParseResponseBody","dataName":"errorResponse","data":{"errorLabel":"404-soa-unableToParseResponseBody","errorDescription":null}}
|
||||||
// {"success":false,"errorCode":"vehicleNotInAccount","dataName":null,"data":null}
|
// {"success":false,"errorCode":"vehicleNotInAccount","dataName":null,"data":null}
|
||||||
|
// {"success":false,"errorCode":"InvalidCredentials","dataName":"remoteServiceStatus","data":{"serviceRequestId":null,"success":false,"cancelled":false,"remoteServiceType":null,"remoteServiceState":null,"subState":null,"errorCode":null,"result":null,"updateTime":null,"vin":null,"errorDescription":"The credentials supplied are invalid, tries left 2"}}
|
||||||
type ErrorResponse struct {
|
type ErrorResponse struct {
|
||||||
ErrorLabel string `json:"errorLabel"` // "404-soa-unableToParseResponseBody"
|
ErrorLabel string `json:"errorLabel"` // "404-soa-unableToParseResponseBody"
|
||||||
ErrorDescription string `json:"errorDescription,omitempty"` // null
|
ErrorDescription string `json:"errorDescription,omitempty"` // null
|
||||||
|
59
utils.go
59
utils.go
@ -1,7 +1,6 @@
|
|||||||
package mysubaru
|
package mysubaru
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"math"
|
"math"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -9,6 +8,23 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// timestamp is a function
|
||||||
|
func timestamp() string {
|
||||||
|
return strconv.FormatInt(time.Now().UnixNano()/1000000, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// urlToGen .
|
||||||
|
func urlToGen(url string, gen string) string {
|
||||||
|
var re = regexp.MustCompile(`api_gen`)
|
||||||
|
// dirty trick for current G3
|
||||||
|
if gen == "g3" {
|
||||||
|
gen = "g2"
|
||||||
|
}
|
||||||
|
url = re.ReplaceAllString(url, gen)
|
||||||
|
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
// VinCheck - Vehicle Identification Number check digit validation
|
// VinCheck - Vehicle Identification Number check digit validation
|
||||||
// Parameter: string - 17 digit VIN
|
// Parameter: string - 17 digit VIN
|
||||||
// Return:
|
// Return:
|
||||||
@ -110,34 +126,17 @@ func transcodeDigits(vin string) int {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// timeTrack .
|
// timeTrack .
|
||||||
func timeTrack(name string) {
|
// func timeTrack(name string) {
|
||||||
start := time.Now()
|
// start := time.Now()
|
||||||
fmt.Printf("%s took %v\n", name, time.Since(start))
|
// fmt.Printf("%s took %v\n", name, time.Since(start))
|
||||||
}
|
// }
|
||||||
|
|
||||||
// timestamp is a function
|
|
||||||
func timestamp() string {
|
|
||||||
return strconv.FormatInt(time.Now().UnixNano()/1000000, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
// contains .
|
// contains .
|
||||||
func contains(s []string, str string) bool {
|
// func contains(s []string, str string) bool {
|
||||||
for _, v := range s {
|
// for _, v := range s {
|
||||||
if v == str {
|
// if v == str {
|
||||||
return true
|
// return true
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return false
|
// return false
|
||||||
}
|
// }
|
||||||
|
|
||||||
// urlToGen .
|
|
||||||
func urlToGen(url string, gen string) string {
|
|
||||||
var re = regexp.MustCompile(`api_gen`)
|
|
||||||
// dirty trick for current G3
|
|
||||||
if gen == "g3" {
|
|
||||||
gen = "g2"
|
|
||||||
}
|
|
||||||
url = re.ReplaceAllString(url, gen)
|
|
||||||
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
|
16
vehicle.go
16
vehicle.go
@ -759,13 +759,13 @@ func (v *Vehicle) selectVehicle() {
|
|||||||
// getAPIGen
|
// getAPIGen
|
||||||
// Get the Subaru telematics API generation of a specified VIN
|
// Get the Subaru telematics API generation of a specified VIN
|
||||||
func (v *Vehicle) getAPIGen() string {
|
func (v *Vehicle) getAPIGen() string {
|
||||||
if contains(v.Features, FEATURE_G1_TELEMATICS) {
|
if slices.Contains(v.Features, FEATURE_G1_TELEMATICS) {
|
||||||
return "g1"
|
return "g1"
|
||||||
}
|
}
|
||||||
if contains(v.Features, FEATURE_G2_TELEMATICS) {
|
if slices.Contains(v.Features, FEATURE_G2_TELEMATICS) {
|
||||||
return "g2"
|
return "g2"
|
||||||
}
|
}
|
||||||
if contains(v.Features, FEATURE_G3_TELEMATICS) {
|
if slices.Contains(v.Features, FEATURE_G3_TELEMATICS) {
|
||||||
return "g3"
|
return "g3"
|
||||||
}
|
}
|
||||||
return "unknown"
|
return "unknown"
|
||||||
@ -780,13 +780,13 @@ func (v *Vehicle) getAPIGen() string {
|
|||||||
// isEV .
|
// isEV .
|
||||||
// Get whether the specified car is an Electric Vehicle.
|
// Get whether the specified car is an Electric Vehicle.
|
||||||
func (v *Vehicle) isEV() bool {
|
func (v *Vehicle) isEV() bool {
|
||||||
return contains(v.Features, FEATURE_PHEV)
|
return slices.Contains(v.Features, FEATURE_PHEV)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getRemoteOptionsStatus .
|
// getRemoteOptionsStatus .
|
||||||
// Get whether the specified VIN has remote locks/horn/light service available
|
// Get whether the specified VIN has remote locks/horn/light service available
|
||||||
func (v *Vehicle) getRemoteOptionsStatus() bool {
|
func (v *Vehicle) getRemoteOptionsStatus() bool {
|
||||||
return contains(v.SubscriptionFeatures, FEATURE_REMOTE)
|
return slices.Contains(v.SubscriptionFeatures, FEATURE_REMOTE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseDoor .
|
// parseDoor .
|
||||||
@ -927,19 +927,19 @@ func (v *Vehicle) parseTire(prefix, suffix, name string, value any) {
|
|||||||
// // getRemoteStartStatus .
|
// // getRemoteStartStatus .
|
||||||
// // Get whether the specified VIN has remote engine start service available.
|
// // Get whether the specified VIN has remote engine start service available.
|
||||||
// func (v *Vehicle) getRemoteStartStatus() bool {
|
// func (v *Vehicle) getRemoteStartStatus() bool {
|
||||||
// return contains(v.Features, FEATURE_REMOTE_START)
|
// return slices.Contains(v.Features, FEATURE_REMOTE_START)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // getSafetyStatus .
|
// // getSafetyStatus .
|
||||||
// // Get whether the specified VIN is has an active Starlink Safety Plus service plan.
|
// // Get whether the specified VIN is has an active Starlink Safety Plus service plan.
|
||||||
// func (v *Vehicle) getSafetyStatus() bool {
|
// func (v *Vehicle) getSafetyStatus() bool {
|
||||||
// return contains(v.SubscriptionFeatures, FEATURE_SAFETY)
|
// return slices.Contains(v.SubscriptionFeatures, FEATURE_SAFETY)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // getSubscriptionStatus .
|
// // getSubscriptionStatus .
|
||||||
// // Get whether the specified VIN has an active service plan.
|
// // Get whether the specified VIN has an active service plan.
|
||||||
// func (v *Vehicle) getSubscriptionStatus() bool {
|
// func (v *Vehicle) getSubscriptionStatus() bool {
|
||||||
// return contains(v.SubscriptionFeatures, FEATURE_ACTIVE)
|
// return slices.Contains(v.SubscriptionFeatures, FEATURE_ACTIVE)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // getVehicleName .
|
// // getVehicleName .
|
||||||
|
Reference in New Issue
Block a user