Browser JSON API

From Kolmafia
Revision as of 15:06, 26 October 2024 by Ikzann (talk | contribs) (add details)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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;
}