Channels With Something to Say
Full voice channel status support, role member counts, a gateway that stops tripping over its own reconnects, and a type surface synced back to upstream.
The Last 4.x Before the Big One
Before v5 reinvents the furniture, v4.4.0 ties off the 4.x line with the features people actually kept asking for. Voice channel status lands with full gateway support, guild roles can finally tell you how many members they have, and the gateway stops pretending a half-dead socket is fine.
One more solid 4.x. Then we go to space.
Voice Channel Status
You know that little line of text under a voice channel — "🎮 ranked grind" or "movie night" — that you could read but never touch from code? Now you can.
// Set it
await channel.setVoiceStatus('🎮 Playing ranked');
// Clear it
await channel.setVoiceStatus(null);Setting a status needs the new SET_VOICE_CHANNEL_STATUS permission (1 << 48). It's in PermissionFlagsBits like everything else.
This isn't a thin REST wrapper bolted on top. v4.4.0 ships the whole pipeline Discord documented:
VOICE_CHANNEL_STATUS_UPDATEandVOICE_CHANNEL_START_TIME_UPDATEgateway events, with cache handling- the
CHANNEL_INFOreceive event - the
Request Channel Infosend command (opcode 43) viarequestChannelInfo - audit log entries for status changes (192/193)
- the
statusfield on voice channel payloads
Listen for changes like any other event:
import { createEvent } from 'seyfert';
export default createEvent({
data: { name: 'voiceChannelStatusUpdate' },
run([status, channel]) {
console.log(`Channel ${status.id} → ${status.status ?? '(cleared)'}`);
},
});Need the current status and start time for a guild's channels without waiting for an update to fire? Ask the gateway directly:
client.gateway.requestChannelInfo(guildId, ['status', 'voice_start_time']);The reply comes back as a CHANNEL_INFO event. No polling, no scraping.
Role Member Counts
How many people actually have the @Verified role? Previously you counted by hand through the member list. Now it's one call.
const counts = await guild.roles.memberCounts();
// { '1234567890': 42, '0987654321': 7, ... }
console.log(`Verified members: ${counts[verifiedRoleId]}`);Returns a plain roleId → count map for the whole guild. Build a leaderboard, audit role bloat, whatever. It's just a number now.
Gateway Reconnect Hardening
v4.3.0 killed zombie connections with an ACK timeout. v4.4.0 fixes what happened after — the reconnect itself.
Shard reconnect and websocket close handling got stabilized so a shard recovers cleanly instead of getting wedged on a bad close code or racing its own resume. The close path is more careful about distinguishing "resume this" from "start over," and the reconnect logic no longer steps on itself when Discord drops the socket at an awkward moment.
This one shipped with actual reconnect tests, so it stays fixed.
Type Surface Synced to Upstream
Seyfert's exported API types drifted from discord-api-types over time, and a pile of deprecated compatibility aliases had been quietly riding along. v4.4.0 syncs everything back to the canonical upstream names and drops the shims.
Payloads for users, guilds, monetization, soundboard, and messages were refreshed; REST type names for guilds, channels, stickers, soundboard, voice, and interaction callbacks now match upstream. The framework internals consume the canonical names too, so the next sync is far less painful.
This is type-surface work — no runtime behavior changed — but if you imported one of the old deprecated type aliases directly, your editor will point you at the current name. Follow it.
Deno Stops Throwing
The "magic import" guard used to throw under Deno. Deno fixed the underlying issue, so the throw is gone. Minimum version is Deno 2.6.9 — document it is, and now startup doesn't yell at you either.
Upgrade
pnpm install [email protected]v4.4.0 is the 4.x line going out on a high note: voice channels that talk back, roles that count, and a gateway that knows how to get back up.
Next stop is v5. Pack light.