Skip to content

Casao/the-traveler

 
 

Repository files navigation

the-traveler

npm npm GitHub license GitHub issues Build Status codecov

the-traveler is a small npm package which wraps around the Destiny 2 API. It uses Promises for a modern workflow in your application.

Table of Contents

Getting Started

npm install the-traveler
# or
yarn add the-traveler

Prerequisites

To use this package you will need to obtain an API access key from the Bungie.net developer website. Please visit https://www.bungie.net/en/Application to obtain your access token.

After obtaining your access token you are ready for using the Destiny 2 API in your next awesome project.

import Traveler from 'the-traveler';
import { ComponentType } from 'the-traveler/build/enums';

const traveler = new Traveler({
    apikey: 'pasteYourAPIkey',
    userAgent: 'yourUserAgent', //used to identify your request to the API
});

If you want to use this package inside a ES5 project you can import it like so:

var Traveler = require('the-traveler').default;
const Enums = require('the-traveler/build/enums')

const traveler = new Traveler({
    apikey: 'yourAPIkey',
    userAgent: 'yourUserAgent' //used to identify your request to the API
});

//Access the enums (example componentType profiles)
var profilesType = Enums.ComponentType.Profiles;

If you want to show the URLs the API wrapper is requesting, just add debug: true to the configuration array when instantiate a Traveler object

const traveler = new Traveler({
    apikey: 'pasteYourAPIkey',
    userAgent: 'yourUserAgent', //used to identify your request to the API
    debug: true 
});

OAuth

If you want to use OAuth to get access to endpoints which require user approval provide the Traveler object with your OAuth clientId and if you are using a confidential client type additionally the clientSecret.

import Traveler from 'the-traveler';

const traveler = new Traveler({
    apikey: 'pasteYourAPIkey',
    userAgent: 'yourUserAgent', //used to identify your request to the API
    oauthClientId: 'yourClientId',
    oauthClientSecret: 'yourClientSecret',
});

Please ensure that you specified a redirectURL in your application settings on https://www.bungie.net/en/Application. After you have done that, you can generate the authentication URL which has to be visited by your users to approve your application. The URL is constructed with the following schema: https://www.bungie.net/en/OAuth/Authorize?client_id={yourClientID}&response_type=code.

const authUrl = traveler.generateOAuthURL(); // The URL your users have to visit to give your application access

If a user visit this site and approve your application he/she will be redirected to the redirectURL you specified. This URL is expaned with query parameter called code: https://www.example.com/?code=hereComesTheCode

This is the code you need to obtain the OAuth Access token with the getAccessToken() method.

traveler.getAccessToken(hereComesTheCode).then(oauth => {
    // Provide your traveler object with the oauth object. This is later used for making authenticated calls
    traveler.oauth = oauth; 
}).catch(err => {
    console.log(err)
})

The OAuth response schema is depended on the client type you are using. With a public type the response does not contain a refresh_token. This means that a user has to authenticate everytime again after the OAuth access token has expired.

Response:

{ access_token: '',
  token_type: 'Bearer',
  expires_in: 3600,
  membership_id: ''}

If you are using a confidential client type the response will contain a refresh_token which can be used to get a new access_token without requiring the user to approve your app again. Use this refresh_token to prevent you from getting errors if the access_token has expired. In the following you can see such a response with the method to renew the token.

Response:

{ access_token: '',
  token_type: 'Bearer',
  expires_in: 3600,
  refresh_token: ',
  refresh_expires_in: 7776000,
  membership_id: '' }

Use refresh:

traveler.refreshToken(traveler.oauth.refresh_token).then(oauth => { // take the refresh token from the oauth object you provided when initialize the oauth to the traveler
    // Provide your traveler object with the oauth object. This is later used for making authenticated calls
    traveler.oauth = oauth; 
}).catch(err => {
    console.log(err)
})

So the refresh procedure has to be initiated manually, there is no automatic refresh implemented.

To wrap this up, the flow is the following:

  • Provide clientId and clientSecret (only for confidential)
  • Generate authUrl and redirect users to it
  • Grab the code parameter from your redirectURL
  • Use code to get the OAuth object and apply it to the Traveler object
  • FOR Public Reauthenticate your users after the access token has expired. They have to visit the authorization url again
  • FOR Confidential Use traveler.oauth.refreshtoken to renew the accessToken, without user interaction by traveler.refreshToken()
  • After the oauth object is set on the traveler object you can query the endpoints which require authentiation
  • Keep in mind that it would be very useful to store the tokens for your users securely!

Notices

Typescript Support

The npm package comes with d.ts files to allow autocompletion and type checking if you are using the-traveler within Typescript.

There are some other noteworthy information which could help to resolve some issues with the Destiny 2 API.

Typical Response

The response object from the API is always constructed like the following snippet indicates. The Response will contain the actual request data, while ErrorCode, ThrottleSeconds, ErrorStatus, Message and MessageData will hold additional data about the sucess of our request.

{ Response: Array or Object,
  ErrorCode: 1,
  ThrottleSeconds: 0,
  ErrorStatus: 'Success',
  Message: 'Ok',
  MessageData: {} }

Privacy

Some information in the Destiny API is privacy protected. If the user set the pricacy settings, and you do not use oauth for those users, it is not possible to obtain specific information through the API. The different pricacy indicators are the following:

  • None: 0
  • Public: 1
  • Private: 2

Documentation

Examples

Search for an Destiny Account on PSN

Query:

traveler
    .searchDestinyPlayer('2', 'playername')
    .then(player => {
        console.log(player);
    }).catch(err => {
        //do something with the error
    })

Response

{ Response:
   [ { iconPath: '/img/theme/destiny/icons/icon_psn.png',
       membershipType: 2,
       membershipId: '4611686018433838874',
       displayName: 'Playername' } ],
  ErrorCode: 1,
  ThrottleSeconds: 0,
  ErrorStatus: 'Success',
  Message: 'Ok',

Get a character for an PSN Account

Here all character specific components are queried. You can either use normal strings or use the integrated enums.

Query:

import Traveler from 'the-traveler';
import {ComponentType} from 'the-traveler/build/enums' 

const traveler = new Traveler({
    apikey: 'pasteYourAPIkey',
    userAgent: 'yourUserAgent' //used to identify your request to the API
});

traveler.getCharacter('2', '4611686018452033461', '2305843009265042115', { components: ['200', '201', '202', '203', '204', '205'] }).then(result => {
    console.log(result);
}).catch(err => {
    console.log(err);
});

// OR

traveler.getCharacter('2', '4611686018452033461', '2305843009265042115', {
    components:
    [
        ComponentType.Characters,
        ComponentType.CharacterInventories,
        ComponentType.CharacterProgressions,
        ComponentType.CharacterRenderData,
        ComponentType.CharacterActivities,
        ComponentType.CharacterEquipment
    ]
}).then(result => {
    console.log(result);
}).catch(err => {
    console.log(err);
});

Response (First level):

{ Response:
   { inventory: { privacy: 2 },
     character: { data: [Object], privacy: 1 },
     progressions: { privacy: 2 },
     renderData: { data: [Object], privacy: 1 },
     activities: { privacy: 2 },
     equipment: { data: [Object], privacy: 1 },
     itemComponents: {} },
  ErrorCode: 1,
  ThrottleSeconds: 0,
  ErrorStatus: 'Success',
  Message: 'Ok',
  MessageData: {} }

Transfer item from vault to character (needs OAuth)

traveler.oauth has to be set before calling this method

traveler
    .transferItem({
        itemReferenceHash: '2907129556',
        stackSize: 1,
        transferToVault: false,
        itemId: '6917529033189743362',
        characterId: 'yourCharacterId',
        membershipType: BungieMembershipType.PSN // BungieMembershipType.PSN in ES5
    })
    .then(result => {
        console.log(result);
    })
    .catch(err => {
        console.log(err);
    });

Async await approach (pseudo-code)

Just a thought about using async and await

async () => {
    const traveler = new Traveler({
        apikey: 'pasteYourAPIkey',
        userAgent: 'yourUserAgent', //used to identify your request to the API
        oauthClientId: 'yourClientId',
        oauthClientSecret: 'yourClientSecret',
    });

    traveler.oauth = await traveler.getAccessToken(accessCode);
    // OR 
    traveler.oauth = await traveler.refreshToken(refreshToken);

    // now do your calls
}

Progress

Please visit the official documentation for the API to check if the endpoints are working or if they are still in preview. If you find endpoints in preview, please keep in mind that errors can occur quite often. If the endpoints get finalized also this package will adopt changes and test the functionalities.

Endpoint Implemented Unlocked in API
Destiny2.GetDestinyManifest alt text alt text
Destiny2.SearchDestinyPlayer alt text alt text
Destiny2.GetProfile alt text alt text
Destiny2.GetCharacter alt text alt text
Destiny2.GetClanWeeklyRewardState alt text alt text
Destiny2.GetItem alt text alt text
Destiny2.GetVendors alt text alt text
Destiny2.GetVendor alt text alt text
Destiny2.TransferItem alt text alt text
Destiny2.EquipItem alt text alt text
Destiny2.EquipItems alt text alt text
Destiny2.SetItemLockState alt text alt text
Destiny2.InsertSocketPlug alt text alt text
Destiny2.ActivateTalentNode alt text alt text
Destiny2.GetPostGameCarnageReport alt text alt text
Destiny2.GetHistoricalStatsDefinition alt text alt text
Destiny2.GetClanLeaderboards alt text alt text
Destiny2.GetClanAggregateStats alt text alt text
Destiny2.GetLeaderboards alt text alt text
Destiny2.GetLeaderboardsForCharacter alt text alt text
Destiny2.SearchDestinyEntities alt text alt text
Destiny2.GetHistoricalStats alt text alt text
Destiny2.GetHistoricalStatsForAccount alt text alt text
Destiny2.GetActivityHistory alt text alt text
Destiny2.GetUniqueWeaponHistory alt text alt text
Destiny2.GetDestinyAggregateActivityStats alt text alt text
Destiny2.GetPublicMilestoneContent alt text alt text
Destiny2.GetPublicMilestones alt text alt text

Built With

Versioning

the-traveler uses SemVer for versioning. For the versions available, see the tags on this repository.

Issues

Do you have any issues or recommendations for this package ? Feel free to open an issue in the issue section :)

License

This project is licensed under the MIT License - see the LICENSE.md file for details

Acknowledgments

the-traveler package isn't endorsed by Bunge and doesn't reflect the views or opinions of Bungies or anyone officially involved in producing or managing Destiny 2. Destiny 2 and Bungie are trademarks or registered trademarks of Bungie, Inc. Destiny 2 © Bungie.

About

The Traveler is a small npm package which wraps around the Destiny 2 API.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 100.0%