Agent Skillswebiny/webiny-js › webiny-websocket-notifications

webiny-websocket-notifications

GitHub

实现 API 到 Admin 端的 WebSocket 实时通知,用于推送后台任务进度并触发 UI 更新或提示。

skills/user-skills/api/websocket-notifications/SKILL.md webiny/webiny-js

Trigger Scenarios

需要在服务端向客户端推送实时消息 需要处理 WebSocket 事件以更新前端状态

Install

npx skills add webiny/webiny-js --skill webiny-websocket-notifications -g -y
More Options

Non-standard path

npx skills add https://github.com/webiny/webiny-js/tree/next/skills/user-skills/api/websocket-notifications -g -y

Use without installing

npx skills use webiny/webiny-js@webiny-websocket-notifications

指定 Agent (Claude Code)

npx skills add webiny/webiny-js --skill webiny-websocket-notifications -a claude-code -g -y

安装 repo 全部 skill

npx skills add webiny/webiny-js --all -g -y

预览 repo 内 skill

npx skills add webiny/webiny-js --list

SKILL.md

Frontmatter
{
    "name": "webiny-websocket-notifications",
    "description": "Sending real-time notifications from the API to the Admin app over websockets, and reacting to them on the client. Use this skill when the developer wants to push a message to the user who triggered some server-side work (e.g. per-entry progress from a background task\/bulk action) and show a toast, update a cache, or refresh UI in response. Requires Webiny 6.5.0 or newer."
}

Websocket notifications (API → Admin)

TL;DR

On the API, inject WebsocketsSendToIdentityUseCase (webiny/api) + IdentityContext (webiny/api/security) and call sendToIdentity.execute({ id }, { action, data }). On the Admin, implement a WebsocketEventHandler (webiny/admin/websockets) that filters on action and reacts (e.g. toast via Notifications from webiny/admin), registered with createFeature + RegisterFeature.

API — emit

import { WebsocketsSendToIdentityUseCase } from "webiny/api";
import { IdentityContext } from "webiny/api/security";

class MyTaskOrHook {
  constructor(
    private identityContext: IdentityContext.Interface,
    private sendToIdentity: WebsocketsSendToIdentityUseCase.Interface
  ) {}

  async notify(entry) {
    // Best-effort: a websocket failure must never fail the real work.
    try {
      const identity = this.identityContext.getIdentity();
      if (identity) {
        await this.sendToIdentity.execute(
          { id: identity.id },
          {
            action: "cms.product.discountApplied",
            data: { id: entry.entryId, price: entry.values.price }
          }
        );
      }
    } catch (ex) {
      // log & swallow
    }
  }
}
// dependencies: [IdentityContext, WebsocketsSendToIdentityUseCase]
  • Send to the user who triggered the work — get them from IdentityContext. In a background task/bulk action, the triggering identity is available.
  • Use a namespaced action string; put the payload in data.
  • Sender data type: { action?: string; data?: T; error?: {...} }.

Admin — listen

import { WebsocketEventHandler } from "webiny/admin/websockets";
import { Notifications } from "webiny/admin";

const ACTION = "cms.product.discountApplied";

class MyHandlerImpl implements WebsocketEventHandler.Interface {
  constructor(private notifications: Notifications.Interface) {}

  async handle(event: WebsocketEventHandler.Event): Promise<void> {
    const payload = event.payload as { action?: string; data?: { id: string; price: number } };
    if (payload.action !== ACTION || !payload.data) {
      return; // every handler sees every message — filter by action
    }
    this.notifications.success({
      title: "Discount applied",
      description: `New price ${payload.data.price}.`
    });
  }
}

export const MyHandler = WebsocketEventHandler.createImplementation({
  implementation: MyHandlerImpl,
  dependencies: [Notifications]
});

Read the message off event.payloadevent.payload.action and event.payload.data (the exact { action, data } object the API sent).

Admin — register

Register the handler in a feature and render it from your Admin.Extension:

import { createFeature, RegisterFeature } from "webiny/admin";
import { MyHandler } from "./MyHandler.js";

const MyFeature = createFeature({
  name: "MyExtension/Notifications",
  register(container) {
    container.register(MyHandler);
  }
});

export default () => <RegisterFeature feature={MyFeature} />;

The websockets runner resolves every registered WebsocketEventHandler and calls handle for each incoming message — hence the action filter in each handler.

Related

  • webiny-cms-bulk-actions — the typical emitter: a bulk action's processData sends a message per processed entry so the Admin can toast progress live.

Version History

  • 80eb1c5 Current 2026-08-20 10:07

Same Skill Collection

.claude/skills/grill-me/SKILL.md
.claude/skills/prd-to-plan/SKILL.md
.claude/skills/preflight/SKILL.md
.claude/skills/tester/SKILL.md
.claude/skills/write-a-prd/SKILL.md
skills/repo-skills/add-feature-flag/SKILL.md
skills/user-skills/admin/admin-architect/SKILL.md
skills/user-skills/admin/admin-permissions/SKILL.md
skills/user-skills/admin/form-model/SKILL.md
skills/user-skills/admin/new-entry-wizard/SKILL.md
skills/user-skills/admin/website-builder/page-settings/SKILL.md
skills/user-skills/admin/website-builder/wb-preview-url-modifier/SKILL.md
skills/user-skills/api-bundle-size-limit/SKILL.md
skills/user-skills/api/api-architect/SKILL.md
skills/user-skills/api/cms-bulk-actions/SKILL.md
skills/user-skills/api/custom-field-type/SKILL.md
skills/user-skills/api/event-handler-pattern/SKILL.md
skills/user-skills/api/graphql-api/SKILL.md
skills/user-skills/api/http-route/SKILL.md
skills/user-skills/api/permissions/SKILL.md
skills/user-skills/api/use-case-pattern/SKILL.md
skills/user-skills/api/v5-to-v6-migration/SKILL.md
skills/user-skills/cli-extensions/SKILL.md
skills/user-skills/configure-auth0/SKILL.md
skills/user-skills/configure-entraid/SKILL.md
skills/user-skills/configure-okta/SKILL.md
skills/user-skills/dependency-injection/SKILL.md
skills/user-skills/full-stack-architect/SKILL.md
skills/user-skills/generated/api/aco/SKILL.md
skills/user-skills/generated/api/cms/SKILL.md
skills/user-skills/generated/api/file-manager/SKILL.md
skills/user-skills/generated/api/scheduler/SKILL.md
skills/user-skills/generated/api/security/SKILL.md
skills/user-skills/generated/api/system/SKILL.md
skills/user-skills/generated/api/tenancy/SKILL.md
skills/user-skills/generated/api/tenant-manager/SKILL.md
skills/user-skills/generated/api/website-builder/SKILL.md
skills/user-skills/generated/infra/SKILL.md
skills/user-skills/infrastructure-extensions/SKILL.md
skills/user-skills/local-development/SKILL.md
skills/user-skills/mailer-smtp/SKILL.md
skills/user-skills/project-structure/SKILL.md
.claude/skills/webiny-skill-creator/SKILL.md
skills/user-skills/admin/ui-extensions/SKILL.md
skills/user-skills/api/ai-powerups-content/SKILL.md
skills/user-skills/cognito-federation/SKILL.md
skills/user-skills/content-models/SKILL.md
skills/user-skills/generated/admin/aco/SKILL.md
skills/user-skills/generated/admin/ai-powerups/SKILL.md

Metadata

Files
0
Version
80eb1c5
Hash
e52bdc5e
Indexed
2026-08-20 10:07

inicio - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-22 05:42
浙ICP备14020137号-1 $mapa de visitantes$