Security News
Research
Supply Chain Attack on Rspack npm Packages Injects Cryptojacking Malware
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
the-traveler
Advanced tools
The Traveler is a small npm package which wraps around the Destiny 2 API. It uses Promises for a modern workflow in your application.
npm install the-traveler
# or
yarn add the-traveler
To use this package you will need to obtain an API access key from the Bungie.net developer webiste. 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
});
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.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 on if you are using. With a public
type the response does not contain an 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 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 => {
// 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:
clientId
and clientSecret (only for confidential)
authUrl
and redirect users to itcode
parameter from your redirectURL
code
to get the OAuth object
and apply it to the Traveler object
authorization url
againtraveler.oauth.refreshtoken
to renew the accessToken
, without user interaction by traveler.refreshToken()
async
and await
to overcome the callback hell
, see Async await approach (pseudo-code)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.
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: {} }
Some information in the Destiny API is privacy protected. If the user set the pricacy settings it is not possible to obtain specific information through the API. The different pricacy indicators are the following:
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',
Here all character specific components are queried. You can either use normal strings or use the integrated enums for a better naming.
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: {} }
traveler.oauth
has to be set before calling this method
traveler
.transferItem({
itemReferenceHash: '2907129556',
stackSize: 1,
transferToVault: false,
itemId: '6917529033189743362',
characterId: 'yourCharacterId',
membershipType: Enums.BungieMembershipType.PSN
})
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
});
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
}
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 bear 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 | ||
Destiny2.SearchDestinyPlayer | ||
Destiny2.GetProfile | ||
Destiny2.GetCharacter | ||
Destiny2.GetClanWeeklyRewardState | ||
Destiny2.GetItem | ||
Destiny2.GetVendors | ||
Destiny2.GetVendor | ||
Destiny2.TransferItem | ||
Destiny2.EquipItem | ||
Destiny2.EquipItems | ||
Destiny2.SetItemLockState | ||
Destiny2.InsertSocketPlug | ||
Destiny2.ActivateTalentNode | ||
Destiny2.GetPostGameCarnageReport | ||
Destiny2.GetHistoricalStatsDefinition | ||
Destiny2.GetClanLeaderboards | ||
Destiny2.GetClanAggregateStats | ||
Destiny2.GetLeaderboards | ||
Destiny2.GetLeaderboardsForCharacter | ||
Destiny2.SearchDestinyEntities | ||
Destiny2.GetHistoricalStats | ||
Destiny2.GetHistoricalStatsForAccount | ||
Destiny2.GetActivityHistory | ||
Destiny2.GetUniqueWeaponHistory | ||
Destiny2.GetDestinyAggregateActivityStats | ||
Destiny2.GetPublicMilestoneContent | ||
Destiny2.GetPublicMilestones |
We use SemVer for versioning. For the versions available, see the tags on this repository.
Do you have any issues or recommendations for this package ? Feel free to open an issue in the isse section :)
This project is licensed under the MIT License - see the LICENSE.md file for details
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.
FAQs
A Node.js API wrapper for the Destiny 2 API
The npm package the-traveler receives a total of 5 weekly downloads. As such, the-traveler popularity was classified as not popular.
We found that the-traveler demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.
Security News
Sonar’s acquisition of Tidelift highlights a growing industry shift toward sustainable open source funding, addressing maintainer burnout and critical software dependencies.