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

@meet-im/meet-bot-jssdk

v1.0.0

Published

MeetIM Chatbot JavaScript SDK - 支持 Long Polling 消息获取和消息发送

Downloads

947

Readme

@meet-im/meet-bot-jssdk

MeetIM Chatbot JavaScript SDK - 支持 Long Polling 消息获取、消息发送和媒体文件处理

安装

pnpm add @meet-im/meet-bot-jssdk

快速开始

类实例风格

import { MeetBot } from '@meet-im/meet-bot-jssdk'

const bot = new MeetBot({
  token: 'bot_id:secret',
  useV2: true, // 启用 getUpdatesV2,支持引用消息
})

bot.on('message', ({ message, quoteMsgMap }) => {
  console.log('收到消息:', message.content)

  // 处理引用消息
  if (message.quoteSeqID && message.sessionInfo) {
    const { getConvID, getQuoteMsgKey } = await import('@meet-im/meet-bot-jssdk')
    const convID = getConvID(
      message.sessionInfo.firstID,
      message.sessionInfo.secondID,
      message.sessionInfo.sessionType,
      message.sessionInfo.companyID
    )
    const quoteKey = getQuoteMsgKey(convID, message.quoteSeqID)
    const quoteMsg = quoteMsgMap[quoteKey]
    if (quoteMsg) {
      console.log('引用消息:', quoteMsg.content)
    }
  }

  if (message.sessionInfo) {
    bot.sendMessage(message.sessionInfo, { content: `收到: ${message.content}` })
  }
})

bot.startPolling()

函数式风格

import { getUpdatesV2, sendMessage } from '@meet-im/meet-bot-jssdk'

const token = 'bot_id:secret'
const baseUrl = 'https://staging-meet-api.miyachat.com'

const { msgs, quoteMsgMap } = await getUpdatesV2({ token, baseUrl })

for (const { message } of msgs) {
  if (message.sessionInfo) {
    console.log('收到消息:', message.content)

    await sendMessage({
      token,
      baseUrl,
      sessionInfo: message.sessionInfo,
      msgContent: { content: '收到!' },
    })
  }
}

API 文档

MeetBot 类

构造函数

new MeetBot(config: MeetBotConfig)

| 参数 | 类型 | 必填 | 说明 | | ------------------ | ------------------ | ---- | ------------------------------------------------------ | | token | string | 是* | Bot Token,格式:bot_id:secret | | botId | string | number | 是* | Bot ID(与 botToken 配合使用) | | botToken | string | 是* | Bot Token(与 botId 配合使用) | | baseUrl | string | 否 | API 地址,默认 https://staging-meet-api.miyachat.com | | pollingLimit | number | 否 | 每次拉取消息条数,默认 100 | | longPollingTimeout | number | 否 | 长轮询超时时间(秒),默认 30 | | useV2 | boolean | 否 | 使用 getUpdatesV2 接口,默认 false | | logLevel | 'silent' | 'info' | 否 | 日志级别,默认 'silent' |

*token 或 (botId + botToken) 二选一

方法

| 方法 | 说明 | | -------------------------------------- | ------------------ | | on(event, handler) | 监听事件 | | off(event, handler) | 移除事件监听 | | startPolling(options?) | 启动长轮询 | | stopPolling() | 停止轮询 | | isPolling() | 获取轮询状态 | | getUpdates(options?) | 手动获取消息(V1) | | getUpdatesV2(options?) | 手动获取消息(V2) | | sendMessage(sessionInfo, msgContent) | 发送消息 | | getUploadURL(params) | 获取单文件上传地址 | | getMultiPartUploadURL(params) | 获取分片上传地址 | | completeMultipartUpload(params) | 完成分片上传 | | getAccessURL(params) | 获取文件下载地址 | | uploadFile(buffer, options) | 上传文件 | | sendMedia(sessionInfo, options) | 发送媒体消息 |

startPolling options

| 参数 | 类型 | 默认值 | 说明 | | -------------- | ------------------------ | ------ | ------------------------------ | | timeout | number | 30 | 长轮询超时时间(秒) | | limit | number | 100 | 每次拉取消息条数 | | retryDelay | number | 1000 | 重试延迟基础时间(毫秒) | | maxRetries | number | 0 | 最大重试次数(0 表示无限重试) | | onOffsetUpdate | (offset: number) => void | - | offset 更新回调 |

事件

| 事件 | 参数 | 说明 | | --------------- | -------------------------------------- | ---------- | | message | { message: MsgContent, quoteMsgMap } | 收到新消息 | | error | Error | 发生错误 | | polling_start | void | 轮询开始 | | polling_stop | void | 轮询停止 |

函数式 API

getUpdates(已废弃)

getUpdates(params: GetUpdatesParams): Promise<BotUpdate[]>

| 参数 | 类型 | 必填 | 默认值 | 说明 | | ------- | ------ | ---- | ------ | ----------------------- | | token | string | 是 | - | Bot Token | | baseUrl | string | 否 | - | API 地址 | | timeout | number | 否 | 0 | Long Polling 超时(秒) | | offset | number | 否 | 0 | 从该 seqId 之后获取 | | limit | number | 否 | 100 | 最大返回条数 |

getUpdatesV2(推荐)

getUpdatesV2(params: GetUpdatesV2Params): Promise<GetUpdatesV2Result>

| 参数 | 类型 | 必填 | 默认值 | 说明 | | ------- | ------ | ---- | ------ | ----------------------- | | token | string | 是 | - | Bot Token | | baseUrl | string | 否 | - | API 地址 | | timeout | number | 否 | 0 | Long Polling 超时(秒) | | limit | number | 否 | 100 | 最大返回条数 |

返回值:

interface GetUpdatesV2Result {
  msgs: { message: MsgContent }[]
  quoteMsgMap: Record<string, MsgContent> // key: "convID:seqID"
}

sendMessage

sendMessage(params: SendMessageParams): Promise<SendMessageResult>

| 参数 | 类型 | 必填 | 说明 | | ----------- | ----------- | ---- | --------- | | token | string | 是 | Bot Token | | baseUrl | string | 否 | API 地址 | | sessionInfo | SessionInfo | 是 | 会话信息 | | msgContent | MsgContent | 是 | 消息内容 |

媒体文件 API

getUploadURL

获取单文件上传签名地址。

getUploadURL(params): Promise<UploadURLResult>

| 参数 | 类型 | 必填 | 说明 | | -------------- | ------ | ---- | ---------------- | | token | string | 是 | Bot Token | | originFileName | string | 是 | 原始文件名 | | contentType | string | 是 | MIME 类型 | | md5 | string | 是 | 格式:md5_hash | | size | number | 是 | 文件大小(字节) |

getAccessURL

获取文件下载地址。

// 方式1:完整参数
getAccessURL({ token, firstId, secondId, sessionType, seqId, fileId })

// 方式2:使用 sessionInfo
getAccessURL({ token, sessionInfo, seqId, fileId })

uploadFile

上传文件(自动选择单文件或分片上传)。

uploadFile(token, buffer, { fileName, contentType, onProgress? })

sendMedia

发送媒体消息(上传并发送)。

sendMedia(token, sessionInfo, { buffer, fileName, contentType, content?, onProgress? })

工具函数

getConvID

生成会话 ID。

import { getConvID } from '@meet-im/meet-bot-jssdk'

const convID = getConvID(firstID, secondID, sessionType, companyID?)

| 会话类型 | convID 格式 | | -------- | -------------------------------------- | | 私聊 (1) | min:maxmin:max:companyID | | 群聊 (3) | firstID+secondID 或追加 +companyID | | 频道 | firstID_secondID 或追加 _companyID |

getQuoteMsgKey

生成引用消息的 key。

import { getQuoteMsgKey } from '@meet-im/meet-bot-jssdk'

const key = getQuoteMsgKey(convID, seqID) // "convID:seqID"

类型定义

type SessionType = 1 | 3 // 1: 私聊, 3: 群聊

interface SessionInfo {
  firstID: number
  secondID: number
  sessionType: SessionType
  companyID?: number
}

type MsgType = 'NORMAL' | 'RECALL' | 'QUOTE'

interface AttachmentInfo {
  fileID: string | number
  fileName?: string
  filePath?: string
  fileSize?: number
  mimeType?: string
  fileUrl?: string
}

interface ExtraInfo {
  msgType?: MsgType
  attechmentInfo?: AttachmentInfo // 单附件
  attechmentInfos?: AttachmentInfo[] // 多附件
  [key: string]: unknown
}

interface MsgContent {
  content: string
  seqId?: number
  timestamp?: number
  fromUid?: number
  atIds?: number[]
  quoteSeqID?: number // 引用消息 seqID
  extraInfo?: ExtraInfo
  sessionInfo?: SessionInfo
}

interface BotUpdate {
  message?: MsgContent
}

interface GetUpdatesV2Result {
  msgs: { message: MsgContent }[]
  quoteMsgMap: Record<string, MsgContent>
}

interface SendMessageResult {
  msgContent: MsgContent
  quoteMsg: unknown
  userProfileMap: Record<number, unknown>
}

错误处理

SDK 提供以下错误类型:

| 错误类 | 说明 | | ----------------- | -------------- | | MeetBotError | 基础错误类 | | ApiError | API 返回的错误 | | NetworkError | 网络连接错误 | | TimeoutError | 请求超时错误 | | ValidationError | 参数验证错误 |

import { ApiError, NetworkError } from '@meet-im/meet-bot-jssdk'

try {
  await bot.sendMessage(sessionInfo, { content: 'Hello' })
} catch (error) {
  if (error instanceof ApiError) {
    console.error('API 错误:', error.code, error.statusCode)
  } else if (error instanceof NetworkError) {
    console.error('网络错误:', error.message)
  }
}

开发

# 安装依赖
pnpm install

# 构建
pnpm build

# 测试
pnpm test

# 类型检查
pnpm typecheck

# 代码格式化
pnpm format

# 代码检查
pnpm lint

License

MIT