Browser JSON API: Difference between revisions

From Kolmafia
Jump to navigation Jump to search
Ikzann (talk | contribs)
create browser json page
 
Ikzann (talk | contribs)
add details
 
Line 1: Line 1:
Any relay script that injects client-side JavaScript code into the relay browser can get access to Mafia data by making an HTTP request to the <code>/KoLmafia/jsonApi</code> endpoint. Requests should be x-www-urlencoded with <code>pwd=[hash]</code> and <code>body=[json object]</code>.
Any relay script that injects client-side JavaScript code into the relay browser can get access to Mafia data by making an HTTP request to the <code>/KoLmafia/jsonApi</code> endpoint. Requests should be x-www-urlencoded with <code>pwd=[hash]</code> and <code>body=[json object]</code>.
== Request API ==


The JSON request object has the type <code>{ properties?: string[], functions?: { name: string, args: unknown[] }[] }</code>. Names of functions are in JS style (camelCase).
The JSON request object has the type <code>{ properties?: string[], functions?: { name: string, args: unknown[] }[] }</code>. Names of functions are in JS style (camelCase).
Line 8: Line 10:


Details for an enumerated type instance can be requested with the special <code>identity</code> function, which can take placeholder arguments and return the full object.
Details for an enumerated type instance can be requested with the special <code>identity</code> function, which can take placeholder arguments and return the full object.
== Example ==
Example request body:
<pre>
{
  "properties": ["kingLiberated"],
  "functions": [{ "name": "availableAmount", "args": [{
    "objectType": "Item",
    "identifierString": "seal-clubbing club"
  }] }]
}
</pre>
Example response:
<pre>
{
  "properties": [true],
  "functions": [0]
}
</pre>
== TypeScript code ==
The following browser TypeScript code will allow easy submission of API calls. Or you can use the more full-featured <code>tome-kolmafia</code> library to handle this all for you.
<pre>
type ApiRequest = {
  properties?: readonly string[];
  functions?: readonly { name: string; args: unknown[] }[];
};
type ApiResponse = {
  properties?: string[];
  functions?: unknown[];
};
export async function apiCall(
  request: ApiRequest,
  pwd: string,
): Promise<ApiResponse> {
  const response = await fetch("/KoLmafia/jsonApi", {
    method: "post",
    body: new URLSearchParams({
      body: JSON.stringify(request),
      pwd,
    }),
    headers: {
      // Mafia only accepts this format.
      "Content-Type": "application/x-www-form-urlencoded",
    },
  });
  const json = await response.json();
  if ("error" in json) {
    throw new Error(json.error);
  }
  return json;
}
</pre>

Latest revision as of 15:06, 26 October 2024

Any relay script that injects client-side JavaScript code into the relay browser can get access to Mafia data by making an HTTP request to the /KoLmafia/jsonApi endpoint. Requests should be x-www-urlencoded with pwd=[hash] and body=[json object].

Request API

The JSON request object has the type { properties?: string[], functions?: { name: string, args: unknown[] }[] }. Names of functions are in JS style (camelCase).

The response will have type { error: string } or { properties?: string[], functions?: unknown[] }, with properties and functions each present if they were present on the request object. The ordering of each of properties and functions will correspond to the request ordering.

Enumerated types (Item, Familiar, Modifier, etc.) can be passed in with either of the following placeholder formats: { objectType: EnumeratedTypeName, identifierString: string } | { objectType: EnumeratedTypeName, identifierNumber: number }. If both identifierString and identifierNumber are present, identifierNumber will be prioritized. Enumerated types will be returned as a POJO with all the fields of a JS enumerated type, with field names in camelCase, except any second-level referenced objects will be left as placeholders. Objects will also have the placeholder fields (objectType, identifierString, identifierNumber if applicable) set.

Details for an enumerated type instance can be requested with the special identity function, which can take placeholder arguments and return the full object.

Example

Example request body:

{
  "properties": ["kingLiberated"],
  "functions": [{ "name": "availableAmount", "args": [{
    "objectType": "Item",
    "identifierString": "seal-clubbing club"
  }] }]
}

Example response:

{
  "properties": [true],
  "functions": [0]
}

TypeScript code

The following browser TypeScript code will allow easy submission of API calls. Or you can use the more full-featured tome-kolmafia library to handle this all for you.

type ApiRequest = {
  properties?: readonly string[];
  functions?: readonly { name: string; args: unknown[] }[];
};

type ApiResponse = {
  properties?: string[];
  functions?: unknown[];
};

export async function apiCall(
  request: ApiRequest,
  pwd: string,
): Promise<ApiResponse> {
  const response = await fetch("/KoLmafia/jsonApi", {
    method: "post",
    body: new URLSearchParams({
      body: JSON.stringify(request),
      pwd,
    }),
    headers: {
      // Mafia only accepts this format.
      "Content-Type": "application/x-www-form-urlencoded",
    },
  });
  const json = await response.json();
  if ("error" in json) {
    throw new Error(json.error);
  }
  return json;
}