Skip to content

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.