mirror of
https://github.com/misenhower/splatoon3.ink.git
synced 2026-03-21 09:44:09 -05:00
Add nxapi-powered NSO client
This commit is contained in:
parent
eea6984e64
commit
9bd16d2e41
|
|
@ -1,3 +1,9 @@
|
|||
# Nintendo API
|
||||
NINTENDO_TOKEN=
|
||||
|
||||
# User agent string
|
||||
USER_AGENT=
|
||||
|
||||
# Twitter API parameters
|
||||
TWITTER_CONSUMER_KEY=
|
||||
TWITTER_CONSUMER_SECRET=
|
||||
|
|
|
|||
45
app/common/ValueCache.mjs
Normal file
45
app/common/ValueCache.mjs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import fs from 'fs/promises';
|
||||
|
||||
export default class ValueCache
|
||||
{
|
||||
constructor(key) {
|
||||
this._key = key;
|
||||
}
|
||||
|
||||
get path() {
|
||||
return `storage/${this._key}.json`;
|
||||
}
|
||||
|
||||
async _getRawItem() {
|
||||
try {
|
||||
let data = await fs.readFile(this.path);
|
||||
|
||||
return JSON.parse(data);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async get() {
|
||||
let item = await this._getRawItem();
|
||||
|
||||
// If the cached value is already expired, return null
|
||||
if (item && item.expires && item.expires < new Date) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
async getData() {
|
||||
let item = await this.get();
|
||||
|
||||
return item && item.data;
|
||||
}
|
||||
|
||||
async setData(data, expires = null) {
|
||||
let serialized = JSON.stringify({ expires, data }, undefined, 2);
|
||||
|
||||
await fs.writeFile(this.path, serialized);
|
||||
}
|
||||
}
|
||||
75
app/nso/NsoClient.mjs
Normal file
75
app/nso/NsoClient.mjs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import CoralApi from 'nxapi/coral';
|
||||
import { addUserAgent } from "nxapi";
|
||||
import ValueCache from '../common/ValueCache.mjs';
|
||||
|
||||
let _nxapiInitialized = false;
|
||||
|
||||
function initializeNxapi() {
|
||||
if (!_nxapiInitialized) {
|
||||
addUserAgent(process.env.USER_AGENT);
|
||||
}
|
||||
|
||||
_nxapiInitialized = true;
|
||||
}
|
||||
|
||||
export default class NsoClient
|
||||
{
|
||||
constructor(nintendoToken = null) {
|
||||
initializeNxapi();
|
||||
|
||||
this.nintendoToken = nintendoToken || process.env.NINTENDO_TOKEN;
|
||||
this.coralCache = new ValueCache('coral');
|
||||
}
|
||||
|
||||
_calculateCacheExpiry(expiresIn) {
|
||||
let expires = Date.now() + expiresIn * 1000;
|
||||
|
||||
// Expire 5min early to make sure we have time to execute requests
|
||||
return expires - 5 * 60 * 1000;
|
||||
}
|
||||
|
||||
async getCoralApi() {
|
||||
let data = await this.coralCache.getData();
|
||||
|
||||
if (!data) {
|
||||
data = await this._createCoralSession();
|
||||
}
|
||||
|
||||
return CoralApi.createWithSavedToken(data);
|
||||
}
|
||||
|
||||
async _createCoralSession() {
|
||||
console.debug('Creating Coral session');
|
||||
let { data } = await CoralApi.createWithSessionToken(this.nintendoToken);
|
||||
|
||||
let expires = this._calculateCacheExpiry(data.credential.expiresIn);
|
||||
console.debug(`Caching Coral session until: ${expires}`);
|
||||
await this.coralCache.setData(data, expires);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async getWebServiceToken(id) {
|
||||
let tokenCache = new ValueCache(`webservicetoken.${id}`);
|
||||
let token = await tokenCache.getData();
|
||||
|
||||
if (!token) {
|
||||
token = await this._createWebServiceToken(id, tokenCache);
|
||||
}
|
||||
|
||||
return token.accessToken;
|
||||
}
|
||||
|
||||
async _createWebServiceToken(id, tokenCache) {
|
||||
let coral = await this.getCoralApi();
|
||||
|
||||
console.debug(`Creating web service token for ID ${id}`);
|
||||
let { result } = await coral.getWebServiceToken(id);
|
||||
|
||||
let expires = this._calculateCacheExpiry(result.expiresIn);
|
||||
console.debug(`Caching web service token for ID ${id} until: ${expires}`);
|
||||
await tokenCache.setData(result, expires);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
2161
package-lock.json
generated
2161
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
|
@ -13,6 +13,7 @@
|
|||
"cron": "^2.1.0",
|
||||
"dotenv": "^16.0.2",
|
||||
"ecstatic": "^4.1.4",
|
||||
"nxapi": "^1.4.0",
|
||||
"pinia": "^2.0.13",
|
||||
"puppeteer": "^17.0.0",
|
||||
"twitter-api-v2": "^1.12.5",
|
||||
|
|
|
|||
2
storage/.gitignore
vendored
Normal file
2
storage/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||
Loading…
Reference in New Issue
Block a user