2026-09-17 14:15:37 +03:00
|
|
|
# Modules
|
|
|
|
|
|
|
|
|
|
Source: `src/domains/ModulesDomain.ts`. Calls an installed module function as
|
|
|
|
|
the signed-in player through `POST /sdk/v1/modules/{module}/{fn}`.
|
|
|
|
|
|
2026-09-17 15:28:08 +03:00
|
|
|
## Generated clients
|
2026-09-17 14:15:37 +03:00
|
|
|
|
2026-09-17 15:28:08 +03:00
|
|
|
Use `rudder client generate` from `liveops-module-sdk/cli` instead of calling
|
|
|
|
|
modules by name:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
export RUDDER_URL=https://api.rudder.build RUDDER_TOKEN=... RUDDER_PROJECT=...
|
|
|
|
|
rudder client generate --lang ts --out src/rudder.modules.ts # staging by default
|
|
|
|
|
rudder client generate --lang ts --out src/rudder.modules.ts --environment prod
|
|
|
|
|
rudder client generate --lang ts --manifests ./modules --out src/rudder.modules.ts # local manifests
|
2026-09-17 14:15:37 +03:00
|
|
|
```
|
|
|
|
|
|
2026-09-17 15:28:08 +03:00
|
|
|
The file reads the manifests of the installed modules, generates only
|
|
|
|
|
`trigger: client` functions, and lists every module with its version in the
|
|
|
|
|
header. It exports:
|
2026-09-17 14:15:37 +03:00
|
|
|
|
2026-09-17 15:28:08 +03:00
|
|
|
- `modules(client)`: `{ <module>: { <fn>(args): Promise<Result> } }`
|
|
|
|
|
- `<Module><Fn>Args` / `<Module><Fn>Result` types from the manifest schemas
|
|
|
|
|
- `<Module><Fn>Error`: the function's declared codes plus `RudderKernelError`
|
2026-09-17 14:15:37 +03:00
|
|
|
|
|
|
|
|
```ts
|
2026-09-17 15:28:08 +03:00
|
|
|
import { createClient, RudderModuleError } from '@rudder/sdk';
|
|
|
|
|
import { modules, type StoreBuyError } from './rudder.modules';
|
|
|
|
|
|
|
|
|
|
const m = modules(createClient({ projectKey }));
|
2026-09-17 14:15:37 +03:00
|
|
|
try {
|
2026-09-17 15:28:08 +03:00
|
|
|
const result = await m.store.buy({ offer: 'starter_pack' });
|
2026-09-17 14:15:37 +03:00
|
|
|
} catch (error) {
|
2026-09-17 15:28:08 +03:00
|
|
|
if (error instanceof RudderModuleError) {
|
|
|
|
|
switch (error.code as StoreBuyError) {
|
|
|
|
|
case 'insufficient_funds': /* ... */ break;
|
|
|
|
|
case 'offer_not_found': /* ... */ break;
|
|
|
|
|
}
|
2026-09-17 14:15:37 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
2026-09-17 15:28:08 +03:00
|
|
|
|
|
|
|
|
Commit the generated file and regenerate it when installed modules change.
|
|
|
|
|
Do not edit it by hand.
|
|
|
|
|
|
|
|
|
|
## `modules.call`
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
client.modules.call<T = unknown>(
|
|
|
|
|
module: string,
|
|
|
|
|
fn: string,
|
|
|
|
|
args?: unknown,
|
|
|
|
|
options?: { moduleVersion?: string },
|
|
|
|
|
): Promise<T>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- Sends `{ args }`; `args` is `{}` when omitted. Resolves to the response
|
|
|
|
|
`result`. Console output and the kernel call log never reach players.
|
|
|
|
|
- Idempotency: each call generates one `Idempotency-Key` (UUID v4) and sends
|
|
|
|
|
the same key on every retry, so the server runs the function at most once
|
|
|
|
|
and returns the stored response for a repeated key. A new `call()` gets a
|
|
|
|
|
new key.
|
|
|
|
|
- Retries: up to 2, with jittered exponential backoff, on network errors, 5xx
|
|
|
|
|
and 409 with code `conflict`. Other 4xx responses (including other 409
|
|
|
|
|
codes) are never retried.
|
|
|
|
|
- `moduleVersion` (set by generated clients) is sent as
|
|
|
|
|
`X-Rudder-Module-Version: <module>@<version>`. A major mismatch with the
|
|
|
|
|
installed module is logged on the backend; the call still runs.
|
|
|
|
|
|
|
|
|
|
## Errors
|
|
|
|
|
|
|
|
|
|
- 422 `{ error, code, requestId }` rejects with `RudderModuleError<C>`
|
|
|
|
|
(`status` 422, `code`, `message` from `error`, `requestId`). `C` defaults
|
|
|
|
|
to `string`; use the generated union to narrow it.
|
|
|
|
|
- A trap is a 500 and a timeout a 504, both `RudderHttpError` without details
|
|
|
|
|
(after the retries above).
|
|
|
|
|
- 401 follows the normal refresh flow (`RudderAuthError` when it fails).
|