Node.js (GraphQL Request)
Step 1. Getting started
Step 1.1. Overview
After the initial setup in Step 1, you'll have the following APIs at your fingertips.
main.js
import { gql } from "graphql-request";
import { DeliveryTrackerGraphQLClient } from "./DeliveryTrackerGraphQLClient.js";
// Create a Client that connects to the DeliveryTracker Server.
const client = new DeliveryTrackerGraphQLClient(
"[YOUR_CLIENT_ID]",
"[YOUR_CLIENT_SECRET]"
);
// Example query to get the time and code of a recent event
// There are many other queries, which can be used to retrieve various information.
// Please refer to the documentation and API schema on the official site
const trackQuery = gql`
query GetTrackLastEvent($carrierId: ID!, $trackingNumber: String!) {
track(carrierId: $carrierId, trackingNumber: $trackingNumber) {
lastEvent {
time
status {
code
}
}
}
}
`;
// Call the DeliveryTracker API.
const response = await client.request(trackQuery, {
carrierId: "kr.cjlogistics",
trackingNumber: "1234567890",
});
console.log(response);
Step 1.2. Add dependencies
This document walks you through how to use the Delivery Tracker API using graphql-request. To do this, we first install graphql-request.
npm add graphql-request graphql
Step 1.3. Add Transport class
The GraphQLClient
built into graphql-request does not provide Delivery Tracker Auth out of the box.
For authentication, add a DeliveryTrackerGraphQLClient
that inherits from GraphQLClient
and implements Delivery Tracker Auth.
DeliveryTrackerGraphQLClient.js
import { GraphQLClient } from "graphql-request";
class DeliveryTrackerGraphQLClient extends GraphQLClient {
constructor(clientId, clientSecret) {
super("https://apis.tracker.delivery/graphql", {
fetch: (input, init) => this._fetch(input, init),
});
this._accessToken = null;
this._credentials = "Basic " + btoa(`${clientId}:${clientSecret}`);
}
async _fetch(input, init) {
let response = await fetch(input, {
...init,
headers: {
...init.headers,
"Authorization": `Bearer ${await this.getAccessToken()}`,
}
});
let responseBody = await response.text();
if(this._hasUnauthenticatedError(JSON.parse(responseBody))) {
response = await fetch(input, {
...init,
headers: {
...init.headers,
"Authorization": `Bearer ${await this.getAccessToken(true)}`,
}
});
responseBody = await response.text();
}
return {
ok: response.ok,
status: response.status,
headers: response.headers,
text: async () => responseBody,
};
}
_hasUnauthenticatedError(responseBody) {
if (!Array.isArray(responseBody.errors)) {
return false;
}
for (const error of responseBody.errors) {
try {
if (error.extensions?.code === "UNAUTHENTICATED") {
return true;
}
} catch (e) {}
}
return false;
}
async getAccessToken(forceFetchNewAccessToken = false) {
if (this._accessToken === null || forceFetchNewAccessToken) {
this._accessToken = await this._fetchNewAccessToken();
}
return this._accessToken;
}
async _fetchNewAccessToken() {
const authResponse = await fetch(
"https://auth.tracker.delivery/oauth2/token",
{
method: "POST",
headers: {
"Authorization": This._credentials,
"Content-Type": "application/x-www-form-urlencoded",
},
body: "grant_type=client_credentials",
},
);
if(authResponse.status >= 400) {
throw new Error(`Auth error: http response code=${authResponse.status} body=${await authResponse.text()}`);
}
try {
const authResponseBody = await authResponse.json();
const accessToken = authResponseBody.access_token;
if (typeof accessToken !== "string") {
throw new Error('typeof accessToken !== "string"');
}
return accessToken;
} catch (e) {
throw new Error("The access_token field was not found.", { cause: e });
}
}
}
export { DeliveryTrackerGraphQLClient };
Step 1.4. Execute your first query
"Step 1.1. Write the main.js
code described in "Overview" and run main.js
to get the API working.