diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0f03404a..327a2d75 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1350,6 +1350,9 @@ importers:
       oidc-provider:
         specifier: ^7.10.6
         version: 7.11.5
+      p-map:
+        specifier: ^4.0.0
+        version: 4.0.0
       qs:
         specifier: ^6.10.3
         version: 6.11.0
diff --git a/server/package.json b/server/package.json
index d73a6be0..afb83ce9 100644
--- a/server/package.json
+++ b/server/package.json
@@ -66,6 +66,7 @@
     "nanoid": "^3.1.23",
     "nodemailer": "^6.7.2",
     "oidc-provider": "^7.10.6",
+    "p-map": "^4.0.0",
     "qs": "^6.10.3",
     "redlock": "^4.2.0",
     "send": "^0.18.0",
diff --git a/server/services/core/chat/inbox.service.ts b/server/services/core/chat/inbox.service.ts
index e304ed1d..4b757ef7 100644
--- a/server/services/core/chat/inbox.service.ts
+++ b/server/services/core/chat/inbox.service.ts
@@ -6,6 +6,7 @@ import {
   TcPureContext,
   InboxStruct,
 } from 'tailchat-server-sdk';
+import pMap from 'p-map';
 
 /**
  * 收件箱管理
@@ -70,6 +71,14 @@ class InboxService extends TcService {
         payload: 'any',
       },
     });
+    this.registerAction('batchAppend', this.batchAppend, {
+      visibility: 'public',
+      params: {
+        userIds: { type: 'array', items: 'string' },
+        type: 'string',
+        payload: 'any',
+      },
+    });
     this.registerAction('removeMessage', this.removeMessage, {
       visibility: 'public',
       params: {
@@ -115,6 +124,48 @@ class InboxService extends TcService {
     return true;
   }
 
+  /**
+   * append 的多用户版本
+   */
+  async batchAppend(
+    ctx: TcContext<{
+      userIds: string[];
+      type: string;
+      payload: Record<string, any>;
+    }>
+  ) {
+    const { userIds, type, payload } = ctx.params;
+
+    const docs = await this.adapter.model.create(
+      userIds.map((userId) => ({
+        userId,
+        type,
+        payload,
+      }))
+    );
+
+    const inboxItems: InboxStruct[] = await this.transformDocuments(
+      ctx,
+      {},
+      docs
+    );
+
+    pMap(
+      inboxItems,
+      async (inboxItem) => {
+        await Promise.all([
+          this.notifyUsersInboxAppend(ctx, [inboxItem.userId], inboxItem),
+          this.emitInboxAppendEvent(ctx, inboxItem),
+        ]);
+      },
+      {
+        concurrency: 10,
+      }
+    );
+
+    return true;
+  }
+
   async removeMessage(
     ctx: TcContext<{
       userId?: string;