rickbassham / tesla

Golang client for the Tesla owner's API.
ISC License
15 stars 3 forks source link

Getting "HTTP status: 403 Forbidden" messages when streaming. #5

Open pmcanseco opened 4 years ago

pmcanseco commented 4 years ago

Hi, I'm trying to use your library to stream vehicle data over websocket. I added some logging to see what messages are coming out and going in. I found that the tesla API will only response with the following:

sent: 
{
    MessageType: "data:subscribe_oauth"
    Token: "<redacted>"
    Value: "speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading"
    Tag: <vehicleid>
}

received: 
{ 
    MessageType: "control:hello" 
}
{ 
    MessageType: "data:error" 
    Value: "owner_api error: `Got HTTP status: 403 Forbidden for . Response: {\"response\":\"unauthorized\"}`"
    Tag: <vehicleid>
}

Here's my code:

    httpCli := http.DefaultClient
    httpCli.Transport = http.DefaultTransport
    conn := tesla.NewConn(httpCli.Transport, tesla.DefaultBaseURL, clientID, clientSecret)
    authErr := conn.Authenticate(email, password)
    if authErr != nil {
        panic(errors.Wrap(authErr, "failed to authenticate"))
    }

    stream, streamErr := conn.Stream(<vehicleid>, "<redacted>") // the token parameter in this function is not used within
    if streamErr != nil {
        panic(errors.Wrap(streamErr, "failed to stream"))
    }

    for {
        select {
        case msg := <-stream.Data():
            fmt.Println(msg)
        }
    }

Other calls, like seeing the charge state or vehicle location work perfectly. It's just the streaming that won't cooperate.

Am I doing something wrong, are there any extra special steps required to be able to stream, or could Tesla have disabled this functionality altogether?

rickbassham commented 4 years ago

Hey Pablo, I haven't used this code in a while, so Tesla may have modified it. Looking at someone else's ruby code

    def streaming_connect_message
      {
        msg_type: 'data:subscribe',
        token: Base64.strict_encode64("#{email}:#{self['tokens'].first}"),
        value: 'speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading',
        tag: self['vehicle_id'].to_s,
      }
    end

It looks like it should be a different message on connect that we send. If you want to fork and modify it, that would be awesome. Just send me a PR once you've tested it, and I'll get it merged in.