npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ding-ai-minutes-bridge

v0.0.9

Published

钉钉 AI 听记桌面端开放 SDK,提供跨 iframe 调用桌面端 JSAPI 的能力

Readme

@ali/ding-ai-minutes-bridge

钉钉 AI 听记桌面端开放 SDK,提供跨 iframe 调用桌面端 JSAPI 的能力。

安装

npm install @ali/ding-ai-minutes-bridge
# 或
pnpm install @ali/ding-ai-minutes-bridge

快速开始

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// 调用桌面端 JSAPI
const result = await AIMinutesBridge.call('methodName', { key: 'value' })

API 文档

初始化配置

// 方式1: 初始化后调用
AIMinutesBridge.init({ enableLog: true })

// 方式2: 链式调用
const result = await AIMinutesBridge
  .init({ enableLog: true })
  .call('methodName', params)

常用方法示例

requestAuthCode 获取免登码

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// 打开调试日志
AIMinutesBridge.init({ enableLog: true })

try {
    // 由于请求由听记域名(https://shanji.dingtalk.com)代理申请,请将https://shanji.dingtalk.com 加入微应用的端内免登地址
    const result = await AIMinutesBridge.call('requestAuthCode', {
      corpId: 'ding12345' // 填入当前 corpId
    });
    console.log('requestAuthCode success, result', result);
  } catch (error) {
    console.log('requestAuthCode errror', error);
  }

getCurrentTheme 获取当前主题

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'
try {
    const result = await AIMinutesBridge.call('getCurrentTheme', {});
    console.log('getCurrentTheme success, result', result);
  } catch (error) {
    console.log('getCurrentTheme errror', error);
  }

webPageSizeChange 页面尺寸变化

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'
try {
    const result = await AIMinutesBridge.call('webPageSizeChange', {
      height: 1100,
    });
    console.log('webPageSizeChange success, result', result);
  } catch (error) {
    console.log('webPageSizeChange errror', error);
  }

subscribeEvent 订阅事件

订阅事件,当事件触发时会收到回调通知。默认使用 flash_minutes_bridge namespace

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// 使用默认 namespace ('flash_minutes_bridge') 订阅事件
const result = await AIMinutesBridge.subscribeEvent(
  'webPageSizeChange',  // eventName
  (data) => {           // 事件处理器
    console.log('收到事件数据:', data);
  }
);

// 使用自定义 namespace 订阅事件
const result2 = await AIMinutesBridge.subscribeEvent(
  'customEvent',        // eventName
  (data) => {           // 事件处理器
    console.log('收到事件数据:', data);
  },
  {
    namespace: 'my_custom_namespace' // 自定义 namespace(可选)
  }
);

if (result.success) {
  console.log('订阅成功:', result.message);
} else {
  console.log('订阅失败:', result.message);
}

参数说明:

  • eventName: string - 事件名称(必填)
  • handler: (data: unknown) => void - 事件触发时的回调函数(必填)
  • namespace?: string - channel 命名空间,默认为 'flash_minutes_bridge'(可选)

注意:

  • SDK 内部会自动生成唯一的 callbackId 用于标识此次订阅
  • 同一个 namespace + eventName + callbackId 组合只能订阅一次
  • 订阅成功后,当事件触发时,宿主页面会推送事件数据到 iframe

unsubscribeEvent 取消订阅事件

取消已订阅的事件监听。

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// 取消订阅(需要知道订阅时使用的 callbackId)
const result = await AIMinutesBridge.unsubscribeEvent(
  'flash_minutes',      // namespace
  'webPageSizeChange',  // eventName
  callbackId            // 订阅时使用的 callbackId
);

if (result.success) {
  console.log('取消订阅成功:', result.message);
} else {
  console.log('取消订阅失败:', result.message);
}

注意:

  • 目前 subscribeEvent 方法不返回 callbackId,如果需要取消订阅,建议:
    1. 使用 AIMinutesBridge.call('subscribeEvent', {...}) 方式手动传入 callbackId
    2. 或仅在页面卸载时调用 cleanup() 清理所有订阅

publishEvent 发布事件

向指定 eventName 发布事件,所有订阅了该事件的 iframe 页面(除了发布者自己)都会收到通知。默认使用 flash_minutes_bridge namespace

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// 使用默认 namespace ('flash_minutes_bridge') 发布自定义事件
const result = await AIMinutesBridge.publishEvent(
  'customEvent',      // eventName
  { message: 'Hello', timestamp: Date.now() }  // 事件数据
);

// 使用自定义 namespace 发布事件
const result2 = await AIMinutesBridge.publishEvent(
  'customEvent',      // eventName
  { message: 'Hello' }, // 事件数据
  'my_custom_namespace' // 自定义 namespace(可选)
);

console.log(`事件已推送到 ${result.pushCount} 个订阅者`);

参数说明:

  • eventName: string - 事件名称(必填)
  • data: unknown - 任意类型的事件数据(必填)
  • namespace?: string - channel 命名空间,默认为 'flash_minutes_bridge'(可选)

返回值:

  • success: boolean - 是否发布成功
  • pushCount: number - 成功推送到的订阅者数量
  • message: string - 响应消息

注意:

  • 发布者自身不会收到该事件的通知
  • flash_minutes_bridge namespace 已默认加入白名单,无需额外配置

cleanup 清理资源

在页面卸载前调用,清理所有事件订阅和 SDK 资源。

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// 页面卸载前清理资源
window.addEventListener('beforeunload', () => {
  AIMinutesBridge.cleanup();
});

页面间通信完整示例

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// ========== 页面 A(发布者)==========
async function initPageA() {
  AIMinutesBridge.init({ enableLog: true });

  // 发布事件
  document.getElementById('sendBtn')?.addEventListener('click', async () => {
    const result = await AIMinutesBridge.publishEvent(
      'my_app',
      'message',
      { from: 'Page A', text: 'Hello Page B!' }
    );
    console.log(`消息已发送给 ${result.pushCount} 个接收者`);
  });
}

// ========== 页面 B(订阅者)==========
async function initPageB() {
  AIMinutesBridge.init({ enableLog: true });

  // 订阅事件
  await AIMinutesBridge.subscribeEvent(
    'message',
    (data) => {
      console.log('收到消息:', data);
      // 输出: { from: 'Page A', text: 'Hello Page B!' }
    }
  );
}

其他 jsapi

其他jsapi 为内应用调用,三方页面无法使用

call(methodName, params)

调用桌面端 JSAPI。

const result = await AIMinutesBridge.call('methodName', { param1: 'value1' })

参数:

  • methodName: string - 方法名
  • params?: unknown - 参数对象

返回: Promise<T> - 返回 Promise,resolve 时获取结果


init(config)

初始化 SDK 配置,支持链式调用。

AIMinutesBridge.init({ enableLog: true })

setLogEnabled(enabled)

动态设置日志开关,支持链式调用。

AIMinutesBridge.setLogEnabled(true)

getVersion()

获取 SDK 版本号。

const version = AIMinutesBridge.getVersion() // "1.0.0"

isInIframe()

检查当前是否在 iframe 中运行。

const inIframe = AIMinutesBridge.isInIframe() // true/false

类型导入

import type {
  BridgeConfig,
  BridgeMessage,
  MessagePayload,
  MessageResult,
  ReceivedMessage,
  EventPushMessage,
  EventHandler,
  EventSubscription,
  // API 参数类型
  RequestAuthCodeParams,
  GetCurrentThemeParams,
  WebPageSizeChangeParams,
  SubscribeEventParams,
  SubscribeEventResult,
  UnsubscribeEventParams,
  UnsubscribeEventResult,
  PublishEventParams,
  PublishEventResult,
} from '@ali/ding-ai-minutes-bridge'

页面间通信完整示例

场景:两个 iframe 页面互相通信

使用 默认 namespace 'flash_minutes_bridge' 进行页面间通信:

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// ========== 页面 A(作为发布者)==========
async function initPublisher() {
  AIMinutesBridge.init({ enableLog: true });

  // 点击按钮发布事件(使用默认 namespace 'flash_minutes_bridge')
  document.getElementById('sendBtn')?.addEventListener('click', async () => {
    const result = await AIMinutesBridge.publishEvent(
      'newMessage',  // eventName
      {
        from: 'Page A',
        text: 'Hello from Page A!',
        timestamp: Date.now()
      }
    );
    console.log(`消息已发送给 ${result.pushCount} 个接收者`);
  });

  // 页面卸载前清理
  window.addEventListener('beforeunload', () => {
    AIMinutesBridge.cleanup();
  });
}

// ========== 页面 B(作为订阅者)==========
async function initSubscriber() {
  AIMinutesBridge.init({ enableLog: true });

  // 订阅消息事件(使用默认 namespace 'flash_minutes_bridge')
  await AIMinutesBridge.subscribeEvent(
    'newMessage',  // eventName
    (data) => {
      console.log('收到来自 Page A 的消息:', data);
      // 在页面上展示消息
      displayMessage(data);
    }
  );

  // 也可以同时发布自己的消息
  document.getElementById('replyBtn')?.addEventListener('click', async () => {
    await AIMinutesBridge.publishEvent(
      'newMessage',  // eventName
      {
        from: 'Page B',
        text: 'Hi Page A!',
        timestamp: Date.now()
      }
    );
  });

  // 页面卸载前清理
  window.addEventListener('beforeunload', () => {
    AIMinutesBridge.cleanup();
  });
}

使用自定义 namespace

如果需要使用自定义 namespace,可以传递第三个参数:

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// 使用自定义 namespace 发布事件
await AIMinutesBridge.publishEvent(
  'syncData',           // eventName
  { updated: true },    // data 
  'my_custom_app'
);

// 使用自定义 namespace 订阅事件
await AIMinutesBridge.subscribeEvent(
  'syncData',           // eventName
  (data) => {          // handler
    console.log('收到同步数据:', data);
  },
  {
    namespace: 'my_custom_app',
  } 
);

缓存消息

如果需要缓存消息,即先 pub 消息,后 sub 消息,可以传递第三个参数:

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

// 使用 useCache 发布事件
await AIMinutesBridge.publishEvent(
  'syncData',           // eventName
  { updated: true },    // data   
);

// 后订阅事件也能收到数据
await AIMinutesBridge.subscribeEvent(
  'syncData',           // eventName
  (data) => {          // handler
    console.log('收到同步数据:', data);
  },
  {
     useCache: true, // 使用缓存
  }
);

双向通信(一个页面既是发布者也是订阅者)

import AIMinutesBridge from '@ali/ding-ai-minutes-bridge'

async function initBidirectional() {
  AIMinutesBridge.init({ enableLog: true });

  // 订阅来自其他页面的消息(使用默认 namespace)
  await AIMinutesBridge.subscribeEvent(
    'syncData',
    (data) => {
      console.log('收到同步数据:', data);
      updateUI(data);
    }
  );

  // 当本地数据变化时,发布事件通知其他页面
  document.getElementById('input')?.addEventListener('change', async (e) => {
    await AIMinutesBridge.publishEvent(
      'syncData',
      {
        field: 'input',
        value: e.target.value,
        source: 'page1'
      }
    );
  });
}

## 注意事项

1. **iframe 环境**: 此 SDK 必须在 iframe 中运行,通过 `postMessage` 与父窗口通信
2. **默认 namespace**: `subscribeEvent` 和 `publishEvent` 默认使用 `'flash_minutes_bridge'` namespace,该 namespace 已加入宿主页面白名单,无需额外配置
3. **事件订阅/发布**: 订阅和发布的事件需要宿主页面(听记桌面端)支持
4. **权限控制**: 使用自定义 namespace 时,需要确保该 namespace 在宿主页面的白名单中
5. **资源清理**: 建议在页面卸载时调用 `cleanup()` 方法,避免内存泄漏
6. **发布者排除**: 发布事件时,发布者自身不会收到该事件的通知
7. **跨页面通信**: 通过 `publishEvent` 和 `subscribeEvent` 可以实现多个 iframe 页面之间的双向通信