Giter VIP home page Giter VIP logo

zwift-mobile-api's Introduction

GDPR and Zwift's Developer API

In July '08, this library was converted to use Zwift's new Developer API, in accordance with Zwift's policies.

The Developer API requires a special developer account, and won't work with regular rider accounts like before. Currently, Zwift is not able to offer developer accounts to hobby developers, but I'm hoping they'll be able to at some point. You can contact Zwift at [email protected] to register interest and ask for further information.

zwift-mobile-api

A simple javascript library to make it a bit easier to call some of the Zwift API endpoints

  • Automatically handle creating and renewing of a valid token (requires username and password to login with a valid Zwift account)
  • Decode protobuf data to get live current speed/power/time data for currently riding players
  • List and download previous activities, decoded from FIT files

Usage

$> npm install --save zwift-mobile-api

Login

var ZwiftAccount = require("zwift-mobile-api");
var account = new ZwiftAccount(username, password);

Rider Profiles

// Get profile for "me"
account.getProfile().profile().then(p => {
    console.log(p);  // JSON of rider profile (includes id property you can use below)
});

// Get profile data for a particular rider (requires Zwift player id)
var profile = account.getProfile(playerId);

profile.followers().then(followers => {
    console.log(followers); // JSON array of rider's followers
});

profile.followees().then(followees => {
    console.log(followees); // JSON array of rider's followees
});

// Give a RideOn (from 'playerId' to 'otherRiderId')
// Can lookup 'activityId' from 'currentActivityId' of profile() response
profile.giveRideOn(otherRiderId, activityId);

// Retrieve the goals you have
profile.goals().then(goal=> {
    console.log(goal); //JSON array of goals
})

// Delete a goal; goalID is printed from getGoals()
goalID = 200147
prof.deleteGoal(goalID)

List Riders

// (note: currently all riders are listed in world '1',
// so worlds 2 and 3 are empty no matter the schedule)

var world = account.getWorld(1);

world.riders().then(riders => {
    console.log(riders); // JSON array of all riders currently riding
});

Rider Status

// (note: currently all riders are listed in world '1',
// so worlds 2 and 3 are empty no matter the schedule)

var world = account.getWorld(1);

// Get the status of the specified rider
// (includes x,y position, speed, power, etc)
world.riderStatus(playerId).then(status => {
    console.log(status); // JSON of rider status
});

Events

var event = account.getEvent();

// Search for events
// options:
//   eventStartsAfter = earliest start time (milliseconds since 1970)
//   eventStartsBefore = latest start time (milliseconds since 1970)
const options = {
    eventStartsAfter: Date.now() - 3600000,
    eventStartsBefore: Date.now() + 600000
};
event.search(options).then(results => {
    results.forEach(event => console.log(
        `${event.id}: ${event.name} - sub groups `
        + event.eventSubgroups.map(g => `${g.label}:${g.id}`)
    ))
});

// Get riders who signed up to an event sub group
// (get subGroupId from search() results)
event.riders(subGroupId).then(riders =>
    riders.forEach(r => console.log(
        `${r.id} - ${r.firstName} ${r.lastName}`
    ))
);

// Get the results for an event subgroup.
// Note that results returned by Zwift are not sorted, even though they
// often come through as slowest first.
event.segmentResults(eventSubgroupId).then(results => {
    results.sort((a,b) => {
        if (a.elapsedMs > b.elapsedMs) {
            return 1;
        } else if (a.elapsedMs == b.elapsedMs) {
            return 0;
        }
        return -1;
    })
    for (let result of results) {
        console.log(result);
    }
});

Previous Activities

// Get profile data for a particular rider (requires Zwift player id)
var profile = account.getProfile(playerId);

// Get the list of previous activities
// (start, limit parameters for paging - e.g. (0,30) for first 30 activities)
profile.activities(start, limit).then(activities => {
    console.log(activities); // JSON array of activities
});

// Get full position data for an activity from FIT file
// (translated back into Zwift world coordinates)
account.getActivity(playerId).get(activityId).then(activity => {
    console.log(activity); // JSON of activity including positions
});

zwift-mobile-api's People

Contributors

bissont avatar martinwtrl avatar ogadai avatar wiedmann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zwift-mobile-api's Issues

Request failed with status code 403

Hi when trying to get world like in the example code

var ZwiftAccount = require("zwift-mobile-api"); 
var account = new ZwiftAccount("my_user", "my_passwd"); 

var world = account.getWorld(1);  
world.riders().then(riders => {
    console.log(riders); // JSON array of all riders currently riding
}, (error) => {
    console.log('Error!');
    console.error(error);
});

I get Request failed with status code 403 error.
What am i doing wrong? Thanks for the help!

Speed units

Not really an issue, but what units are the rider speed?

I get 0 when stationary, but turning the pedals by hand yields 7070934 for roughly 4 mph.

0.1.11 breaks something (seen in zwift-second-screen)

It seems like 0.1.11 breaks something which gives more 'Failed to get status' in zwift-second-screen (both 0.0.55 and 0.0.56).

Example
1008 active riders in world
added 46976 (1)
added 210524 (2)
added 24617 (3)
Failed to get status for 24617

The problems does not occur if I use 0.1.11

Upload workout

It would be nice if there is the ability to upload a workout via the API (instead of just having it in a folder to get sync)

Give RideOns

An action to give RideOns would be nice:

  • rideOn to single Rider
  • rideOn to group

404 for riderStatus

Hi,

When I wanna get the riderStatus I get a 404:

world.riderStatus(playerId).then(status => {
console.log(status); // JSON of rider status
});

(node:12596) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Request failed with status code 404

Progress toward challenge

Hi,

Not an issue, but more an idea: I want to figure out how much progress I've made toward a challenge with an API call, if we can.

I was thinking of trying to figure this out by running wireshark just before finishing a ride so that when
Zwift displays the progress toward a challenge, I can hopefully see the GET request my client issued to Zwift. What do you think?

Thanks!
Tim

Upgrade Error

Hi

I have been using the zwift-mobile-api which has been working great but realised I have not upgraded code base for GDPR changes and so upgraded yesterday but I started to receive errors.

I rolled back the upgrade and then found that the error I was receiving came from getAccessToken.js and Profile.js but if I used the original version of these files all worked as before.

Thinking the error was being created from installed software versions I created a clean Raspberry Pi install and installed NPM and zwift-mobile-api but still got the same error.

Can you point me in correct direction if I have missed something from upgrade.

I used simple script to test from the read.me file:

var ZwiftAccount = require("zwift-mobile-api");
var account = new ZwiftAccount(user, password);

// Get profile for "me"
account.getProfile().profile().then(p => {
console.log(p); // JSON of rider profile (includes id property you can use below)
});

Genererating this error:

nodejs ZwiftAccount.js
(node:10708) UnhandledPromiseRejectionWarning: Error: Request failed with status code 403
at createError (/home/pi/node_modules/zwift-mobile-api/node_modules/axios/lib/core/createError.js:15:15)
at settle (/home/pi/node_modules/zwift-mobile-api/node_modules/axios/lib/core/settle.js:18:12)
at IncomingMessage.handleStreamEnd (/home/pi/node_modules/zwift-mobile-api/node_modules/axios/lib/adapters/http.js:186:11)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
(node:10708) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:10708) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

rider status

i want to get the full status x,y position, speed, power, etc.

if i execute the script in terminal .. there is an error

"UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Request failed with status code 404"

the little script

`var ZwiftAccount = require("zwift-mobile-api"); // don't edit this line

// settings you HAVE to edit are below this line //
var account = new ZwiftAccount("user", "password"); // put in your Zwift credentials between " "
var playerId = "IknowMyID"; // put your Zwift ID between " "
// end of settings you HAVE to edit //

var world = account.getWorld(1);

// Get the status of the specified rider
// (includes x,y position, speed, power, etc)
world.riderStatus(playerId).then(status => {
console.log(status); // JSON of rider status
});`

push speed to the server

Hello,

its maybe a stupid question, but do you have any idea how i could push speed and incline to zwift? I am asking the question because i am trying to build a bridge between iFit and Zwift and that would help if i could use an API (instead of broadcasting through BLE or ANT+).

Thanks

Nico

Zwift communication protocol changing to mandate encryption

xposting from wiedmann/zwift-packet-monitor#5

Hey folks,

I'm a backend engineer at Zwift and want to bring to your attention some upcoming changes that are likely to affect your project.

In July we are rolling out a new encryption protocol that will affect all UDP and TCP communication between client and server, and also between client and the Zwift Companion app (ZC), in order to meet a new requirement from Google Play (they recently changed their user data safety policy).

The rollout will span several days and you may see both encrypted and unencrypted clients running concurrently during that period. It is expected that by July 20th we will have all our communication fully encrypted.

After July 20th, unencrypted clients will be considered deprecated, but still supported. Eventually, however, Zwift will enforce encryption for all clients, but that date is still to be determined.

How exactly that affects your project will depend on what it does:

  • server clones: they won't be affected by encryption while unencrypted communication is still supported. Encrypted clients must negotiate encryption with the server, and they will simply fall back to unencrypted communication if the server doesn't know any better. When encryption is enforced, however, these projects will stop working;
  • ZC clones: they won't be affected during that initial phase either. Encrypted clients must also negotiate encryption with ZC, and they will also fall back to unencrypted in case of pre-encryption ZCs. When encryption is enforced, however, these projects will stop working;
  • client sniffers: those will be immediately impacted when rollout starts. Not only is the protocol specification changing, but the very payload being sniffed by those projects is now encrypted. Logic that relies on reading user data from network packets will simply fail if the data is encrypted, as one would expect;
  • BLE and ANT+ devices: projects that emulate either BLE or ANT+ devices won't be affected, not even after encryption is enforced (unless of course they also fit any of the roles aforementioned). We are not changing those communication protocols in any way.

Please note that this change is required to secure user data, not to discourage community projects. We are internally discussing if and how we can help community projects go through the change and continue working. That said, please have in mind that this is not merely an engineering decision, but it must also involve other departments like Product and Legal. We will post further updates here as soon as we have any news.

We'll also try our best to answer questions, depending on the availability of our backend engineering team. You can trust replies from any of the engineers listed here.

Ride On!

Distance to rider driving ahead

Hello,

could you please give me a hint, to find the distance to the next rider driving ahead. Sorry, if I overlooked in API or documentation.

Regards,

Sebastian

Workout / Interval messages

Is there anything representing workouts in the api? It seems like there are a few undefined messages in zwiftMessages.proto. If the power/time/cadence of each interval was in there it would allow for some integration with the workouts and music, lights, etc.

Is there a way to log the entire buffer while doing a workout to track down whether that info is there?

access the API with a special developer account

You write that you can only access the API with a special developer account.

With the Zwift Mobile API client written in Python it works with a normal account.
https://github.com/jsmits/zwift-client

In this project the Zwift Mobile API client written in Python works with a normal Zwift account.
https://github.com/snicker/zwift_hass

Why, what is different. I would very much like to use your zwift-mobile-api with a normal Zwift account.

Thanks for your info

Crash when using library

I use the library in this project https://www.instructables.com/id/Internet-Connected-Fan-for-Use-With-Zwift/ and my javascript crashes every x minutes, but with errors outside my script. Can u tell if the problem lies somewhere in your library? (was very glad to find the library by the way, made my project possible!)

events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: getaddrinfo ENOTFOUND api.particle.io api.particle.io:443
    at errnoException (dns.js:50:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:92:26)
 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.