Raw Requests and Raw Events
Call a Fluxer route that has no method, and read a gateway event that has no typed event
Most bots never need this page. When a Fluxer route has no Fluxerly method, or a gateway event has no typed event, the SDK still gives a way in. The endpoint map lists the routes that Fluxerly methods call, the other routes that accept the bot's token, and a few noted exceptions, with why the routes without a method rarely matter. It leaves out routes that need no token, such as sign-in, but client.rest.request can still send them
Call a Route Without a Method
A Fluxer route that has no Fluxerly method can still be called. The client.rest.call method sends it with the bot's token, and the compiler checks it against Fluxer's API description, with Fluxer's own field names. This one reads a channel's latest messages:
export async function latestContents(client, channelId) {
const result = await client.rest.call("GET /channels/{channel_id}/messages", {
params: { channel_id: channelId },
query: { limit: 10 },
})
return result.map((response) => response.body.map((message) => message.content))
}
import type { Client } from "@neontechspace/fluxerly"
export async function latestContents(client: Client, channelId: string) {
const result = await client.rest.call("GET /channels/{channel_id}/messages", {
params: { channel_id: channelId },
query: { limit: 10 },
})
return result.map((response) => response.body.map((message) => message.content))
}
The route is written as Fluxer's documentation writes it. The params field fills its path template, query holds the query and body the JSON body, and the response body has the route's type, so a misspelled field, a missing required field or an unlisted route fails to compile. An array sends a repeated parameter, so query: { tag: ["101", "102"] } sends tag=101&tag=102, and the message routes also take files
The types come from Fluxer's OpenAPI document at the commit this release pins, with a few reviewed corrections that cite Fluxer's source. RestRoutes links each route to its section of Fluxer's documentation. Nothing checks Fluxer's answer at runtime, so check a response field before relying on it
Routes Newer Than the SDK
The client.rest.request method takes any path and body, for a route or field newer than the pinned description, or a route that needs no token. This one reads another application's public name, from a route that needs no token:
export async function applicationName(client, applicationId) {
const result = await client.rest.request({
method: "GET",
path: `/oauth2/applications/${applicationId}/public`,
})
return result.map((response) => (typeof response.body.name === "string" ? response.body.name : undefined))
}
import type { Client } from "@neontechspace/fluxerly"
export async function applicationName(client: Client, applicationId: string) {
const result = await client.rest.request<{ name?: unknown }>({
method: "GET",
path: `/oauth2/applications/${applicationId}/public`,
})
return result.map((response) => (typeof response.body.name === "string" ? response.body.name : undefined))
}
The path is the part after /v1, with the query in query. The type argument only names the expected body, so check each field before relying on it
What Both Methods Share
Both use the queue, rate limits, deadline and logging of the named methods. Logs name only the route, never the query, body or answer, unless logging.unsafe prints masked bodies for the rest category while debugging. A non-2xx answer fails the Result with RestRequestError, whose status and apiError say what Fluxer answered, and invalid input, such as a missing path parameter, fails with reason input before anything is sent. Neither method reads nor updates the caches
Read an Event Without a Type
Every gateway event also arrives as the raw event, in the form Fluxer sent it. Types listed in gateway do not arrive, apart from the mention and reaction batch exceptions that gateway describes. When documented is true, Fluxer's documentation describes the event's type, and comparing t with that type gives d its documented fields under Fluxer's own names, so a misspelled field fails to compile. This one notices when the bot's own membership of a thread changes:
export function watchOwnThreadMembership(client) {
return client.on("raw", (dispatch) => {
if (!dispatch.documented || dispatch.t !== "THREAD_MEMBER_UPDATE")
return
console.log(`The bot's membership of thread ${dispatch.d.id} in guild ${dispatch.d.guild_id} changed`)
})
}
import type { Client } from "@neontechspace/fluxerly"
export function watchOwnThreadMembership(client: Client) {
return client.on("raw", (dispatch) => {
if (!dispatch.documented || dispatch.t !== "THREAD_MEMBER_UPDATE") return
console.log(`The bot's membership of thread ${dispatch.d.id} in guild ${dispatch.d.guild_id} changed`)
})
}
The types come from Fluxer's gateway and HTTP API documentation at the Fluxer commit the SDK was reviewed against. They check nothing at runtime: d is still the body Fluxer sent, which can lack a documented field or carry a newer one, so check a field before relying on it. A type that documentation does not describe, such as one Fluxer added later, still arrives, with documented: false and an unknown d to validate. Gateway names the payload of each documented type, and Gateway the objects inside them, keyed by the address of their documentation, such as Gateway
A raw handler turns off ignored, so the bot also receives the event types that setting would skip. With ignored, register the raw handler before client.connect. Automatic filtering is decided when Identify starts a new session. Adding a raw handler later does not change that session's filtering, and Resume keeps the existing list
Read a Refused Voice Join
The raw event receives only opcode 0 dispatches. Fluxer sends an opcode 12 Gateway Error frame when it refuses a voice join the session asked for, and that frame arrives as the gatewayError event, with Fluxer's code and message in d:
export function reportRefusedVoiceJoins(client) {
return client.on("gatewayError", (frame) => {
console.log(`Shard ${frame.shardId} could not join voice: ${frame.d.code}`)
})
}
import type { Client } from "@neontechspace/fluxerly"
export function reportRefusedVoiceJoins(client: Client) {
return client.on("gatewayError", (frame) => {
console.log(`Shard ${frame.shardId} could not join voice: ${frame.d.code}`)
})
}
At the reviewed Fluxer commit the codes are VOICE_, VOICE_ and VOICE_CHANNEL_FULL, and other refused joins send no frame. The connection stays open. The frame has no sequence number, so Resume does not replay it and a frame sent while the shard is disconnected is lost. gateway never suppresses it. Without a gatewayError subscription, the SDK logs each frame at Warn with the code gateway.gatewayError. In a test, test delivers one to the bot
Send a Gateway Command Without a Method
The client.gateway.send method sends an outgoing gateway command that has no method. Core concepts explains how it shares pacing with the SDK's own commands. When Fluxer refuses a Voice State Update sent this way, the answer is a Gateway Error frame
The Effect API has the same client.rest.call and client.rest.request methods and raw and gatewayError events