Script API Reference
Hodor runs your scripts in a built-in JavaScript engine. Depending on the script type, Hodor calls one of the entry functions below at the right time — you only implement the logic you need. If you do not modify anything, delete the unused entry function to avoid unnecessary calls.
Available global objects and classes:
| Category | Names |
|---|---|
| Entry functions | onRequest, onResponse, onSessionCompleted, onSchedule, abort() |
Native $ modules | $codec, $hash, $hmac, $crypto, $jwt, $format, $fs, $env, $uuid, $log |
| Web standard APIs | fetch, HTTPClient, setTimeout / setInterval, btoa / atob / sleep / require / TextEncoder / crypto, console |
| HTTP classes | Request, Response, Body, Headers, URLSearchParams |
| Storage | SharedPreferences, sdk variables |
| Contexts | RewriteContext, CompletedContext, ScheduleContext |
Use console.log(...) anywhere in a script to inspect values — output is shown in the script's log view.
Entry Functions
Scripts are detected by scanning for async function declarations — the parameter count of each entry function is fixed (onRequest/onResponse take 3, onSessionCompleted takes 4, onSchedule takes 1). Arrow-function assignments (let onRequest = async (...) => {}) are not detected. Parameter names are free.
onRequest(context, url, request)
Designed for Rewrite Script and Quick Request pre-request scripts. This function is called before the HTTP request is sent to the server. Return the (possibly modified) request.
| Parameter | Type | Description |
|---|---|---|
context | RewriteContext | The context object. |
url | string | The URL of the HTTP request. |
request | Request | The HTTP request object. |
// modify request body
async function onRequest(context, url, request) {
// parse to Text
var text = request.body.parseText()
console.log(text)
request.body = "this is a replaced request text"
// parse to JSON
var json = request.body.parseJSON()
json["script_json"] = "JSONValue"
request.body = json
// parse to URLSearchParams
var urlencoded = request.body.parseURLSearchParams()
urlencoded.append("script", "parseURLSearchParams")
request.body = urlencoded
// Done
return request;
}
// redirect, modify path / queries / headers
async function onRequest(context, url, request) {
console.log(url);
// set a parameter, you can get it in onResponse
context.parameters["custom"] = "custom parameter on request"
// redirect
request.scheme = "http"
request.path = "/upload/json"
request.host = "192.168.3.30"
request.port = 6000
// change method
request.method = "POST"
// queries operation
request.queries.append("name", "value1") // add query
request.queries.set("name", "value2") // replace or add query
request.queries.get("name") // get query by name
request.queries.delete("name") // delete query by name
// headers operation
request.headers.delete("accept") // delete header by name
request.headers.append("hodor", "custom value") // add name-value pair
request.headers.forEach((value, name) => {
console.log(name + ":" + value)
});
// Done
return request;
}
onResponse(context, url, response)
Designed for Rewrite Script and Quick Request post-response scripts. This function is called before the HTTP response is sent to the client. Return the (possibly modified) response.
| Parameter | Type | Description |
|---|---|---|
context | RewriteContext | The context object. |
url | string | The URL of the HTTP response. |
response | Response | The HTTP response object. |
// response body
async function onResponse(context, url, response) {
// parse to Text
var text = response.body.parseText()
console.log(text)
response.body = "this is a replaced response text"
// parse to JSON
var json = response.body.parseJSON()
json["script_json"] = "JSONValue"
response.body = json
// parse to URLSearchParams
var urlencoded = response.body.parseURLSearchParams()
urlencoded.append("script", "parseURLSearchParams")
response.body = urlencoded
// Done
return response;
}
// change status code and headers
async function onResponse(context, url, response) {
// get parameters set in onRequest
console.log(context.parameters["custom"]) // Output "custom parameter on request"
response.statusCode = 200 // change status code
response.statusPhrase = "OK" // change status phrase
response.headers.delete("accept")
response.headers.append("hodor", "custom value")
response.headers.forEach((value, name) => {
console.log(name + ":" + value)
});
// Done
return response
}
onSessionCompleted(context, url, request, response)
Designed for HTTP Completed Script. Called asynchronously after the HTTP response is returned, without affecting data transmission between the app and the server. Useful for data collection and forwarding.
| Parameter | Type | Description |
|---|---|---|
context | CompletedContext | The context object. |
url | string | The URL of the HTTP request. |
request | Request | The HTTP request object. |
response | Response | The HTTP response object. |
// sample: pass session data to your own server
async function onSessionCompleted(context, url, request, response) {
try {
var reqText = request.body.parseText();
var rspText = response.body.parseText()
var params = {
"body": { // HTTPClient post body data
"url": url, // request url
"reqHeader": request.headers.encode(), // request headers
"reqText": reqText, // request body
"rspHeader": response.headers.encode(), // response headers
"rspText": rspText, // response body
},
"headers": { // HTTPClient headers
"from": "onSessionCompleted"
},
}
const rsp = await HTTPClient.post("http://192.168.3.30:8000/upload", params)
let text = rsp.body.parseText()
console.log(text)
} catch(error) {
console.log(error)
}
}
onSchedule(context)
Designed for Schedule Script. Called at the scheduled trigger time (5 or 6-part cron expressions are supported). Use abort() to stop the schedule loop.
| Parameter | Type | Description |
|---|---|---|
context | ScheduleContext | The context object. |
async function onSchedule(context) {
// set custom parameters for next runloop
context.parameters["custom"] = "custom parameters for next runloop";
// repeated count
console.log(`repeatedCount ${context.repeatedCount}`);
// if repeatedCount is 2, abort schedule
if (context.repeatedCount == 2) {
abort()
}
// you can also use HTTPClient to send requests
const rsp = await HTTPClient.get("https://www.apple.com")
let text = rsp.body.parseText()
console.log(text)
}
abort()
Inside channel scripts (onRequest / onResponse / onSchedule), call abort() to stop the script and abort the current execution immediately — it throws an AbortError that Hodor reports back to you.
// ✅ correct — abort() is injected into the script scope
async function onRequest(context, url, request) {
if (url.includes("/tracking")) abort();
return request;
}
Do not declare onRequest(context, url, request, aborter) with a 4th parameter. The parameter count of entry functions is fixed — a 4th parameter makes the entry undetectable.
Native Modules
All $-prefixed modules are injected when the runtime activates. They are implemented natively, return synchronously (unless noted) and treat string inputs as UTF-8.