@clipboard-health/notifications

中文文档
3.17.17发布于 2026/11/05MITTypeScriptCommonJS近 30 天下载 2.2万

通过第三方供应商发送通知.

中文使用文档
文档目录5 节
  1. 目录
  2. 使用量
  3. triggerChunked
  4. 调试
  5. 地方发展指挥部

@ 剪贴板- 健康/ 通知

通过第三方供应商发送通知.

目录

使用量

triggerChunked

triggerChunked 将全部、不可改变的触发请求保存在工作有序时间,消除有呆滞数据的问题,将请求排入提供者限制范围,以及在工作执行时间更新请求时可能出现的一能关键冲突.

  1. 搜索您的服务 triggerNotification.constants.ts, (中文(简体) ), triggerNotification.job.ts 财务报告和审定财务报表 notificationClient.provider.ts如果它们不存在,则创建它们:

    // triggerNotification.constants.ts
    export const TRIGGER_NOTIFICATION_JOB_NAME = "TriggerNotificationJob";
    
    // triggerNotification.job.ts
    import type { BaseHandler } from "@clipboard-health/background-jobs-adapter";
    import {
      ERROR_CODES,
      isClientError,
      type NotificationClient,
      type SerializableTriggerChunkedRequest,
      toTriggerChunkedRequest,
    } from "@clipboard-health/notifications";
    import { isFailure } from "@clipboard-health/util-ts";
    
    import { CBHLogger } from "./setup";
    import { TRIGGER_NOTIFICATION_JOB_NAME } from "./triggerNotification.constants";
    
    /**
     * For @clipboard-health/mongo-jobs:
     * 1. Implement `HandlerInterface<SerializableTriggerChunkedRequest>`.
     * 2. The 10 default `maxAttempts` with exponential backoff of `2^attemptsCount` means ~17 minutes
     *    of cumulative delay. If your notification could be stale before this, set
     *    `SerializableTriggerChunkedRequest.expiresAt` when enqueueing.
     *
     * For @clipboard-health/background-jobs-postgres:
     * 1. Implement `Handler<SerializableTriggerChunkedRequest>`.
     * 2. The 20 default `maxRetryAttempts` with exponential backoff of `10s * 2^(attempt - 1)` means
     *    ~121 days of cumulative delay. If your notification could be stale before this, set
     *    `maxRetryAttempts` (and `SerializableTriggerChunkedRequest.expiresAt`) when enqueueing.
     */
    export class TriggerNotificationJob implements BaseHandler<SerializableTriggerChunkedRequest> {
      // For background-jobs-postgres, use `public static queueName = TRIGGER_NOTIFICATION_JOB_NAME;`
      public name = TRIGGER_NOTIFICATION_JOB_NAME;
      private readonly logger = new CBHLogger({
        defaultMeta: {
          logContext: TRIGGER_NOTIFICATION_JOB_NAME,
        },
      });
    
      public constructor(
        // @Inject(NOTIFICATION_CLIENT_TOKEN)
        private readonly client: NotificationClient,
      ) {}
    
      public async perform(
        data: SerializableTriggerChunkedRequest,
        /**
         * For mongo-jobs, implement `BackgroundJobType<SerializableTriggerChunkedRequest>`, which has
         *    `_id`, `attemptsCount`, and `uniqueKey`.
         *
         * For background-jobs-postgres, implement `Job<SerializableTriggerChunkedRequest>`, which has
         *    `id`, `retryAttempts`, and `idempotencyKey`.
         */
        job: { _id: string; attemptsCount: number; uniqueKey?: string },
      ) {
        const metadata = {
          // For background-jobs-postgres, this is called `retryAttempts`.
          attempt: job.attemptsCount + 1,
          jobId: job._id,
          recipientCount: data.body.recipients.length,
          workflowKey: data.workflowKey,
        };
        this.logger.info("TriggerNotificationJob processing", metadata);
    
        try {
          const request = toTriggerChunkedRequest(data, {
            attempt: metadata.attempt,
            idempotencyKey: job.uniqueKey ?? metadata.jobId,
            // In case the tests are moving the time forward we need to ensure notifications don't expire.
            // ...(isTestMode && { expiresAt: new Date(3000, 0, 1) }),
          });
          const result = await this.client.triggerChunked(request);
    
          if (isFailure(result)) {
            const code = result.error.issues[0]?.code;
    
            // Expired: the notification is no longer relevant (e.g. a reminder for an event that
            // has already started). Not actionable, so log at WARN and move on.
            if (code === ERROR_CODES.expired) {
              this.logger.warn("TriggerNotificationJob skipped due to expiry", { ...metadata });
              return;
            }
    
            // The request itself is broken (empty/over-max recipients, invalid expiresAt or
            // idempotency key, missing signing key, or a non-429 4xx from the provider).
            // Retrying won't help — log at ERROR so it pages and we can fix the caller.
            if (isClientError(code)) {
              this.logger.error("TriggerNotificationJob skipped due to client error", {
                ...metadata,
                error: result.error,
              });
              return;
            }
    
            // Everything else (rateLimited, unknown, 5xx, network) is transient — throw so the
            // job retries with backoff.
            throw result.error;
          }
    
          const success = "TriggerNotificationJob success";
          this.logger.info(success, { ...metadata, response: result.value });
          // For background-jobs-postgres, return the `success` string result.
        } catch (error) {
          this.logger.error("TriggerNotificationJob failure", { ...metadata, error });
          throw error;
        }
      }
    }
    
    import { NotificationClient } from "@clipboard-health/notifications";
    
    import { CBHLogger, type Provider, toLogger, tracer } from "./setup";
    
    export const NOTIFICATION_CLIENT_TOKEN = "NOTIFICATION_CLIENT";
    
    export const NotificationClientProvider: Provider<NotificationClient> = {
      provide: NOTIFICATION_CLIENT_TOKEN,
      useFactory: (): NotificationClient =>
        new NotificationClient({
          apiKey: process.env["KNOCK_API_KEY"]!,
          logger: toLogger(
            new CBHLogger({
              defaultMeta: { context: "NotificationClient" },
            }),
          ),
          tracer,
        }),
    };
    
  2. 搜索服务中存储工作流程密钥的常数 。 如果没有,就创造它:

    /* eslint sort-keys: "error" */
    
    /**
     * Alphabetical list of workflow keys.
     */
    export const WORKFLOW_KEYS = {
      eventStartingReminder: "event-starting-reminder",
    } as const;
    
  3. 构建您的 SerializableTriggerChunkedRequest 并调整你的工作。 想着排队 TriggerNotificationJob 作为一项职能,要求以最佳做法的方式发送通知。 你不应该打电话 triggerChunked 直接说 例如,如果您的通知被延迟, 创建一个未来运行的背景任务, 做任何必要的检查以确保您应该通知, 然后排队 TriggerNotificationJob。 。 。 .

    import type { BackgroundJobsAdapter } from "@clipboard-health/background-jobs-adapter";
    import type { SerializableTriggerChunkedRequest } from "@clipboard-health/notifications";
    
    import { BackgroundJobsService } from "./setup";
    import { TRIGGER_NOTIFICATION_JOB_NAME } from "./triggerNotification.constants";
    import { WORKFLOW_KEYS } from "./workflowKeys";
    
    /**
     * Enqueue a notification job in the same database transaction as the changes it's notifying about.
     * The `session` option is called `transaction` in `background-jobs-postgres`.
     */
    async function enqueueTriggerNotificationJob(adapter: BackgroundJobsAdapter) {
      // Assume this comes from a database and are used as template variables...
      const notificationData = {
        favoriteColor: "blue",
        // Use @clipboard-health/date-time's formatShortDateTime in your service for consistency.
        favoriteAt: new Date().toISOString(),
        secret: "2",
      };
    
      const jobData: SerializableTriggerChunkedRequest = {
        // Important: Read the TypeDoc documentation for additional context.
        body: {
          recipients: ["userId-1", "userId-2"],
          data: notificationData,
        },
        // Helpful when controlling notifications with feature flags.
        dryRun: false,
        // Set expiresAt at enqueue-time so it remains stable across job retries. Use date-fns in your
        // service instead of this manual calculation.
        expiresAt: new Date(Date.now() + 60 * 60_000).toISOString(),
        // Keys to redact from logs
        keysToRedact: ["secret"],
        workflowKey: WORKFLOW_KEYS.eventStartingReminder,
      };
    
      // Option 1 (default): Automatically use background job ID as idempotency key.
      await adapter.enqueue(TRIGGER_NOTIFICATION_JOB_NAME, jobData, { session: "..." });
    
      // Option 2 (advanced): Provide custom idempotency key to job and notification libraries for more
      // control. You'd use this to provide enqueue-time deduplication. For example, if you enqueue when
      // a user clicks a button and only want them to receive one notification.
      await adapter.enqueue(TRIGGER_NOTIFICATION_JOB_NAME, jobData, {
        // Called `idempotencyKey` in `background-jobs-postgres`.
        unique: `meeting-123-reminder`,
        session: "...",
      });
    }
    
    void enqueueTriggerNotificationJob(
      // Use your instance of `@clipboard-health/mongo-jobs` or `@clipboard-health/background-jobs-postgres` here.
      new BackgroundJobsService(),
    );
    

调试

Knock 的回复和错误的日志条目包括 knockRequestId敲门的身份证明. 过滤器由 请求编号 下级 观察性 > 翻译: 日志 内 敲打仪表板 看着Knock自己对请求和回应的看法 尸体 尸体 尸体 尸体 尸体 敲打其中的长值, 标记其下降 __knock_truncated__ 或者说 [TRUNCATED],并保留30天 API 日志。 。 。 .

地方发展指挥部

见 package.json scripts 用于命令列表.

版本与发布记录

@clipboard-health/notifications 共发布 436 个版本,首次发布于 2025/09/17;过去 12 个月发布了 393 个版本。

版本发布日期距今
3.17.17latest2026/11/054 天前
3.17.162026/11/055 天前
3.17.152026/11/045 天前
3.17.142026/10/3110 天前
3.17.132026/10/2812 天前
3.17.122026/10/2813 天前

关于 @clipboard-health/notifications 的常见问题

@clipboard-health/notifications 是什么?

通过第三方供应商发送通知.

如何安装 @clipboard-health/notifications?

在项目目录运行 npm install @clipboard-health/notifications,或使用 pnpm add / yarn add / bun add。

@clipboard-health/notifications 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@clipboard-health/notifications 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@clipboard-health/notifications 可以商用吗?

@clipboard-health/notifications 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@clipboard-health/notifications 的下载量有多少?

根据 npm 官方下载统计,@clipboard-health/notifications 在 2026/10/10 – 2026/11/08 这 30 天内被下载 21,764 次,日均约 725 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@clipboard-health/notifications 还在维护吗?

最新版本 3.17.17 发布于 2026/11/05(4 天前);至今共发布 436 个版本,其中过去 12 个月发布了 393 个;首次发布于 2025/09/17。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。