106 lines
2.5 KiB
TypeScript
106 lines
2.5 KiB
TypeScript
import { Mize } from "@ppc/marts/stub_deno";
|
|
|
|
export const opts = {
|
|
"habitica.api_url": {
|
|
env_var_name: "PPC_HABITICA_API_URL",
|
|
default_val: "https://habitica.com/api/v3",
|
|
},
|
|
"habitica.user_id": {
|
|
env_var_name: "PPC_HABITICA_USER_ID",
|
|
},
|
|
"habitica.client_name": {
|
|
default_val: "3544a0b8-d71a-46e0-9bb1-6ddbb2abcddb-PPC-Software",
|
|
},
|
|
"habitica.api_token": {
|
|
env_var_name: "PPC_HABITICA_API_TOKEN",
|
|
},
|
|
};
|
|
|
|
export async function habitica(mize: Mize) {
|
|
console.log("hiiiiiiiiiiiiiiiiiiii");
|
|
mize.add_opts(opts);
|
|
|
|
mize.add_part(new Habitica(mize));
|
|
}
|
|
|
|
async function handleRateLimit(response) {
|
|
const limit = response.headers.get("X-RateLimit-Limit") || "NONE";
|
|
const remaining = parseInt(
|
|
response.headers.get("X-RateLimit-Remaining") || "10",
|
|
10,
|
|
);
|
|
const reset = response.headers.get("X-RateLimit-Reset");
|
|
|
|
console.log(
|
|
`RateLimit: ${limit} | Remaining: ${remaining} | Reset: ${reset}`,
|
|
);
|
|
|
|
if (remaining < 2 && reset) {
|
|
const resetDate = new Date(reset);
|
|
const now = new Date();
|
|
const waitMs = resetDate.getTime() - now.getTime() + 1000;
|
|
|
|
if (waitMs > 0) {
|
|
console.log(
|
|
`Waiting ${Math.round(waitMs / 1000)} secs for next rate limit window...`,
|
|
);
|
|
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
}
|
|
}
|
|
}
|
|
|
|
class Habitica {
|
|
mize: Mize;
|
|
|
|
constructor(mize: Mize) {
|
|
this.mize = mize;
|
|
}
|
|
|
|
async get_tasks(type: string = "todos") {
|
|
return await this.api_request("GET", `tasks/user?type=${type}`);
|
|
}
|
|
|
|
async delete_task(id: string) {
|
|
await this.api_request("DELETE", `tasks/${id}`);
|
|
}
|
|
|
|
async api_request(
|
|
method: string,
|
|
path: string,
|
|
extraHeaders: object = {},
|
|
data: object = {},
|
|
) {
|
|
const mize = this.mize;
|
|
|
|
if (!path.startsWith("/")) {
|
|
path = "/" + path;
|
|
}
|
|
const headers = Object.assign(
|
|
{
|
|
"Content-Type": "application/json",
|
|
"x-api-user": mize.get_config("habitica.user_id"),
|
|
"x-api-key": mize.get_config("habitica.api_token"),
|
|
"x-client": mize.get_config("habitica.client_name"),
|
|
},
|
|
extraHeaders,
|
|
);
|
|
|
|
const response = await fetch(mize.get_config("habitica.api_url") + path, {
|
|
method,
|
|
headers,
|
|
body: JSON.stringify(data),
|
|
});
|
|
|
|
await handleRateLimit(response);
|
|
|
|
if (!response.ok) {
|
|
console.log("request_url:", mize.get_config("habitica.api_url") + path);
|
|
throw new Error(
|
|
`Habitica API error: ${response.status} ${response.statusText}`,
|
|
);
|
|
}
|
|
|
|
return (await response.json()).data;
|
|
}
|
|
}
|