🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@fluojs/discord

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fluojs/discord

Webhook-first, transport-agnostic Discord delivery core for Fluo with notifications integration.

Source
npmnpm
Version
1.0.2
Version published
Weekly downloads
66
-63.54%
Maintainers
1
Weekly downloads
 
Created
Source

@fluojs/discord

English 한국어

Webhook-first, transport-agnostic Discord delivery core for fluo. It provides a Nest-like module API, an injectable DiscordService for standalone usage, and a first-party DiscordChannel for @fluojs/notifications integration without assuming a Node-only Discord SDK.

Table of Contents

Installation

npm install @fluojs/discord @fluojs/notifications

This package follows the repo-wide Node.js 20+ install baseline reflected in published package metadata, while keeping its delivery contract transport-agnostic at runtime through explicit fetch-compatible boundaries.

When to Use

  • When you want one package that can send Discord messages directly and also plug into @fluojs/notifications.
  • When transport choice must stay explicit and portable across Node, Bun, Deno, and Cloudflare-compatible application boundaries.
  • When Discord delivery should prefer incoming webhooks while still allowing richer REST or bot-backed integrations through a custom transport contract.
  • When configuration must enter through DI or explicit options instead of process.env reads inside the package.

Quick Start

Register the module

import { Module } from '@fluojs/core';
import { DiscordModule, createDiscordWebhookTransport } from '@fluojs/discord';

@Module({
  imports: [
    DiscordModule.forRoot({
      defaultThreadId: 'release-thread-id',
      transport: createDiscordWebhookTransport({
        fetch: globalThis.fetch.bind(globalThis),
        webhookUrl: 'https://discord.com/api/webhooks/123/abc',
      }),
    }),
  ],
})
export class AppModule {}

Send Discord messages directly

import { Inject } from '@fluojs/core';
import { DiscordService } from '@fluojs/discord';

@Inject(DiscordService)
export class DeployNotifier {
  constructor(private readonly discord: DiscordService) {}

  async announce(version: string) {
    await this.discord.send({
      content: `Deploy ${version} finished successfully.`,
    });
  }
}

Common Patterns

Standalone delivery with DiscordService

Use DiscordService when your application wants direct Discord delivery without routing through the notifications foundation.

DiscordModule.forRootAsync({
  inject: [ConfigService],
  useFactory: (config) => ({
    defaultThreadId: config.discord.defaultThreadId,
    transport: createDiscordWebhookTransport({
      fetch: config.runtime.fetch,
      webhookUrl: config.discord.webhookUrl,
    }),
  }),
});

Behavioral contract notes:

  • DiscordService.send(...) resolves defaultThreadId before delivery.
  • The service initializes the configured transport during module bootstrap and closes factory-owned resources during application shutdown.
  • Sends are accepted only after bootstrap marks the transport ready; attempts before bootstrap, during startup, after failed bootstrap, while shutting down, or after shutdown are rejected before delivery.
  • Sends attempted while the service is shutting down or already stopped are rejected before reusing the cached transport.
  • Blank defaultThreadId and notifications.channel values are trimmed and ignored; the notifications channel defaults to discord.
  • The package never reads process.env directly. All configuration must enter through explicit options or DI.

Integration with @fluojs/notifications

Inject DISCORD_CHANNEL into NotificationsModule.forRootAsync(...) so the Discord package remains the only place that understands Discord-specific payload fields and recipient-to-thread translation.

import { Module } from '@fluojs/core';
import { NotificationsModule } from '@fluojs/notifications';
import {
  DISCORD_CHANNEL,
  DiscordModule,
  createDiscordWebhookTransport,
} from '@fluojs/discord';

@Module({
  imports: [
    DiscordModule.forRoot({
      transport: createDiscordWebhookTransport({
        fetch: globalThis.fetch.bind(globalThis),
        webhookUrl: 'https://discord.com/api/webhooks/123/abc',
      }),
    }),
    NotificationsModule.forRootAsync({
      inject: [DISCORD_CHANNEL],
      useFactory: (channel) => ({
        channels: [channel],
      }),
    }),
  ],
})
export class AppModule {}

Supported notification payload fields:

  • content, embeds, components, attachments
  • allowedMentions, username, avatarUrl, tts
  • threadId, threadName, flags, poll, metadata

Behavioral contract notes:

  • One notification dispatch maps to exactly one Discord thread route. Use payload.threadId or a single entry in recipients.
  • If payload.threadId is omitted, DiscordService.sendNotification(...) uses the first recipients entry or falls back to defaultThreadId.
  • Notification metadata is merged from payload metadata, dispatch metadata, and template/subject markers. template is rendered only when a renderer is configured.
  • If a notification needs fan-out across multiple Discord threads, call sendMany(...) instead of one multi-recipient dispatch.

Webhook-first delivery with explicit fetch injection

Use createDiscordWebhookTransport(...) when you want a portable first-party transport that only depends on a fetch-compatible HTTP boundary.

const transport = createDiscordWebhookTransport({
  fetch: runtime.fetch,
  webhookUrl: discordWebhookUrl,
});

await discord.send({
  content: 'Deploy finished',
  embeds: [{ description: 'Build 124 succeeded.' }],
});

For richer API integrations such as bot-backed REST delivery, implement the exported DiscordTransport contract and inject it through DiscordModule.forRoot(...) or forRootAsync(...).

Behavioral contract notes:

  • The built-in webhook transport retries transient 408, 429, and 5xx responses, and also retries transport-level exceptions, using bounded exponential backoff before surfacing an error. Permanent upstream responses are not retried.
  • Successful webhook responses are exposed through DiscordSendResult.response; caller-visible DiscordTransportError messages still omit raw upstream response bodies by default, including after rate-limit retries fail.
  • Malformed or non-absolute webhookUrl values are rejected immediately as DiscordConfigurationError instead of being retried as delivery failures.

Intentional limitations

The Discord package intentionally does not:

  • read credentials or webhook URLs from process.env
  • ship a Node-only Discord SDK inside the shared root package boundary
  • force one provider strategy beyond the webhook-first helper and exported transport contract
  • translate one notification into multi-thread fan-out inside a single dispatch call

These limitations are part of the package contract so runtime choice, provider capability, and rollout strategy stay explicit at the application boundary.

Public API Overview

Core

  • Discord
  • DiscordModule.forRoot(options) / DiscordModule.forRootAsync(options)
  • DiscordModuleOptions
  • DiscordAsyncModuleOptions
  • DiscordService
  • DiscordChannel
  • DISCORD
  • DISCORD_CHANNEL

Compose applications through DiscordModule and integrate notifications through DISCORD_CHANNEL plus the exported transport contracts.

Contracts and helpers

  • DiscordMessage
  • NormalizedDiscordMessage
  • DiscordWebhookTransportOptions
  • DiscordFetchLike
  • DiscordFetchResponse
  • DiscordSendResult
  • DiscordSendOptions
  • DiscordSendManyOptions
  • DiscordSendBatchResult
  • DiscordSendFailure
  • DiscordNotificationPayload
  • DiscordNotificationDispatchRequest
  • DiscordAllowedMentions
  • DiscordAttachment
  • DiscordComponent
  • DiscordEmbed
  • DiscordPoll
  • DiscordTransport
  • DiscordTransportContext
  • DiscordTransportFactory
  • DiscordTransportReceipt
  • DiscordTemplateRenderInput
  • DiscordTemplateRenderResult
  • DiscordTemplateRenderer
  • createDiscordWebhookTransport(options)

Status and errors

  • createDiscordPlatformStatusSnapshot(...)
  • DiscordLifecycleState
  • DiscordPlatformStatusSnapshot
  • DiscordStatusAdapterInput
  • DiscordConfigurationError
  • DiscordMessageValidationError
  • DiscordTransportError
  • @fluojs/notifications: Shared orchestration layer that consumes DISCORD_CHANNEL.
  • @fluojs/config: Recommended for resolving webhook URLs or thread ids without direct environment access.
  • @fluojs/event-bus: Useful when Discord notifications are one side effect among several event-driven workflows.

Example Sources

  • packages/discord/src/module.test.ts: Module registration, async wiring, webhook transport, and notifications integration examples.
  • packages/discord/src/public-surface.test.ts: Public export and TypeScript contract verification.
  • packages/discord/src/status.test.ts: Health/readiness contract examples.

Keywords

fluo

FAQs

Package last updated on 15 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts