On This Page

Events and Collectors

56 symbols from @neontechspace/fluxerly

Interfaces#

CallCreate#

A private-channel call began or became visible, including initial call state delivered shortly after READY and state recovered after a lost call connection

Recovered state can repeat a call that was already observed, so this is not proof that a new call started

interface CallCreate extends CallUpdateinterface CallCreate
  extends CallUpdate
createdAtMs optional#

Unix time in milliseconds when the call was opened

Present only on initial or recovered call state

number
recipientIds optional#

Every recipient of the channel, whether or not they joined the call

Present only on initial or recovered call state

readonly string[]

Inherited from CallUpdate: channelId, messageId, region, ringingUserIds, voiceStates

CallDelete#

A private-channel call ended or became temporarily unavailable

interface CallDelete
channelId#

Private channel ID the call took place in

string
unavailable#

True when the call became unavailable rather than ending

An unavailable call can return with a later callCreate that includes its recipients and creation time, although Fluxer does not guarantee recovery

boolean

CallUpdate#

Current state of an active private-channel call: Its ringing set, participants and voice region

This is a frozen observation, not a patch to merge and not a cached call record. Changes can be missed during connection gaps

interface CallUpdate
channelId#

Private channel ID the call takes place in

string
messageId#

ID of the call message that opened the call

string
region#

Voice region serving the call, or null until Fluxer chooses one

string | null
ringingUserIds#

Account IDs currently being rung, in received order

readonly string[]
voiceStates#

Connected participants, frozen in Fluxer's order by participant ID

readonly CallVoiceState[]

CallVoiceState#

One participant's connection in a private call, as observed when the call was created or updated

The fields match VoiceState without a community and member, since calls take place in private channels and Fluxer attaches no community member there. Fluxer's region_id and server_id entry fields are internal routing data and are not projected

interface CallVoiceState
    extends Omit<VoiceState, "guildId" | "member">interface CallVoiceState
  extends Omit<
    VoiceState,
    "guildId" | "member"
  >

Inherited from VoiceState: channelId, connectionId, isDeafened, isE2eeCapable, isMobile, isMuted, isPeerToPeer, isSelfDeafened, isSelfMuted, isSelfStreaming, isSelfVideoOn, isSuppressed, sessionId, userId, version, viewerStreamKeys

ChannelPinsUpdate#

Notice that a channel's pins changed, without identifying the pinned or unpinned message

Fetch pins explicitly for the current list. This event does not fetch it automatically

interface ChannelPinsUpdate
channelId#

Affected channel ID as a decimal string

string
guildId optional#

Community ID when Fluxer supplies it

Omission means no community context was supplied, not a confirmed private channel. No channel lookup or cache inference supplies this field

string
lastPinTimestamp#

Last-pin time supplied by Fluxer as an ISO 8601 string, or null

This value can stay unchanged after an unpin, so it is not a unique change cursor

string | null

Collector#

Wait for the bounded message collection created by messages.collect

Use close to end intake early and result to obtain its final result. Use await using to close the collector and wait for its cleanup when the enclosing block ends

interface Collector<M extends MessageCore = Message>interface Collector<
  M extends MessageCore = Message
>

[asyncDispose]#

Close this collector and wait for its cleanup, as await using does at the end of a block

The collection outcome is not rethrown here. Read it from result when it matters

[asyncDispose](): Promise<void>
Returns
Promise<void>

close#

Stop accepting messages now, keeping accepted messages for a successful partial result

Repeated calls preserve whichever terminal outcome was recorded first. Use result to await callback cleanup and read the collection

close(): void

Returns immediately

result#

Wait for the final frozen collection result after timer, queue, filter, listener and callback cleanup

Idle, timeout or stop can succeed with no messages or a partial collection. Collection cancellation, filter or callback failure, overflow, gateway loss and client closure fail without partial messages. Multiple or later waiters receive the same collection outcome. Cancelling this wait affects only the waiter, not collection. Keeping the handle or successful result keeps its message snapshots in memory

result(options?: OperationOptions): ResultAsync<
    CollectorResult<M>,
    ConfigurationError | CollectorFailure | CancelledError
>result(
  options?: OperationOptions
): ResultAsync<
  CollectorResult<M>,
  | ConfigurationError
  | CollectorFailure
  | CancelledError
>

Parameters

options optional
OperationOptions

Unexpected SDK failures reject with SdkDefect

CollectorOptions#

Choose which new messages to collect in one channel and when to stop

Connect the client before registering. Collection does not read history or connect automatically. Only messageCreate observations are collected, using this client's selected message fields. Each accepted message ID is counted once. Later edits and deletions do not revise the result. Reaching the count or a listening deadline can finish successfully. Filter, handler, budget and connection failures return no partial result. For sharded clients, a shard is one gateway connection assigned to a group of communities

interface CollectorOptions<M extends MessageCore = Message>
    extends EventBufferOptionsinterface CollectorOptions<
  M extends MessageCore = Message
>
  extends EventBufferOptions

An optional callback handles each accepted message, and an optional AbortSignal cancels the whole collection. The Effect entry point instead accepts an Effect handler and owns collection through its registration scope

filter optional#

Return true to accept a message, or false to skip it

Omit to accept all messages in the channel, including bots. Runs synchronously in receive order, after channel selection. Do not return a Promise or perform blocking work. Throwing or returning anything except a boolean fails this collector with reason filter. A thrown value is the CollectorError cause. The failure is also reported to the client-level onError with kind filter and the message IDs, or logged at Error. Asynchronous work returned by mistake is neither awaited nor cancelled, and its rejection is discarded. A slow filter blocks other JavaScript work. The collector checks its deadlines again after the filter returns

(message: M) => boolean
guildId optional#

Community that owns this channel, as a positive decimal ID within the unsigned 64-bit range

The caller must supply the correct community, because the SDK does not fetch the channel to verify membership. Its assigned gateway shard must be connected. Recovery of that shard ends collection, while unrelated shards do not. Events with a different supplied guildId are discarded. Missing community context does not prove the channel is private. Omit this option for unknown or private scope. Then the whole gateway must be connected and any shard recovery ends collection

string
idleMs optional#

Stop successfully after this many milliseconds without an accepted message

Omit to disable this deadline. Integer 1 through 2,147,483,647. The interval starts at registration and resets before each accepted message's callback. Rejected messages, duplicate IDs and messages still queued do not reset it. Callback time counts as idle time. The earlier idle or total deadline wins. Equal deadlines produce reason timeout

number
maxBytes optional#

Maximum UTF-8 JSON bytes kept for accepted messages

Positive safe integer, default 4,194,304, not a total memory limit

number
maxMessages optional#

Stop successfully after this many accepted messages and their callbacks

Positive safe integer, default 1

number
onMessage optional#

Process accepted messages one at a time, after filtering and acceptance into the retained-byte budget

Return the asynchronous work so collection can wait for it. If it returns an Err result, collection stops with that error, like a throw. To recover instead, check the Result inside the callback. A throw or rejected Promise fails collection with CollectorError reason handler, whose cause is the thrown value. The callback is not retried. The failure is also reported to the client-level onError with kind collector and the message IDs, or logged at Error. Terminal completion aborts the callback's signal and waits for its returned Promise, including on stop, timeout and shutdown. Work that ignores the signal can hold completion open indefinitely. Do not await this collector's completion or client shutdown here. Requests already dispatched by the callback are not rolled back

(message: M, signal: AbortSignal) => unknown(message: M, signal: AbortSignal)
  => unknown
signal optional#

Cancel the entire collection

An already-aborted signal rejects registration, a later abort returns CancelledError without partial messages

OperationSignal
timeoutMs optional#

Stop successfully after this many milliseconds from registration, regardless of activity

Integer 1 through 2,147,483,647, default 30,000

number

Inherited from EventBufferOptions: maxPendingBytes, maxPendingMessages

CollectorResult#

Messages collected before the count, total deadline, idle deadline or explicit stop ended collection

The frozen messages are past observations, not current server state or the complete conversation

interface CollectorResult<M extends MessageCore = Message>interface CollectorResult<
  M extends MessageCore = Message
>
messages#

Accepted snapshots in receive order, with each message ID included once

Later changes do not alter this array

readonly M[]
reason#

Why collection finished successfully: The count was met, total time expired, idle time expired, or stop was called

The reason limit waits for the final accepted callback. Other reasons can return an empty array or a message whose callback was cancelled

"stopped" | "idle" | "timeout" | "limit"| "stopped" | "idle" | "timeout"
| "limit"

DirectMessageRecipientChange#

IDs accompanying a private-channel recipient change

No automatic user fetch

interface DirectMessageRecipientChange
channelId#

Affected private channel

string
userId#

Added or removed account

string

EntranceSoundPlay#

A participant's entrance sound started playing in a voice channel or private call they were already connected to

Fluxer sends one event to every other connected participant, never to the participant whose sound plays. The SDK does not download the sound, fetch the channel or account, or cache this notice

interface EntranceSoundPlay
channelId#

Voice channel or private call channel ID

string
contentType#

Media type Fluxer reported for the sound file, such as audio/ogg

string
durationMs#

Sound length in whole milliseconds, a nonnegative safe integer

number
guildId#

Community that owns the voice channel, or null for a private call

string | null
hash#

Fluxer's content hash of the sound file, usable to reuse an already downloaded copy

string
soundId#

Entrance sound ID

string
url#

Address to download the sound from, as received and without an SDK download or validation of its host

string
userId#

Account ID of the participant whose sound plays

string

EventBufferOptions#

Limit the waiting queue for one event subscription or collector

Each registration owns its own queue. Filling it stops that registration, or drops events for a handler whose overflow policy drops them, and never affects unrelated subscriptions. These limits measure pending payloads and received JSON bytes, not total application memory use

interface EventBufferOptions
maxPendingBytes optional#

Maximum UTF-8 bytes of waiting received JSON, including full bulk payloads

Positive safe integer, default 4,194,304

number
maxPendingMessages optional#

Maximum waiting payloads, excluding active handlers

A bulk event counts once, positive safe integer, default 256

number

EventContext#

Delivery details for one event, passed to on handlers, runBot handlers and event middleware

The object is frozen and describes how this client received the event, not Fluxer state. The type parameters K and M choose the event and the client's message type that previous is typed for. A handler's context has both set for its event. The defaults accept the context of any event and message selection, so a helper that takes EventContext works with every handler

interface EventContext<
    K extends EventName = EventName,
    M extends MessageCore = MessageCore
>interface EventContext<
  K extends EventName = EventName,
  M extends MessageCore
    = MessageCore
>
previous optional#

The snapshot this client's cache held for the changed or removed entity just before it applied the event, as PreviousSnapshots lists per event, or undefined

It is undefined for every other event, when that cache category is disabled, and when the cache held no snapshot because the entity was never observed or its snapshot expired or was removed. Compare it with the payload to log what changed, and treat undefined as unknown, not as absent in Fluxer. A write through an SDK resource method updates the cache too, so the event after it can hold the value the write stored, or undefined where the write removed the entry, instead of the value from before the write. Every handler of the event receives the same frozen snapshot, which is not copied. A queued event keeps its snapshot in memory until the handler runs or the event is dropped, and maxPendingBytes does not count it. The SDK always sets the property. It is optional so that a context built by hand, such as in a unit test, can leave it out

PreviousSnapshot<K, M>
receipt#

A number that orders events by arrival

The client gives each event the next number when it accepts it, starting at 1 and counting across all of its shards in the order it received the events. Every handler of the same event sees the same number, and events decoded from one frame get consecutive numbers in dispatch order. Handlers of one community can run out of order because of handler concurrency, partitions or partitionReady, so compare receipts to learn which event came first: The smaller receipt arrived first. One handler sees gaps between the numbers, because the client also numbers events that its subscription does not receive, so only the order has meaning. Under a supervisor each child process numbers its own events, so receipts from different processes cannot be compared. The client's lastReceipt reads the newest receipt given, for work that is not an event

number
const newest = new Map()
export function isOutOfOrder(channelId, context) {
    const last = newest.get(channelId) ?? 0
    newest.set(channelId, Math.max(last, context.receipt))
    return context.receipt < last
}
import type { EventContext } from "@neontechspace/fluxerly"
const newest = new Map<string, number>()
export function isOutOfOrder(channelId: string, context: EventContext) {
    const last = newest.get(channelId) ?? 0
    newest.set(channelId, Math.max(last, context.receipt))
    return context.receipt < last
}
receivedBytes#

UTF-8 byte length of the whole received gateway frame that carried the event, the same size counted against maxPendingBytes

Events decoded from one frame, such as guildCreate and its voiceStateSnapshot, report the same value

number
sessionEpoch#

The receiving shard's ShardState.sessionEpoch when the client accepted the event, before it waited in this handler's queue

An event received before a new session keeps its earlier value even when the handler runs after the new session started, so compare this value rather than the shard's current one to tell which session an event belongs to. Keep the last value seen per community, because one shard serves many communities, and treat a changed value as a sign that events of that community between the two sessions may have been missed. Fluxer then sends the community again as a guildCreate event. It is 0 for events of a session resumed from a saved session before the shard's first new session in this client

number
const seen = new Map()
export function missedEvents(guildId, context) {
    const previous = seen.get(guildId)
    seen.set(guildId, context.sessionEpoch)
    return previous !== undefined && previous !== context.sessionEpoch
}
import type { EventContext } from "@neontechspace/fluxerly"
const seen = new Map<string, number>()
export function missedEvents(guildId: string, context: EventContext) {
    const previous = seen.get(guildId)
    seen.set(guildId, context.sessionEpoch)
    return previous !== undefined && previous !== context.sessionEpoch
}
shardId#

Local shard whose gateway connection received the event

A client without a sharding plan uses shard 0 until Fluxer requires more shards and it moves to automatic sharding

number

EventHandlerOptions#

Configure how client.on schedules handlers and reports their failures

The type parameter T is the event payload that a partition function receives

interface EventHandlerOptions<T = unknown> extends HandlerOptions<T>interface EventHandlerOptions<
  T = unknown
>
  extends HandlerOptions<T>
onError optional#

Receive this subscription's failures instead of the client-level onError: A handler that threw or rejected, with the original error and the IDs of the message being handled, or overflow that stopped the subscription

A failure only queues its report, so the hook never holds a handler slot. Reports are delivered one at a time in order, with up to 64 waiting while the hook is busy. Later ones are logged instead, with fields.reportOutcome "queueFull", and counted in diagnostics().counters.reportsDropped. A hook that throws or rejects is logged with the original failure and never retried. Reports already queued when the subscription closes are still delivered. Client shutdown does not wait for a pending hook promise. The report it was handling and any queued ones are logged at Error instead, with fields.reportOutcome "interrupted" for the report being handled and "subscriptionClosed" for queued or later reports

(report: FailureReport) => unknown
partitionReady optional#

Hold the events of a partition key until that key is ready, without using a handler slot

Valid only together with partition, otherwise registration throws ConfigurationError. Before the first waiting event of a key starts, the SDK calls this hook with the key. The key's events stay in the queue until the hook settles, while events of other keys keep starting. A held event does not use one of the concurrency slots, but it counts toward maxPendingMessages and maxPendingBytes, so a bot that waits for many keys at once needs a larger maxPendingMessages than the default 256. Held events also count as waiting work for a draining shutdown, so a hook that never settles makes the drain wait until its limit. A hook that returns a value other than a promise or thenable marks the key ready at once, with no extra turn. A returned promise holds the key until it resolves. The SDK remembers that a key is ready only while it has waiting or running events. After the key went idle, its next event calls the hook again, so memory stays bounded by the keys with queued work. Hooks for different keys run at the same time, and every burst of events after an idle period calls the hook again. Keep it a cheap, idempotent check that answers at once when the key is already ready, such as returning an already settled promise. Events without a key share the key "", and the hook receives "". With partition "guild", a direct message has no community, so its key is its channel ID. A hook should treat keys it does not know as ready. A hook that throws, rejects or fails reports every waiting event of that key as a failure of that event's handler, as a throwing partition function does, and those handlers do not run. The key is then forgotten, so a later event calls the hook again. The hook receives a signal that aborts when the subscription stops, which includes unsubscribing, client shutdown and a draining shutdown that reaches its drain limit. An Err result returned or resolved by the hook counts as a failure with its error

(key: string, signal: AbortSignal) => unknown(key: string, signal: AbortSignal)
  => unknown
export function afterServerSetup(client, setups) {
    // A server whose setup is unknown, such as a direct message channel, is ready at once
    return client.on("messageCreate", (message) => void message.content, {
        partition: "guild",
        partitionReady: (key) => setups.get(key),
    })
}
import type { Client } from "@neontechspace/fluxerly"
export function afterServerSetup(client: Client, setups: Map<string, Promise<void>>) {
    // A server whose setup is unknown, such as a direct message channel, is ready at once
    return client.on("messageCreate", (message) => void message.content, {
        partition: "guild",
        partitionReady: (key) => setups.get(key),
    })
}

Inherited from HandlerOptions: concurrency, maxPendingBytes, maxPendingMessages, overflow, partition

EventInvocationOf#

One on handler invocation of a specific event type, as seen by event middleware

interface EventInvocationOf<
    K extends EventName,
    M extends MessageCore = Message
>interface EventInvocationOf<
  K extends EventName,
  M extends MessageCore = Message
>
context#

Shard, its session epoch, receipt number, received size of the frame that carried the event and the previous snapshot

EventContext<K, M>
event#

Event name the subscription was registered for

K
payload#

Frozen event payload the handler receives

EventMap<M>[K]
subscriptionId#

Identifier of the subscription whose handler this invocation runs, such as messageCreate#3

string

EventMap#

Event names and payload types accepted by on, events and waitFor

Register listeners before triggering an action to observe its event. Payloads are frozen copies of data received from Fluxer. They cannot be changed and do not update as Fluxer changes. A new listener does not receive earlier events from the cache. Requests do not generate synthetic events. Changes can be missed during disconnection and recovery. Bulk events remain one event instead of also delivering their individual entries. Message events use this client's messageFields selection. Known malformed received data still fails the connection even if excluded. Community and account cache handling, where documented below, occurs before event delivery

interface EventMap<M extends MessageCore = Message>
    extends GuildLifecycleEventsinterface EventMap<
  M extends MessageCore = Message
>
  extends GuildLifecycleEvents
callCreate#

A private-channel call began or became visible, including initial and recovered call state, without a call cache

CallCreate
callDelete#

A private-channel call ended, or became unavailable when unavailable is true

CallDelete
callUpdate#

An active private-channel call's ringing set, participants or region changed

This is the full current state, not a patch

CallUpdate
channelPinsUpdate#

A channel's pins changed, with community context only when supplied and without fetching the list

Does not identify the message. The timestamp may stay unchanged after unpin

ChannelPinsUpdate
directMessageCreate#

A private conversation became visible to this bot, which does not prove it was just created

Updates its enabled private-conversation cache observation

DirectMessageChannel
directMessageDelete#

A private conversation closed, was left, or was deleted for this bot

Other accounts may still have access. Clears the enabled private-conversation cache and evicts this channel's cached messages

id

Private conversation channel ID as a decimal string

string
directMessageRecipientAdd#

A private conversation gained a recipient

Clears the enabled private-conversation cache without reconstructing a recipient list

DirectMessageRecipientChange
directMessageRecipientRemove#

A private conversation lost a recipient

Clears the enabled private-conversation cache without establishing conversation deletion

DirectMessageRecipientChange
directMessageUpdate#

Current private conversation data, without previous values to compare

Updates its enabled private-conversation cache observation

DirectMessageChannel
entranceSoundPlay#

Another participant's entrance sound started playing where this account has a voice connection, without a download or cache write

EntranceSoundPlay
guildAuditLogEntryCreate#

A newly recorded community audit entry, requiring VIEW_AUDIT_LOG

Its reason, options and changes are not safe diagnostic text

GuildAuditLogEntryCreate
guildBanAdd#

A ban was recorded for these community and account IDs, without full ban details or proof that member removal finished

Evicts the enabled member cache entry

MemberReference
guildBanRemove#

An explicit ban removal, not proof of rejoining

A ban expiring automatically may not emit this event. Evicts the enabled member cache entry

MemberReference
guildChannelCreate#

A community channel became visible, possibly after creation, without establishing its creation time or enumerating initial channels

Updates its enabled channel-cache observation

GuildChannel
guildChannelDelete#

A community channel was deleted or became invisible

Evicts its cached messages, without generating message deletion events. Evicts its enabled channel-cache entry. A category deletion invalidates all channels cached for that community. Deleting a text, announcement, forum or media channel also deletes its threads, and Fluxer sends no threadDelete for them. The channel cache then evicts the threads whose parentId is this channel, and the message cache evicts the messages of every channel in this community that the channel cache does not hold outside those threads, including messages without community context. Without the channel cache that is every message of the community. EventContext.previous holds the enabled channel cache's snapshot of the channel from before the event

GuildChannel
guildChannelUpdate#

Current community channel data

EventContext.previous holds the enabled channel cache's snapshot from before the update. Fetch explicitly if a decision requires fresh permissions. Updates its enabled channel-cache observation, except a category update invalidates all channels cached for the community. Fluxer retypes a converted channel's threads without thread events for archived ones, so a text or announcement channel update also evicts the channel's cached threads whose type its type cannot hold. Fluxer removes forum tags through this update alone and drops them from posts on read, so a forum or media channel update also evicts the channel's cached posts that apply a tag missing from its availableTags. Either update also stops pending reads from storing the channel's threads, whether or not the channel was cached. Other pending reads by ID, and reads of other communities, still store what they return, while a pending read of the channel's own community stores nothing

GuildChannel
guildChannelUpdateBulk#

Visible community-channel updates grouped into one batch, without individual guildChannelUpdate events

This is not the complete channel list or proof that permission copying has finished. Invalidates the enabled channel cache for this community

GuildChannelUpdateBulk
guildEmojisUpdate#

Updated community emoji collection, not an initial list or cache refill

Invalidates the enabled expression cache before delivery. Fetch explicitly when current state matters after a connection gap

GuildEmojisUpdate
guildHealthUpdate#

Community-server lag or recovery, without a disconnection, availability change, cache invalidation or automatic reconnect

GuildHealthUpdate
guildMemberAdd#

A member join observation, not an initial roster or complete community membership view

Updates the enabled member-cache observation

GuildMember
guildMemberRemove#

Membership ended, with only community and account IDs supplied

No account lookup or removal-cause inference follows. Evicts the enabled member-cache entry, and EventContext.previous holds the evicted snapshot

MemberReference
guildMemberUpdate#

Current member data

Fluxer can limit delivery by community size and session visibility, so fetch when current state matters. Updates the enabled member-cache observation, and EventContext.previous holds the snapshot it replaced. Before handlers run, invalidates the member's enabled account-cache entry and affected private-conversation snapshots

GuildMember
guildRoleCreate#

A community role creation observation, not an initial enumeration of roles

Updates the enabled role-cache observation

GuildRole
guildRoleDelete#

Deleted role's IDs, without a guarantee that affected members each produce an update

Invalidates enabled role and member caches for the community. EventContext.previous holds the enabled role cache's snapshot of the role from before the event

RoleReference
guildRoleUpdate#

Current role data

Updates the enabled role-cache observation, and EventContext.previous holds the snapshot it replaced

GuildRole
guildRoleUpdateBulk#

Role updates grouped into one batch, without individual guildRoleUpdate events or a complete role list

Updates the enabled role-cache observations for supplied roles

GuildRoleUpdateBulk
guildStickersUpdate#

Updated community sticker collection, not an initial list or cache refill

Invalidates the enabled expression cache before delivery. Fetch explicitly when current state matters after a connection gap

GuildStickersUpdate
inviteCreate#

Invite metadata supplied when an invite was created

Its code and URL grant access, so keep them out of diagnostics and public logs

InviteMetadata
inviteDelete#

A deleted invite's code and any destination IDs Fluxer still supplied, without reconstructing its old settings

InviteDeleteEvent
messageCreate#

Newly created message using this client's selected fields, with frozen nested metadata rather than downloaded file contents

Updates the enabled message-cache observation. Also stores the author's member, when Fluxer attached one, in the enabled member cache, whichever message fields the client selects

M
messageDelete#

One deleted message's channel and message IDs, plus supplied community ID, text and author ID when available

Evicts its enabled message-cache entry without reconstructing missing context, and EventContext.previous holds the evicted message

MessageDeletion
messageDeleteBulk#

Deleted message IDs grouped by channel, with community context only when supplied

Listen to this and messageDelete to observe both deletion forms. Evicts the listed enabled message-cache entries

MessageBulkDeletion
messageReactionAdd#

One user's reaction addition, not synthesized from reaction batches or successful addReaction requests

The enabled member cache stores the member Fluxer attached

MessageReaction
messageReactionAddMany#

Reaction additions grouped by Fluxer

Listen to this and messageReactionAdd to observe both addition forms

MessageReactionBatch
messageReactionRemove#

One user's reaction was removed, possibly by a moderator rather than that user

The enabled member cache stores the member Fluxer attached

MessageReaction
messageReactionRemoveAll#

All reactions on the target message were cleared, without a list of affected users

ReactionTarget
messageReactionRemoveEmoji#

All reactions using one emoji were cleared from the target message, without a list of affected users

MessageReactionEmojiRemoval
messageUpdate#

Message data supplied for an update, not a patch to merge

EventContext.previous holds the enabled message cache's snapshot from before the update. Optional metadata may be absent. A non-text change can deliver the same selected values again. Replaces the enabled message-cache observation rather than merging absent metadata from an older snapshot. Also stores the author's member, when Fluxer attached one, in the enabled member cache

M
presenceUpdate#

A delivered presence observation with its custom status, without account data, retained state or automatic member subscriptions

PresenceUpdate
presenceUpdateBulk#

Visible online presences delivered together after community recovery, without individual presenceUpdate events

PresenceUpdateBulk
raw#

Every received gateway dispatch in its wire form, including types this SDK version does not decode

The body is not part of the SDK's compatibility contract. See RawDispatch

RawDispatch
threadCreate#

A thread was created, or the bot joined or was added to an existing thread, as isNewlyCreated tells

Stores the thread, without isNewlyCreated, in the enabled channel cache

ThreadCreateEvent
threadDelete#

A thread was deleted

Evicts it from the enabled channel cache and evicts its cached messages, without generating message deletion events. Deleting a parent channel deletes its threads without this event. EventContext.previous holds the enabled channel cache's snapshot of the thread from before the event

ThreadDeletion
threadListSync#

The bot's active threads in a community, or in some of its channels, were replaced

Before delivery, the enabled channel cache evicts its threads in that scope and stores the listed ones. Fluxer never replays this event on Resume, so a resumed shard's cached threads are evicted instead

ThreadListSync
threadMembersUpdate#

Accounts joined or left a thread

When the bot is one of them, or before the bot's account ID is known, the enabled channel cache evicts the thread, because its membership changed. Otherwise the cached memberCount is not updated

ThreadMembersUpdate
threadUpdate#

Current thread data after a change such as a rename, archive or lock

Fluxer leaves the bot's membership out of this event. Replaces the thread's enabled channel-cache observation, and EventContext.previous holds the snapshot it replaced

GuildThreadChannel
typingStart#

A short-lived typing notice, subject to Fluxer's delivery filtering

It is not an account presence snapshot or cache entry. Carries the typing member when Fluxer attached one, and the enabled member cache stores it

TypingStart
userUpdate#

Current public account data, without private account settings

Updates the enabled account cache and clears the enabled private-conversation cache

User
voiceStateSnapshot#

Visible initial voice connections when a community becomes available, including an explicitly supplied empty collection

VoiceStateSnapshot
voiceStateUpdate#

A visible voice connection joined, changed or disconnected

A move can produce multiple phases, and no voice-state cache is updated

VoiceState
webhooksUpdate#

A visible community channel's webhook collection changed, without webhook details, tokens, cache writes or automatic requests

WebhooksUpdate

Inherited from GuildLifecycleEvents: guildCreate, guildDelete, guildUpdate

EventSubscription#

Read future events one at a time with next, then end the subscription with close

Each subscription receives the event type chosen in client.subscribe and keeps no previously delivered history. The default event type is messageCreate

interface EventSubscription<
    K extends EventName = "messageCreate",
    M extends MessageCore = Message
>
    extends Subscriptioninterface EventSubscription<
  K extends EventName
    = "messageCreate",
  M extends MessageCore = Message
>
  extends Subscription

next#

Wait for the next event, returning Ok(payload), or Ok(null) after normal closure

Only one pending next call is allowed. Another call returns EventReadBusyError. Aborting options.signal cancels this read without closing the subscription. Overflow discards the queue and remains an Err. Unexpected SDK failures reject with SdkDefect

next(options?: OperationOptions): ResultAsync<
    EventMap<M>[K] | null,
    ConfigurationError | EventReadError | CancelledError
>next(
  options?: OperationOptions
): ResultAsync<
  EventMap<M>[K] | null,
  | ConfigurationError
  | EventReadError | CancelledError
>

Parameters

options optional
OperationOptions
Returns
ResultAsync<
    EventMap<M>[K] | null,
    ConfigurationError | EventReadError | CancelledError
>ResultAsync<
  EventMap<M>[K] | null,
  | ConfigurationError
  | EventReadError | CancelledError
>

Inherited from Subscription: id, [asyncDispose], close, waitForClose

EventWaitOptions#

Settings for waitFor to receive one future event that passes an optional filter

Waiting does not connect the gateway, read cached history or reconstruct missed events. The queue budgets apply to events received before the wait can take them. Completion, timeout, cancellation and shutdown release the wait's subscription

interface EventWaitOptions<
    K extends EventName,
    M extends MessageCore = Message
>
    extends EventBufferOptions, OperationOptionsinterface EventWaitOptions<
  K extends EventName,
  M extends MessageCore = Message
>
  extends EventBufferOptions, OperationOptions

The signal option cancels this event wait, not the client

filter optional#

Return true to complete with this event, false to keep waiting

Omit to accept the first event. Runs synchronously and can run while the gateway receives events. Keep it short, since deadlines cannot preempt blocking JavaScript. A throw or non-boolean return fails with EventWaitError reason filter. A thrown value is the error's cause. Do not return a Promise. Mistaken asynchronous work is neither awaited nor cancelled, and its rejection is discarded

(event: EventMap<M>[K]) => boolean
timeoutMs optional#

Total milliseconds to wait from registration, an integer from 1 through 2,147,483,647, default 30,000

Expiry fails with EventWaitError reason timeout, rather than returning an empty event

number

Inherited from EventBufferOptions: maxPendingBytes, maxPendingMessages

Inherited from OperationOptions: signal

GuildAuditLogEntryCreate#

Audit entry newly written in a community, using the same field names as audit-log requests

The entry and its nested data are frozen. Access requires Fluxer's VIEW_AUDIT_LOG permission. The reason, options and changes fields can contain application or provider data, so do not treat them as safe diagnostics. Numeric and boolean option values are converted to the same types used by audit-log reads

interface GuildAuditLogEntryCreate extends AuditLogEntryinterface GuildAuditLogEntryCreate
  extends AuditLogEntry
export function administrativeEventsExample(client) {
    return client.subscribe("guildAuditLogEntryCreate", { maxPendingMessages: 10 })
}
import type { Client } from "@neontechspace/fluxerly"
export function administrativeEventsExample(client: Client) {
    return client.subscribe("guildAuditLogEntryCreate", { maxPendingMessages: 10 })
}
guildId#

Community that recorded the entry

string
targetId#

Affected resource ID or invite code, or null when Fluxer recorded no target

string | null
userId#

Acting account ID supplied for this entry

string

Inherited from AuditLogEntry: actionType, changes, id, options, reason

GuildChannelUpdateBulk#

Visible channel updates delivered together, not a complete community channel list

interface GuildChannelUpdateBulk
channels#

Frozen channel snapshots delivered in this dispatch

readonly GuildChannel[]
guildId#

Decimal community ID

string

GuildCreate#

Frozen community data received with an availability event, plus information about whether this is a new join

The event keeps the Guild fields. REST results and cached Guild values do not gain join state. Subscribe before connecting to receive startup availability events. The connect call does not wait for them

interface GuildCreate extends Guild

Join classification requires a Fluxer bot gateway implementing the unavailable-marker distinction. Older or custom instances that omit the marker for startup snapshots cannot be classified reliably. The SDK does not detect that support or infer joins from readiness, elapsed time or cache contents. A supplied marker other than false is invalid for an available snapshot and fails the gateway as a protocol error

export function waitForGuildJoin(client) {
    return client.waitFor("guildCreate", { filter: (guild) => guild.isNewJoin, timeoutMs: 30_000 })
}
import type { Client } from "@neontechspace/fluxerly"

export function waitForGuildJoin(client: Client) {
    return client.waitFor("guildCreate", { filter: (guild) => guild.isNewJoin, timeoutMs: 30_000 })
}
TypeScript
import type { Client } from "@neontechspace/fluxerly/effect"

export function waitForGuildJoinEffect(client: Client) {
    return client.waitFor("guildCreate", { filter: (guild) => guild.isNewJoin, timeoutMs: 30_000 })
}
isNewJoin#

True when the outer GUILD_CREATE omits unavailable, false when it supplies literal false

On a supporting bot gateway, true identifies the first create for a community joined during this session and absent from READY. It remains true if temporary unavailability preceded that first create. Startup and recovery snapshots carry false, including a fresh Identify's membership baseline. A retained join dispatch may replay during Resume, so this is not an exactly-once notification

boolean
joinedAt optional#

ISO 8601 time the bot joined the community, null when Fluxer reports none, or absent when the event carried no value

It is delivered with this event only and is not part of Guild or the guild cache

string | null
memberCount optional#

Members of the community when Fluxer delivered this event, or absent when the event carried none

Fluxer documents it on every create. This is a snapshot that GUILD_UPDATE does not refresh and the guild cache does not store, so it can be outdated immediately. Request current totals with guilds.fetchCounts, which returns a GuildCount

number
onlineCount optional#

Online members of the community when Fluxer delivered this event, or absent when the event carried none

Fluxer counts members with a live gateway session whose status is not offline or invisible, and every recipient receives the same guild-wide figure. It has the snapshot limits of memberCount. GuildCount.onlineCount differs, because it counts only the online members visible to the requesting account

number

Inherited from Guild: afkChannelId, afkTimeoutSeconds, banner, contentWarningLevel, contentWarningText, defaultMessageNotifications, embedSplash, explicitContentFilter, features, icon, id, messageHistoryCutoff, mfaLevel, name, nsfw, ownerId, splash, splashCardAlignment, systemChannelFlags, systemChannelId, verificationLevel

GuildDeletion#

Gateway notification that a community is no longer visible to this client

interface GuildDeletion

This can describe temporary unavailability rather than community deletion or removal of the bot. The unavailable field is true when Fluxer temporarily withholds the community and false when its field is absent. The unavailableHidden field is true when Fluxer marks that unavailable community hidden and false when its field is absent

id#

Decimal guild ID

string
unavailable#

Whether Fluxer reports a temporary unavailable placeholder

boolean
unavailableHidden#

Whether Fluxer reports that temporary placeholder as hidden

boolean

GuildEmojisUpdate#

Custom emoji collection supplied in one community update, frozen in received order

No creator accounts or image contents are included. This is not an initial enumeration or an automatic cache refill

interface GuildEmojisUpdate
export function expressionEventsExample(client) {
    return client.subscribe("guildEmojisUpdate", { maxPendingMessages: 10 })
}
import type { Client } from "@neontechspace/fluxerly"
export function expressionEventsExample(client: Client) {
    return client.subscribe("guildEmojisUpdate", { maxPendingMessages: 10 })
}
guildId#

Community that owns this emoji collection, as a decimal ID

string
items#

Emoji snapshots in Fluxer's received order

readonly GuildEmoji[]

GuildHealthUpdate#

Frozen community-server health notice, without a cache write or automatic reconnect

A degraded community server is lagging, not disconnected or unavailable

interface GuildHealthUpdate
degraded#

True while the community's server is lagging, false when it recovers

This does not report disconnection or unavailability

boolean
guildId#

Community whose server health changed, as a decimal ID

string

GuildLifecycleEvents#

Payload types for community availability, configuration and visibility events

A create event can mean an existing community became available, rather than a new community was created

interface GuildLifecycleEvents
export function guildEventsExample(client) {
    return client.subscribe("guildDelete", { maxPendingMessages: 10 })
}
import type { Client } from "@neontechspace/fluxerly"

export function guildEventsExample(client: Client) {
    return client.subscribe("guildDelete", { maxPendingMessages: 10 })
}
guildCreate#

Community data became available, including startup hydration, recovery and joins

Use isNewJoin for the provider's join distinction, subject to GuildCreate's gateway-support and replay limits. Before delivery, fills the enabled community, role, emoji, sticker and channel caches from the snapshot, replacing this community's earlier roles, emojis, stickers, channels and threads. The channel cache takes the active threads the bot can view, and a malformed thread is left out with a gateway.threadSkipped Warn record. The enabled member cache stores the members the snapshot lists, which are the bot's own and those in voice channels, without treating them as the community's member list. The snapshots sent while a session starts list member accounts by ID only, so from those only the bot's own member is stored, completed from READY's account

GuildCreate
guildDelete#

Community visibility ended or became temporarily unavailable, without establishing deletion or the bot's membership outcome

Before delivery, enabled community-resource and channel caches invalidate this community's observations. Cached messages in this community or with unknown community scope also invalidate, since the SDK has no channel-to-community lookup index. EventContext.previous holds the enabled community cache's snapshot from before the event

GuildDeletion
guildUpdate#

Current community configuration, not a patch to merge

EventContext.previous holds the enabled community cache's snapshot from before the update

Guild

GuildStickersUpdate#

Custom sticker collection supplied in one community update, frozen in received order

No creator accounts or image contents are included. This is not an initial enumeration or an automatic cache refill

interface GuildStickersUpdate
guildId#

Community that owns this sticker collection, as a decimal ID

string
items#

Sticker snapshots in Fluxer's received order

readonly GuildSticker[]

HandlerOptions#

Queue limits, parallelism, ordering and overflow behavior for one on callback registration

Callbacks are not retried. A callback or middleware failure, including a synchronous throw, is reported and releases the invocation's slot and partition key without stopping later event delivery. Closure waits for active callback cleanup. The type parameter T is the event payload that a partition function receives

interface HandlerOptions<T = unknown> extends EventBufferOptionsinterface HandlerOptions<T
  = unknown>
  extends EventBufferOptions
concurrency optional#

Maximum active callbacks, a positive safe integer

The default is 8 for messageCreate or when partition is set, and 1 for other events. A messageCreate callback that must not overlap another needs concurrency 1 or a partition such as channel. Without a partition, starts follow receive order and values above 1 allow callbacks to finish out of order. Within one partition, callbacks run one at a time in receive order, while a later event for another key may start first

number
overflow optional#

What happens when an event arrives while the waiting queue is full

The default, dropOldest, discards the oldest waiting events to make room, and dropNewest discards the arriving event. Both drop policies keep the subscription running, log a Warn record and count the drop in diagnostics().counters.eventsDropped and eventsDroppedByEvent. The policy stop ends the subscription and reports an overflow failure, so waitForClose returns EventOverflowError

"stop" | "dropOldest" | "dropNewest"

With a partition, dropOldest discards from the longest backlog instead of the oldest event overall. The backlog of the arriving event's key counts the arriving event. When another key has a longer backlog, that key loses its oldest waiting event, and ties go to the key whose oldest waiting event is oldest. Otherwise the arriving event's own key loses its oldest waiting event, or the arriving event itself when that key has none waiting. This repeats until the arriving event fits. So an event of another key is discarded only when that key's backlog is longer than the arriving key's, a longer or equal backlog never takes room from a shorter one, and a busy key's backlog shrinks itself first. Events whose partition function failed form one backlog of their own. Under maxPendingBytes the choice still follows the number of waiting events, not their sizes. Events held by partitionReady count as waiting, so a bot that holds many starting keys needs a larger maxPendingMessages than the default 256

partition optional#

Keep related events in order while unrelated events run side by side, up to concurrency

Events with the same key run one at a time in receive order, each starting after the previous one with that key finished. An event whose key is busy waits in the queue while later events with other keys start. The value guild keys each event by its community, which the API calls a guild, and a direct message by its channel. An invite creation is keyed by its destination community, or by its channel for a group invite. The value channel keys each event by its channel, or by its community when it has no channel. A function receives the event and returns its key as a string. Events without a key, including those for which the function returns undefined, share one key. A function that throws or returns another value is reported as a failure of that event's handler, which then does not run. The function runs once per event, when the event is received. With overflow dropOldest, a full queue discards from the longest backlog of one key, as described at overflow. The client.on option partitionReady holds a key's events until that key's own setup is done

"channel" | "guild" | ((event: T) => string | undefined)| "channel"
| "guild"
| ((event: T) => string | undefined)
export function orderedPerChannel(client, handle) {
    // Up to 8 channels at a time, and the messages of one channel in order
    return client.on("messageCreate", (message) => handle(message), { partition: "channel" })
}
import type { Client, Message } from "@neontechspace/fluxerly"
export function orderedPerChannel(client: Client, handle: (message: Message) => Promise<void>) {
    // Up to 8 channels at a time, and the messages of one channel in order
    return client.on("messageCreate", (message) => handle(message), { partition: "channel" })
}

Inherited from EventBufferOptions: maxPendingBytes, maxPendingMessages

InviteDeleteEvent#

Notice that an invite was deleted, without its former settings

Treat the code as access-granting data and keep it out of diagnostics and public logs

interface InviteDeleteEvent
channelId optional#

Invite destination channel ID, when supplied

string
code#

Deleted invite's code, the stable identity supplied for this event

string
guildId optional#

Invite destination community ID, when supplied

string

MessageBulkDeletion#

Message IDs deleted together in one channel

The frozen batch produces one messageDeleteBulk event, without additional messageDelete events

interface MessageBulkDeletion
channelId#

Channel ID shared by the deleted messages

string
guildId optional#

Community ID when Fluxer supplies it

Omission means no community context was supplied, not a confirmed private channel. No channel lookup or cache inference supplies this field

string
ids#

Deleted decimal message IDs in received order, not necessarily chronological or guaranteed to arrive exactly once

readonly string[]

MessageDeletion#

Notice identifying one deleted message, not its full contents or a recoverable copy

The SDK does not fetch or reconstruct missing details from its cache

interface MessageDeletion extends MessageReferenceinterface MessageDeletion
  extends MessageReference
authorId optional#

Deleted message's author ID, only when supplied by Fluxer

string
content optional#

Deleted text when supplied

Absence means unavailable, null is preserved, and "" means known empty text

string | null
guildId optional#

Community ID when Fluxer supplies it

Omission means no community context was supplied, not a confirmed private channel. No channel lookup or cache inference supplies this field

string
member optional#

The author's community membership as Fluxer attached it to the deletion, read from the community's current state at dispatch time

It is a frozen DeletedMessageMember, which has no username or bot flag because Fluxer removes the member's user. Omitted when Fluxer sent none, such as for a message without an author or whose author is no longer a member, and when the member Fluxer sent does not decode or the deletion names no community or author. A member that does not decode never costs the event itself. It is delivered on the event only and the member cache does not store it, so a deletion never changes a cached member

DeletedMessageMember

Inherited from MessageReference: channelId, id

MessageReaction#

One reaction addition or removal delivered by Fluxer

The userId field identifies the user whose reaction changed. Another account can perform the removal

interface MessageReaction extends ReactionTargetinterface MessageReaction
  extends ReactionTarget
emoji#

Emoji whose reaction changed

ReactionEmoji
member optional#

Community membership of the user whose reaction changed, as Fluxer attached it to the event from the community's current state at dispatch time

It is a frozen observation, omitted in direct messages, for users who left the community, and when the member Fluxer sent does not decode or comes without the user's name, which never costs the event itself. With the members cache enabled, the SDK also stores this member there, completing a nameless one from the member already cached for the user, and dropping the cached member when the one sent does not decode

GuildMember
userId#

Account ID of the user whose reaction was added or removed

string

Inherited from ReactionTarget: channelId, guildId, id

MessageReactionBatch#

Reaction additions grouped by Fluxer into one messageReactionAddMany event

Entries retain received order. This does not also emit messageReactionAdd for each entry. Subscribe to both addition events when both forms are needed. Reaction collectors already accept both. A batch counts as one queued event, and its full received JSON counts toward the pending-byte budget. The SDK does not ask Fluxer to batch events or fill in changes Fluxer did not send

interface MessageReactionBatch extends ReactionTargetinterface MessageReactionBatch
  extends ReactionTarget
reactions#

Frozen additions on the target message, in received order

readonly {
    readonly emoji: ReactionEmoji
    readonly userId: string
}[]readonly {
  readonly emoji: ReactionEmoji
  readonly userId: string
}[]

Inherited from ReactionTarget: channelId, guildId, id

MiddlewareRegistration#

Remove event middleware registered with client.use

Use using to remove it when the enclosing block ends

interface MiddlewareRegistration

[dispose]#

Remove the middleware, as using does at the end of a block

[dispose](): void

close#

Stop applying the middleware to invocations that start later

Invocations already running keep their chain. Repeated calls do nothing

close(): void

ObservedCustomStatus#

A custom status observed in a presence event, kept as Fluxer sent it

The SDK does not compare expiresAt with the clock, so a status can be past its expiry when read. A field Fluxer left out or sent as null is null

interface ObservedCustomStatus
emoji#

The emoji shown with the text, or null when the status has none

ObservedCustomStatusEmoji | null
expiresAt#

ISO 8601 time at which the status expires, or null when it does not expire

string | null
text#

Status text, or null when the status has none, such as one that shows only an emoji

string | null

ObservedCustomStatusEmoji#

The emoji of an observed custom status

A Unicode emoji has a name and no id, and a custom emoji has both

interface ObservedCustomStatusEmoji
animated#

Whether the custom emoji is animated, always false for a Unicode emoji or when Fluxer left the flag out

boolean
id#

ID of the custom emoji, or null for a Unicode emoji

string | null
name#

The Unicode emoji, or the custom emoji's name

Null when Fluxer sent an id without a name

string | null

PresenceUpdate#

Account presence reported by Fluxer at one point in time, not a cached or continuously updated status

Changes can be missed during connection gaps. The SDK does not fetch missing presence or account details. Community-scoped updates include guildId, while valid account-scoped observations can omit it. Listening for this event does not request community-member presence subscriptions or guarantee delivery. The hosted provider delivers bot presence through community subscriptions, not friends or group DMs. Common statuses are online, idle, dnd and offline. Other strings are retained if Fluxer adds statuses

interface PresenceUpdate
export function presenceEventsExample(client) {
    return client.subscribe("presenceUpdate", { maxPendingMessages: 10 })
}
import type { Client } from "@neontechspace/fluxerly"
export function presenceEventsExample(client: Client) {
    return client.subscribe("presenceUpdate", { maxPendingMessages: 10 })
}
afk#

Whether Fluxer reported the account as away from keyboard

boolean
customStatus#

The account's custom status, or null when it has none

Fluxer reports null for an account whose status is offline or invisible, so an invisible account never reveals one, and after it clears or expires a status. Fluxer stores custom statuses without validating them, so a field of an unexpected type reads as null and the presence is still delivered

ObservedCustomStatus | null
guildId optional#

Community where the account's presence was observed, when supplied

string
mobile#

Whether Fluxer reported a mobile client

boolean
status#

Status Fluxer reported at event time, which can already be stale when read

A status this SDK version does not recognize is reported as unknown, so a switch over the values stays exhaustive

ObservedPresenceStatus
userId#

Account ID whose presence changed, without an account lookup

string

PresenceUpdateBulk#

Visible online presences grouped into one event after a community becomes available again

Fluxer supplies community context for every entry, omits the recipient's own presence and splits batches at 500 entries. A batch can include visible members outside this client's selected member IDs. The frozen batch does not refill a cache, acknowledge subscriptions or emit individual presenceUpdate events

interface PresenceUpdateBulk
guildId#

Community ID shared by every presence in the batch

string
presences#

Frozen presence observations, each carrying this batch's guildId

readonly PresenceUpdate[]

PreviousSnapshots#

The cached snapshot that EventContext.previous holds for each event that changes or removes one cached entity, keyed by event name

Events not listed here have no previous snapshot. Each snapshot is the frozen value the client's own cache held just before it applied the event, the same value a local lookup such as client.messages.get returned until then. It is never fetched and is not Fluxer's history of the entity. It can be older than the change, because Fluxer may have sent changes this client did not receive or apply. The previous field is undefined when the cache category is not enabled in the cache client option, or when the cache held no snapshot: The entity was never observed, the snapshot expired or was removed for capacity, or an earlier event, write, clear or connection gap removed it

interface PreviousSnapshots<M extends MessageCore = Message>interface PreviousSnapshots<
  M extends MessageCore = Message
>
export function editLog(client, log) {
    // Create the client with the message cache enabled, as in createClient({ token, cache: { messages: true } })
    return client.on("messageUpdate", (message, _signal, { previous }) => {
        if (previous !== undefined && previous.content !== message.content)
            log(`Message ${message.id} changed from ${previous.content} to ${message.content}`)
    })
}
import type { Client } from "@neontechspace/fluxerly"
export function editLog(client: Client, log: (line: string) => void) {
    // Create the client with the message cache enabled, as in createClient({ token, cache: { messages: true } })
    return client.on("messageUpdate", (message, _signal, { previous }) => {
        if (previous !== undefined && previous.content !== message.content)
            log(`Message ${message.id} changed from ${previous.content} to ${message.content}`)
    })
}
guildChannelDelete#

The deleted or hidden channel from the channel cache

GuildChannel
guildChannelUpdate#

The channel from the channel cache before the update

A category update or a guildChannelUpdateBulk event clears the community's cached channels, so a later update of one of them has none

GuildChannel
guildDelete#

The community from the community cache before it was removed or became unavailable

Guild
guildMemberRemove#

The member from the member cache before the removal

A guildBanAdd event for the account removes it from the cache first, so a removal that follows one has none

GuildMember
guildMemberUpdate#

The member from the member cache before the update

GuildMember
guildRoleDelete#

The deleted role from the role cache

GuildRole
guildRoleUpdate#

The role from the role cache before the update

A guildRoleUpdateBulk event has no previous snapshots

GuildRole
guildUpdate#

The community from the community cache, the guilds category, before the update

Guild
messageDelete#

The deleted message from the message cache, as for messageUpdate

M
messageDeleteBulk#

The deleted messages from the message cache, as for messageUpdate, in a frozen list in the order of the event's ids and once per message

Fluxer sends only IDs for a bulk deletion, so this list is the only source of their content and authors. It leaves out each message the cache did not hold, so an ID with no message here is unknown, not absent in Fluxer. When the cache held none of them, previous is undefined instead of an empty list

readonly M[]
messageUpdate#

The edited message from the message cache, with this client's selected message fields

Like every cached message it has no member or other field that only messageCreate carries. A lost gateway connection clears cached messages even when the session resumes

M
threadDelete#

The deleted thread from the channel cache

GuildThreadChannel
threadUpdate#

The thread from the channel cache before the update, with the bot's membership when the cached snapshot had it

GuildThreadChannel

RawDispatch#

One gateway dispatch as Fluxer sent it, before the SDK decodes or validates its body

Delivered for every dispatch the session accepts, including READY, RESUMED and types this SDK version does not handle. The body is Fluxer's unvalidated wire data and is not part of the SDK's compatibility contract, so its shape can change without an SDK release. Raw subscribers do not change cache updates or decoded event delivery

interface RawDispatch

Each delivery is logged at Trace with code events.raw. A raw dispatch is offered before its decoded event, but its handler runs after the SDK has updated caches for it, so it cannot read the values the dispatch replaced. The body object is shared by every raw subscriber, so treat it as read-only. A raw subscriber turns off automatic event suppression, while explicitly ignored types never arrive

d#

Unvalidated dispatch body

unknown
s#

Session sequence number of the dispatch

number
shardId#

Local shard that received the dispatch

number
t#

Upper-case dispatch type, such as MESSAGE_CREATE

string

ReactionCollector#

Wait for the reaction-addition collection created by messages.collectReactions

Use close to end intake early and result to obtain the observations. Collected additions are observations, not current votes

interface ReactionCollector

[asyncDispose]#

Close this collector and wait for its cleanup, as await using does at the end of a block

The collection outcome is not rethrown here. Read it from result when it matters

[asyncDispose](): Promise<void>
Returns
Promise<void>

close#

Stop accepting additions now and keep accepted observations for a successful partial result

Repeated calls preserve the first recorded outcome. Use result to await callback cleanup and read the observations

close(): void

Returns immediately

result#

Wait for the final frozen reaction result after queue, timer, filter, listener and callback cleanup

Idle, timeout or stop can succeed with empty or partial observations. Collection cancellation, filter or callback failure, overflow, gateway loss and client shutdown fail without partial observations. Multiple or later waiters receive the same outcome. Cancelling this wait affects only the waiter, not collection. Keeping the handle or successful result retains its snapshots in memory

result(options?: OperationOptions): ResultAsync<
    ReactionCollectorResult,
    ConfigurationError | CollectorFailure | CancelledError
>result(
  options?: OperationOptions
): ResultAsync<
  ReactionCollectorResult,
  | ConfigurationError
  | CollectorFailure
  | CancelledError
>

Parameters

options optional
OperationOptions

Unexpected failures reject with SdkDefect

ReactionCollectorOptions#

Choose which new reaction additions to collect on one message and when to stop

This listens to single additions and server batches, not existing reactions, removals or current vote totals. Repeated user and emoji pairs count as separate additions. No unique-user count is maintained. Connect before registering. Registration does not fetch the message, check existing reactors or connect automatically. A shard is one gateway connection assigned to a group of communities, and guildId can restrict collection to its owning shard

interface ReactionCollectorOptions extends EventBufferOptionsinterface ReactionCollectorOptions
  extends EventBufferOptions

The signal option cancels the collection, while the signal passed to onReaction controls its active callback

emoji optional#

Collect only this emoji, or omit to accept any emoji

Use any ReactionEmojiInput, including Unicode, custom markup and parsed or received emoji. The SDK normalizes and copies it at registration. Unicode text must match exactly, including skin tone and variation selectors. Custom emoji match by ID even after renaming. A custom input still needs a valid name. Invalid input fails registration with ConfigurationError field emoji, without a request. Matching runs before filter and onReaction, but after the event enters the queue, so other emoji can still fill the pending queue

ReactionEmojiInput
filter optional#

Return true to accept an addition, or false to skip it

Runs after target and optional emoji matching. With both emoji and filter supplied, both must match. Omission accepts every addition passing the emoji selector. Runs synchronously in receive order, then batch order. A throw or non-boolean return fails only this collector with reason filter, and is reported to the client-level onError with kind filter and the message IDs, or logged at Error. Do not return a Promise. Mistaken asynchronous work is not awaited or cancelled, and its rejection is discarded. Slow code blocks JavaScript. Deadlines are checked after the filter returns

(reaction: MessageReaction) => boolean
guildId optional#

Community that owns the target channel, as a positive decimal ID within the unsigned 64-bit range

The caller must supply the correct community, because no channel lookup verifies it. Its assigned gateway shard must be connected. Recovery of that shard ends collection, while unrelated shard recovery does not. Events with a different supplied guildId are discarded. Missing community context does not prove private scope. Omit for private or unknown scope, requiring a connected whole gateway and ending collection on any shard recovery

string
idleMs optional#

Stop successfully after this many milliseconds without an accepted addition

Omit to disable. Integer 1 through 2,147,483,647. Starts at registration and resets before each accepted addition's callback. Excluded emoji, rejected additions and unprocessed queue or batch entries do not reset it. Callback time counts as idle time. Repeated pairs reset the interval when accepted. The earlier idle or total deadline wins, with timeout winning ties

number
maxBytes optional#

Maximum UTF-8 JSON bytes kept for accepted MessageReaction values

Positive safe integer, default 4,194,304, not a total memory limit

number
maxReactions optional#

Stop successfully after this many accepted additions and their callbacks

Repeated pairs count, positive safe integer, default 1

number
onReaction optional#

Process accepted additions sequentially before accepting the next addition

Return asynchronous work so collection can await it. If it returns an Err result, collection stops with that error, like a throw. To recover instead, check the Result inside the callback. Throws and rejected Promises fail with CollectorError reason handler, whose cause is the thrown value, without retrying the callback. The failure is also reported to the client-level onError with kind collector and the message IDs, or logged at Error. Stop, deadlines, cancellation, recovery and shutdown abort the callback signal and wait for its returned Promise. Ignoring the signal can delay completion indefinitely. Do not await collection completion or client shutdown here. Callback requests already dispatched are not rolled back

(reaction: MessageReaction, signal: AbortSignal) => unknown(
  reaction: MessageReaction,
  signal: AbortSignal
) => unknown
signal optional#

Cancel the whole collection

Already-aborted signals reject registration, later abort returns CancelledError without partial additions

OperationSignal
timeoutMs optional#

Stop successfully after this many milliseconds from registration

Activity does not extend it, integer 1 through 2,147,483,647, default 30,000

number

Inherited from EventBufferOptions: maxPendingBytes, maxPendingMessages

ReactionCollectorResult#

Successful observations of reaction additions, not a final vote count

Later removals, clears and message deletion do not change this frozen result

interface ReactionCollectorResult
reactions#

Additions in receive order, then batch order

Repeated user and emoji pairs appear separately

readonly MessageReaction[]
reason#

Successful stop condition: Accepted count, total deadline, idle deadline, or an explicit stop

The reason limit waits for the last callback. Other reasons may return no additions or include an addition whose callback was cancelled

"stopped" | "idle" | "timeout" | "limit"| "stopped" | "idle" | "timeout"
| "limit"

Subscription#

Control one event subscription returned by on or subscribe

Closing this subscription leaves the client and its other subscriptions running. Use await using to close the subscription and wait for its cleanup when the enclosing block ends

interface Subscription
id#

Identifier of this subscription, such as messageCreate#3, used in failure reports and log records

string

[asyncDispose]#

Close this subscription and wait for its cleanup, as await using does at the end of a block

An overflow outcome is not rethrown here. Read it from waitForClose when it matters

[asyncDispose](): Promise<void>
Returns
Promise<void>

close#

Stop new deliveries, drop queued events and stop running handlers, without waiting for the handler that called close

When queued events are dropped, one events.discarded Debug record reports how many, and diagnostics().counters.eventsDropped.closed counts them

close(): void

Returns immediately and signals running handlers to stop. JavaScript promises that ignore the signal cannot be forcibly stopped

waitForClose#

Wait until this subscription has closed and the SDK has released its queue and listeners

Normal closure succeeds with no value, and overflow fails with EventOverflowError, even for a later waiter. Cancelling this wait affects only the waiter, not the subscription or other waiters. Later waits see the same subscription outcome. Do not await this subscription's own closure from inside its handler

waitForClose(options?: OperationOptions): ResultAsync<
    void,
    ConfigurationError | EventOverflowError | CancelledError
>waitForClose(
  options?: OperationOptions
): ResultAsync<
  void,
  | ConfigurationError
  | EventOverflowError
  | CancelledError
>

Parameters

options optional
OperationOptions

This does not wait for arbitrary application promises. Unexpected cleanup failures reject with SdkDefect

ThreadDeletion#

Identity of a deleted thread, without its former settings or messages, which EventContext.previous can hold from the channel cache

Deleting a parent channel deletes its threads without this event

interface ThreadDeletion
guildId#

Community that held the thread

string
id#

Decimal ID of the deleted thread

string
parentId#

Channel that held the thread

string
type#

Type of the deleted thread

10 | 11 | 12

ThreadListSync#

The bot's complete set of active threads in a community, or in some of its channels, as Fluxer replaced it

Fluxer sends it when the bot gains access to channels with active threads, and when a community reloads its thread state. It is never replayed on Resume

interface ThreadListSync
guildId#

Community whose threads were replaced

string
parentIds optional#

Channels whose threads were replaced

Absent when the list replaces every thread in the community

readonly string[]
threads#

Every active thread the bot can view in the replaced scope, each with the bot's membership when it is a member

readonly GuildThreadChannel[]

ThreadMembersUpdate#

Accounts that joined or left one thread, including the bot itself

interface ThreadMembersUpdate
added#

Members who joined, each with their community membership when Fluxer has one for the account

Empty when none joined

readonly ThreadMember[]
guildId#

Community that holds the thread

string
memberCount#

Approximate number of thread members after the change, capped at 50

number
removedUserIds#

Decimal IDs of the accounts that left

Empty when none left

readonly string[]
threadId#

Decimal ID of the thread

string

TypingStart#

Notice that an account began typing, not a lasting indication that it is still typing

The SDK does not cache this notice or fetch the user or channel. With the members cache enabled, the member that Fluxer attached is stored there

interface TypingStart
channelId#

Channel ID where typing began

string
guildId optional#

Owning community ID, when supplied

Absence alone does not prove that the channel is private

string
member optional#

Community membership of the account that began typing, as Fluxer attached it from the community's current state at dispatch time

It is a frozen observation, omitted in direct messages, for accounts that left the community, and when the member Fluxer sent does not decode or comes without the account's name, which never costs the event itself. The members cache, when enabled, handles it as MessageReaction.member describes

GuildMember
timestamp#

Fluxer's Unix timestamp in whole seconds, not milliseconds

number
userId#

Account ID that began typing

string

VoiceState#

One account's voice connection as observed in a community, without audio or video access

A null channelId reports a disconnect. Moving channels can produce a disconnect followed by a join with a new connectionId. Fluxer filters delivery by channel visibility, and connection gaps can miss changes. This frozen observation is not retained as a voice-state cache and does not trigger lookups

interface VoiceState
channelId#

Observed voice channel ID, or null for a disconnect

string | null
connectionId#

Fluxer's connection ID, usable to target one connection in a move or disconnect request

string
guildId#

Community that owns this voice connection

string
isDeafened#

Whether the community has deafened this connection

boolean
isE2eeCapable#

Whether the participant's client supports end-to-end encrypted voice

An omitted flag reads as false

boolean
isMobile#

Whether Fluxer identifies this connection as mobile

boolean
isMuted#

Whether the community has muted this connection

boolean
isPeerToPeer#

Whether this connection exchanges media peer-to-peer and not through LiveKit

A channel or call is peer-to-peer when every voice state in it has this flag. Fluxer sets it to false on all of them when it converts the channel or call to LiveKit, which cannot be undone until the channel or call has emptied. An omitted flag reads as false

boolean
isSelfDeafened#

Whether the participant has deafened themselves

boolean
isSelfMuted#

Whether the participant has muted themselves

boolean
isSelfStreaming#

Whether the connection advertises a screen-share track

The participant's client reports it, and in a community Fluxer sets it to false while the participant lacks the Stream permission. An omitted flag reads as false

boolean
isSelfVideoOn#

Whether the participant is publishing camera video

An omitted flag reads as false

boolean
isSuppressed#

Whether Fluxer reports this connection as prevented from speaking

boolean
member optional#

The participant's community member data as Fluxer attached it to this voice state, omitted when Fluxer sends none

Fluxer refreshes it when the voice state changes, so it can lag behind later nickname or role edits. It is a frozen observation and neither reads nor writes any member cache, unlike the member on message, reaction and typing events, which Fluxer reads from current state at dispatch. A member that does not decode rejects the whole voice state, while those events only omit their member

GuildMember
sessionId optional#

Gateway session ID, when supplied by Fluxer

string
userId#

Connected account's user ID

string
version optional#

Fluxer's monotonic version of this participant's voice state, omitted when Fluxer sends none

It versions one participant's state only, so values of different participants are not comparable

number
viewerStreamKeys#

Keys of the screen shares this connection is watching, empty when it watches none or Fluxer omits them

A key reads {guildId}:{channelId}:{connectionId} for a community voice channel and dm:{channelId}:{connectionId} for a private call, where the last part is the publisher's connectionId

readonly string[]

VoiceStateSnapshot#

Visible voice connections supplied when a community becomes available

Register before connecting to receive startup snapshots. An empty voiceStates array means Fluxer explicitly supplied no initial connections. No event is emitted when the collection is absent. The frozen collection is not a complete member roster or a voice-state cache, and can become stale immediately

interface VoiceStateSnapshot
guildId#

Community whose availability data supplied these connections

string
voiceStates#

Frozen voice connections in received order, including an explicitly supplied empty array

readonly VoiceState[]

WebhooksUpdate#

Notice that the webhooks in a channel changed

No webhook details or token are included. Fetch the current set explicitly if needed. This notification does not write or invalidate an SDK cache

interface WebhooksUpdate
channelId#

Channel whose webhook collection changed

string
guildId#

Community that owns the channel, as a decimal ID

string

Type Aliases#

EventMiddleware#

Event middleware for the default API, run around each client.on handler invocation that starts after registration

It receives the invocation, a next function that runs the rest of the chain and the handler, and the invocation's cancellation signal. The promise returned by next resolves when the rest of the chain has finished, whether or not it failed, and never rejects. Failures after next are reported by the SDK where they occur, so middleware can time or trace a handler but cannot hide its failure. A middleware fails when it throws, rejects, or returns or resolves an Err result, and that failure is reported like a handler failure

type EventMiddleware<M extends MessageCore = Message> =
    (
        invocation: EventInvocation<M>,
        next: () => Promise<void>,
        signal: AbortSignal
    ) => unknowntype EventMiddleware<
  M extends MessageCore = Message
> = (
  invocation: EventInvocation<M>,
  next: () => Promise<void>,
  signal: AbortSignal
) => unknown

EventName#

Event-name strings accepted by on, events and waitFor in both entry points

type EventName = keyof EventMap

ObservedPresenceStatus#

An account status observed in a presence event

Fluxer reports invisible accounts to others as offline, and a status this SDK version does not recognize is unknown

type ObservedPresenceStatus =
    "online" | "idle" | "dnd" | "offline" | "invisible" | "unknown"type ObservedPresenceStatus =
    | "online" | "idle" | "dnd"
    | "offline" | "invisible"
    | "unknown"

ThreadCreateEvent#

A thread that was created or that the bot was added to, with whether it was just created

Fluxer also sends this event to the bot when it joins or is added to an existing thread, then with isNewlyCreated false. The bot's own membership is in membership when the bot is a member

type ThreadCreateEvent =
    GuildThreadChannel & { readonly isNewlyCreated: boolean }type ThreadCreateEvent =
    & GuildThreadChannel
    & {
        readonly isNewlyCreated:
          boolean
      }
export function greetNewThreads(client) {
    return client.on("threadCreate", (thread) => thread.isNewlyCreated ? client.messages.send(thread.id, `Welcome to ${thread.name}`) : undefined)
}
import type { Client } from "@neontechspace/fluxerly"

export function greetNewThreads(client: Client) {
    return client.on("threadCreate", (thread) =>
        thread.isNewlyCreated ? client.messages.send(thread.id, `Welcome to ${thread.name}`) : undefined,
    )
}