Skip to content

Commit

Permalink
Add API key per game version
Browse files Browse the repository at this point in the history
  • Loading branch information
sandervspl committed Jul 19, 2024
1 parent 205eef2 commit 9cbcab4
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 21 deletions.
12 changes: 8 additions & 4 deletions apps/server/src/api/item/auction-house.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import * as R from 'remeda';

import { getAuctionHouse } from '../../utils/tsm';
import * as i from '../../types';
import { getAuctionHouse, tsmApiKeys } from '../../utils/tsm';
import { createDbClient } from '../../db';
import { items } from '../../db/schema';
import { Item } from '../../types/tsm';
import { KEYS, kv } from '../../kv';

const queue = new Map<string | number, Promise<Item[] | undefined>>();

export async function updateAuctionHouseData(auctionHouseId: string | number) {
export async function updateAuctionHouseData(
auctionHouseId: string | number,
version: i.GameVersion,
) {
console.info(auctionHouseId, 'Updating AH');
const KV_KEY = KEYS.tsmAHRecentlyFetched(auctionHouseId);

Expand All @@ -29,10 +33,10 @@ export async function updateAuctionHouseData(auctionHouseId: string | number) {

// Add to queue
console.info(auctionHouseId, 'Adding AH to queue...');

const tsmApiKey = tsmApiKeys[version];
queue.set(
auctionHouseId,
getAuctionHouse(auctionHouseId)
getAuctionHouse(auctionHouseId, tsmApiKey)
.then((items) => {
console.info(auctionHouseId, 'AH fetched!');
return items;
Expand Down
7 changes: 4 additions & 3 deletions apps/server/src/api/item/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { createDbClient } from '../../db';
import { items, itemsMetadata } from '../../db/schema';
import { getItemFromBnet } from '../../utils/blizzard/index.ts';
import { qualityMap } from '../../utils';
import { getAuctionHouse, getItem } from '../../utils/tsm';
import { getAuctionHouse, getItem, tsmApiKeys } from '../../utils/tsm';
import { Item } from '../../types/tsm';

export async function itemService(itemId: number, auctionHouseId: number, version: i.GameVersion) {
Expand Down Expand Up @@ -55,10 +55,11 @@ async function queryItem(id: number, auctionHouseId: number, version: i.GameVers
let item: Item | undefined | null;

// Fetch entire auction house if needed
getAuctionHouse(auctionHouseId);
const tsmApiKey = tsmApiKeys[version];
getAuctionHouse(auctionHouseId, tsmApiKey);

// Get the item from TSM directly
item = await getItem(id, auctionHouseId);
item = await getItem(id, auctionHouseId, tsmApiKey);

if (!item) {
// If TSM fetch failed, return item from DB if possible
Expand Down
4 changes: 2 additions & 2 deletions apps/server/src/scripts/fetch-auction-houses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const MAX_ERRORS = 3;

for (const region of ['eu', 'us'] as i.Region[]) {
// Too many realms to fetch them all, so we'll only fetch seasonal periodically
for (const version of ['seasonal'] as i.GameVersion[]) {
for (const version of ['seasonal', 'era', 'classic', 'hardcore'] as i.GameVersion[]) {
console.log(`Fetching realms for "${region}-${version}"...`);
const realms = await realmService(region, version);

Expand All @@ -21,7 +21,7 @@ for (const region of ['eu', 'us'] as i.Region[]) {

for await (const auctionHouse of realm.auctionHouses) {
try {
await updateAuctionHouseData(auctionHouse.auctionHouseId);
await updateAuctionHouseData(auctionHouse.auctionHouseId, version);
} catch (err: any) {
console.error(
`Failed to update AH for "${realm.name}" (${region}-${version})...`,
Expand Down
32 changes: 20 additions & 12 deletions apps/server/src/utils/tsm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ import { items } from '../db/schema';
import { KEYS, kv } from '../kv';
import { Region, Item } from '../types/tsm';

const versionMap = {
const versionMap: Record<i.GameVersion, string> = {
era: 'Classic Era',
hardcore: 'Classic Era - Hardcore',
classic: 'Wrath',
seasonal: 'Season of Discovery',
} as const;

async function getAccessToken() {
export const tsmApiKeys: Record<i.GameVersion, string> = {
era: process.env.TSM_API_KEY_D!,
hardcore: process.env.TSM_API_KEY_C!,
classic: process.env.TSM_API_KEY_B!,
seasonal: process.env.TSM_API_KEY!,
};

async function getAccessToken(tsmApiKey: string) {
const cached = await kv.get(KEYS.tsmAccessToken);
if (cached) {
return cached;
Expand All @@ -23,7 +30,7 @@ async function getAccessToken() {
client_id: process.env.TSM_CLIENT_ID,
grant_type: 'api_token',
scope: 'app:realm-api app:pricing-api',
token: process.env.TSM_API_KEY,
token: tsmApiKey ?? process.env.TSM_API_KEY,
}),
headers: {
'content-type': 'application/json',
Expand Down Expand Up @@ -60,8 +67,8 @@ async function getAccessToken() {
return access_token;
}

async function headers() {
const token = await getAccessToken();
async function headers(tsmApiKey: string) {
const token = await getAccessToken(tsmApiKey);

return {
Accept: 'application/json',
Expand All @@ -76,8 +83,9 @@ export async function getRealms(regionq: i.Region, version: i.GameVersion) {

// Fetch from TSM if not in cache
if (regions.items.length === 0) {
const tsmApiKey = tsmApiKeys[version];
const response = await fetch(`https://realm-api.tradeskillmaster.com/realms`, {
headers: await headers(),
headers: await headers(tsmApiKey),
});
if (response.status !== 200) {
throw new Error(`Failed to fetch realms`);
Expand Down Expand Up @@ -108,11 +116,11 @@ export async function getRealms(regionq: i.Region, version: i.GameVersion) {

const queue = new Map<string | number, Promise<Item[] | undefined>>();

async function fetchAuctionHouse(auctionHouseId: string | number) {
async function fetchAuctionHouse(auctionHouseId: string | number, tsmApiKey: string) {
console.info(auctionHouseId, 'fetching auction house...');

const response = await fetch(`https://pricing-api.tradeskillmaster.com/ah/${auctionHouseId}`, {
headers: await headers(),
headers: await headers(tsmApiKey),
});

if (response.status !== 200) {
Expand All @@ -125,7 +133,7 @@ async function fetchAuctionHouse(auctionHouseId: string | number) {
return response.json() as Promise<Item[]>;
}

export async function getAuctionHouse(auctionHouseId: string | number) {
export async function getAuctionHouse(auctionHouseId: string | number, tsmApiKey: string) {
// If already in queue, return its request
if (queue.has(auctionHouseId)) {
console.info(auctionHouseId, 'Waiting for AH in queue to resolve...');
Expand All @@ -145,7 +153,7 @@ export async function getAuctionHouse(auctionHouseId: string | number) {
return undefined;
}

const auctionHouse = await fetchAuctionHouse(auctionHouseId);
const auctionHouse = await fetchAuctionHouse(auctionHouseId, tsmApiKey);

if (Array.isArray(auctionHouse) && auctionHouse.length > 0) {
try {
Expand All @@ -170,14 +178,14 @@ export async function getAuctionHouse(auctionHouseId: string | number) {
return queue.get(auctionHouseId);
}

export async function getItem(itemId: number, auctionHouseId: number) {
export async function getItem(itemId: number, auctionHouseId: number, tsmApiKey: string) {
const logPrefix = `${itemId}:${auctionHouseId}`;
console.info(logPrefix, 'Fetching item from TSM');

const response = await fetch(
`https://pricing-api.tradeskillmaster.com/ah/${auctionHouseId}/item/${itemId}`,
{
headers: await headers(),
headers: await headers(tsmApiKey),
},
);

Expand Down

0 comments on commit 9cbcab4

Please sign in to comment.