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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@msbfe/im-sdk

v0.0.31

Published

## 一 聊天室

Downloads

12

Readme

IM-SDK

一 聊天室

1. 安装

yarn add @msbfe/im-sdk

2. 初始化

import IMSDK from '@msbfe/im-sdk';
const [error, chatroom] = await IMSDk.Chatroom.initialize({
  debug: true,
  env: 'test',
  sectionId: '4454',
  token: userinfo.token, // 登录 Token
  chatroomNick: '', // 昵称
  chatroomAvatar: '', // 头像
  tags: [], // 用户标签-助教端登录必须传入 assistant
  forbiddenWordCheckedEnable: true, // 客户端开启严禁词检查,可选,默认值 true
  chatroomEnterCustom: JSON.stringify({
    avatar: 'https://joeschmoe.io/api/v1/random',
  }),
});

3. 功能

  • 登录 ✅
  • 查询聊天室信息 ✅
  • 修改聊天室信息 ✅
  • 查询成员列表 ✅
  • 分页获取成员列表 ✅
  • 查询全部历史消息 ✅
  • 分页查询历史消息 ✅
  • 进入聊天室 ✅
  • 离开聊天室 ✅
  • 发送文本消息 ✅
  • 发送文件消息 ✅
  • 接收聊天室消息 ✅
  • 聊天室禁言 (调用服务端接口) ✅
  • 单个禁言 ✅
  • 临时禁言 ✅
  • 踢出(发、收) ✅
  • 更新学员备注 (调用服务端接口) ✅
  • 拉黑 (自定义消息) ✅
  • 取消拉黑 (自定义消息) ✅
  • 根据课程查询拉黑列表 ✅
  • 上报观看时长 (调用服务端接口) ✅
  • 记录发言次数 (调用服务端接口) ✅
  • 删除聊天消息 (删除聊天消息) ✅
  • 切换聊天室 ✅
  • 触发敏感检查 ✅
  • 获取成员信息 ✅
  • 开启连麦 ✅
  • 关闭连麦 ✅
  • 连麦列表更新 ✅

3.1 登录

const [error, chatroom] = await IMSDk.Chatroom.initialize({
  debug: true,
  env: 'test',
  sectionId: '4454',
  token: userinfo.token, // 登录 Token
  chatroomNick: '', // 昵称
  chatroomAvatar: '', // 头像
  tags: [], // 用户标签-助教端登录必须传入 assistant
  chatroomEnterCustom: JSON.stringify({
    avatar: 'https://joeschmoe.io/api/v1/random',
  }),
});

3.2 查询聊天室信息

  • 发送请求
const [error, obj] = await chatroom.getChatroom();
if (!error) {
  console.log(obj);
}
  • 响应结果:
{
  "id": "2302150639",
  "name": "公告更新", // 公告名称
  "announcement": "公告更新测试",  // 公告内容
  "custom": "",
  "createTime": 1663321877624,
  "updateTime": 1663741386352,
  "queuelevel": "1",
  "creator": "0",
  "onlineMemberNum": 3, // 在线人数
  "mute": false, // 聊天室禁言中,只有管理人员可以发消息
  "broadcastUrl": ""
}

3.3 修改聊天室信息

  • 请求
const [error, obj] = await chatroom.updateChatroom({
  chatroom: {
    name: '公告更新',
    announcement: '公告更新测试',
  },
  custom: JSON.stringify({
    announcement: '公告更新测试',
  }),
  needNotify: true,
});
if (error === null) {
  message.success('修改聊天室信息成功');
}
  • 参数

| 参数 | 默认值 | 描述 | | ------------ | ------ | ------------------------------------------------------ | | name | "" | 公告名称 | | announcement | "" | 公告内容 | | custom | "" | 扩展字段 | | needNotify | false | 默认为 false, 表示公告修改不通知聊天室其它人. 反之通知 |

  • 响应结果
// obj 对应内容
{
  announcement: "公告更新测试",
  chatroomId: ""
}
  • 学员端监听公告更新
// 聊天室信息更新
chatroom.addListener(Chatroom.EVENTS.updateChatroom, function (res) {
  console.log('updateChatroom', res);
});

接收到 res 内容如下:

{
  "chatroomId": "2302150639",
  "idClient": "102baa94-ef75-48bb-ad83-8d0d888ef5a2",
  "from": "1",
  "fromCustom": "",
  "fromClientType": "Web",
  "time": 1663762645958,
  "type": "notification",
  "text": "",
  "resend": false,
  "status": "success",
  "attach": {
    "type": "updateChatroom",
    "from": "1",
    "fromNick": "管理员1",
    "custom": "{\"announcement\":\"公告更新测试\"}"
  },
  "flow": "in"
}

3.4 查询成员列表

  • 请求
const members = await chatroom.getAllChatroomMembers();
console.log(members);
  • 响应
[
  {
    "roomId": "2302150639", // 房间号
    "accId": "6", // 账号
    "type": "manager", // 类型 owner 房主 、manager 管理员、restricted 受限制(被拉黑或禁言) 、common 普通用户、guest 游客
    "nick": "修改成员", // 昵称
    "avatar": "https://ksimage.mashibing.com/132643d814514734bf0d5e4eb63e0e63.jpg", // 头像
    "ext": "cunstom info",
    "isOnline": true, // 在线状态
    "enterTime": 1663848190608, // 进入时间
    "isBlacklisted": false, // 黑名单
    "isMuted": false, // 禁言
    "isTempMuted": false, // 临时禁言
    "tempMuteTtl": 0, // 临时禁言时长(单位秒)
    "isRobot": false, // 是否是聊天机器人
    "isRobotExpireAt": 0 // 机器人失效的时长
  }
]

3.5 分页获取成员列表

  const [error, members] = await chatroom.getChatroomMembers({
    guest = false,
    limit = 100,
    time = 0,
  }
  if(error!=null) {
    console.log(members)
  }

| 参数 | 默认值 | 描述 | | ----- | ------ | ---------------------------------------------------------------------------------- | | guest | false | 只查询固定用户(非游客) | | limit | 100 | 查询数量 | | time | 0 | 默认 0 代表当前服务器时间,获取固定用户传入 updateTime,获取游客用户传入 enterTime |

3.6 查询全部历史消息

  • 请求
chatroom
  .getAllHistoryMsgs({
    msgTypes: [], //可选, 默认值 [text、video、file、image、audio、geo、custom],需要其他可以看下面云信消息列表
    customMsgSubTypes: [], // 可选 默认值为 [],也就是返回全部自定义消息。例如只要机器人消息,可以传递 [IMSDk.Chatroom.EVENTS.robotMessage],
    notificationMsgSubTypes: [], // 可选,默认值为 [], 用于过滤通知子类型消息,注意⚠️,默认情况下 msgTypes 不包含通知消息的
  })
  .then((res: any) => {
    history.value = res;
  });
  • 响应
[
  {
    "chatroomId": "2302150639",
    "idClient": "b82d4114588d6efb89e47f2b85b82393",
    "from": "6",
    "fromNick": "修改成员",
    "fromAvatar": "https://ksimage.mashibing.com/132643d814514734bf0d5e4eb63e0e63.jpg",
    "fromCustom": "cunstom info",
    "userUpdateTime": 1663839160317,
    "fromClientType": "Web",
    "time": 1663839167099,
    "type": "image",
    "text": "",
    "resend": false,
    "status": "success",
    "file": {
      "w": 432,
      "h": 363,
      "type": "PNG",
      "size": 51512,
      "url": "https://nim-nosdn.netease.im/MjYxNzY0Mjk=/bmltYV8xMDg1MTQyNjQzMzZfMTY2MzgzOTE2NjYzN18xYWQwZTQ5MS0yNGNkLTQzYzgtODhiOC1iNjBjMDE4YjZjOTE=?createTime=1663839167053",
      "name": "截屏2022-09-21 16.54.48.png",
      "ext": "png"
    },
    "flow": "out"
  },
  {
    "chatroomId": "2302150639",
    "idClient": "10a0d302-a093-4365-a906-113596ad1249",
    "from": "0",
    "fromNick": "管理员",
    "fromAvatar": "https://ksimage.mashibing.com/132643d814514734bf0d5e4eb63e0e63.jpg",
    "custom": "扩展信息",
    "fromClientType": "Server",
    "time": 1663828031926,
    "type": "text",
    "text": "这是发送的消息",
    "resend": false,
    "status": "success",
    "flow": "in"
  },
  {
    "chatroomId": "2302150639",
    "idClient": "7b7daf5d-2be7-4c2f-a228-5007c91700c0",
    "from": "1",
    "fromCustom": "",
    "fromClientType": "Web",
    "time": 1663818559398,
    "type": "notification",
    "text": "",
    "resend": false,
    "status": "success",
    "attach": {
      "type": "kickMember",
      "from": "1",
      "fromNick": "管理员1",
      "to": ["3"],
      "toNick": ["用户3"]
    },
    "flow": "in"
  }
]

3.7 分页查询历史消息

  • 请求
chatroom.getHistoryMsgs({
  timetag = Date.now(), // 默认值
  limit = 100, // 查询条数
  msgTypes = [], // 查询指定类型的消息
});
  • 参数

| 参数 | 默认值 | 描述 | | -------- | ------ | ------------------------------------------- | | timetag | false | 获取从 timetag 对应的时间点往前的若干条数据 | | limit | 100 | 查询数量 | | msgTypes | [] | 可选历史消息类型,默认为即获取全部消息类型 |

3.8 进入聊天室

// 成员进入
chatroom.addListener(Chatroom.EVENTS.memberEnter, function (res) {
  console.log('memberEnter', res);
  message.info(`[${res.attach.fromNick}] 进入聊天室`);
});

3.9 离开聊天室

// 离开聊天
chatroom.addListener(Chatroom.EVENTS.memberExit, function (res) {
  console.log('memberExit', res);
  message.info(`[${res.attach.fromNick}] 离开聊天室`);
});

3.10 发送文本消息

const handleSend = async () => {
  const [error, msg] = await chatroom.sendText(content.value);
  if (error === null) {
    message.success('发送成功');
    content.value = '';
  }
};

3.11 发送文件消息

<input id="test" type="file" />
chatroom.sendFile({
  type: "image", // "image" | "audio" | "video" | "file";
  fileInput: document.getElementById('test'), // blob | HTMLInputElement | base64
  uploadprogress: (obj) => {},
  uploaddone: (error, file) => {},
  beforesend: (msg) => {},
  done: (error, msg) => {};
});

3.12 发送自定义消息

chatroom.sendCustomMsg({
  type: 'hyperLinks', // 超链接
  data: {
    title: '',
    subtitle: '',
    href: '',
  },
});

3.13 接收聊天室消息

3.13.1 云信消息分类

| 事件名称 | 描述 | | ------------ | ------ | | text | 文本 | | video | 视频 | | file | 视频 | | image | 视频 | | audio | 音频 | | geo | 未知 | | custom | 自定义 | | notification | 通知类 |

根据业务需要把消息按类型进行划分。

3.13.2 基于云信的消息,再划分成 4 类

| 事件名称 | 描述 | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | normal | 普通消息(text、image、audio、video、file、geo) | | tip | 提醒消息(如进入会话时出现的欢迎消息,或者会话命中敏感词后的提示消息等等) | | notification | 通知消息(memberEnter(进入)、memberExit(离开)、gagMember(成员禁言)、ungagMember(成员解除禁言)、updateChatroom(聊天室信息更新)、addTempMute(临时禁言)、removeTempMute(移除临时禁言)、muteRoom(聊天室禁言)、unmuteRoom(移除聊天室禁言)) | | custom | 自定义 normal (正常消息)、loginSuccess(登录成功)、loginFail(登录失败)、black(拉黑)、unblack(取消拉黑)、updateRemark(更新备注)、liveStart(直播开始)、liveEnd(直播结束) 、kicked(被踢出)、error(错误) 、reconnect(重连) 、memberIn(进入)、memberOut(离开)、 robotMessage(机器人消息)、openCall(打开连麦)、closeCall(关闭连麦)、callStatusUpdate(连麦状态更新) |

禁言分为三种模式: 聊天室禁言成员禁言成员临时禁言

3.13.3 接收普通消息

chatroom.addListener(Chatroom.EVENTS.normal, function (msg) {});
chatroom.addListener(Chatroom.EVENTS.tip, function (msg) {});

3.14 聊天室禁言

chatroom.addListener(Chatroom.EVENTS.muteRoom, function (msg) {}); // 聊天室被禁言
chatroom.addListener(Chatroom.EVENTS.unmuteRoom, function (msg) {}); // 聊天室解除禁言

3.15 单禁言

const [error, obj] = chatroom.markChatroomGaglist({
  account: '****',
  isAdd: true, // 添加禁言:true、移除禁言:false
});
if (error === null) {
  console.log('禁言|取消禁言成功');
}

// 禁言
chatroom.addListener(Chatroom.EVENTS.gagMember, function () {});
// 移除禁言
chatroom.addListener(Chatroom.EVENTS.ungagMember, function () {});

3.16 临时禁言

const [error, obj] = chatroom.updateChatroomMemberTempMute({
  account: '****',
  duration: 1000, // 禁言时长: 单位为秒 移除禁言:0
  needNotify: true, // 禁言:true、移除禁言:false
  custom: '', // 对应消息的扩展字段
});

if (error === null) {
  console.log('禁言|取消禁言成功');
}
// 禁言
chatroom.addListener(Chatroom.EVENTS.addTempMute, function () {});
// 移除禁言
chatroom.addListener(Chatroom.EVENTS.removeTempMute, function () {});

3.17 踢出 (聊天室中踢出,刷新还可以继续进入,状态是瞬时的)

const handlekickChatroomMember = async () => {
  const [error, result] = await chatroom.kickChatroomMember({
    account: '3',
  });
  console.log(error, result); //  {account: '3', custom: ''}
};

// 学员端监听踢出消息
chatroom.addListener(Chatroom.EVENTS.kicked, function (res) {
  message.error(res.message);
});

3.18 更新备注

  • 请求
const [error, result] = await chatroom.updateRemark({
  courseId: 44,
  userId: 'user_00000068',
  nickName: '测试',
});
console.log(error, result);
  • 响应
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}

3.19 拉黑

  • 请求
const [error, result] = chatroom.black({
  courseId: '',
  userId: '',
});
  • 响应
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}

3.20 取消拉黑

  • 请求
const [error, result] = chatroom.unblack({
  courseId: '',
  userId: '',
});
  • 响应
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}

3.21 根据课程查询拉黑列表

3.21.1 支持分页
  • 请求
const [error, result] = chatroom.queryBlackList({
  courseId: '41',
  length: 10,
  pageIndex: 1,
});
  • 响应
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": {
    "current": 1,
    "pages": 10,
    "records": [],
    "size": 10,
    "total": 100
  }
}
3.21.2 查询全量
  • 请求
const [error, result] = chatroom.queryAllBlackList({
  courseId: '41',
});
  • 响应
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": [
    {
      "blacklistedTime": "",
      "blacklistedUser": "",
      "blacklistedUserRealName": "",
      "courseId": 0,
      "id": 0,
      "userId": "",
      "userNickname": "",
      "wechatNickname": ""
    }
  ]
}

3.22 聊天室禁言

  • 请求
const [error, result] = await chatroom.muteRoom({
  mute: true, // 禁言: true  取消禁言: false
});
console.log(error, result);
  • 响应
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}

3.23 上报观看时长

  • 请求
const [error, result] = await chatroom.reportWatchTime();
  • 响应
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}

3.24 记录发言次数

  • 请求
const [error, result] = await chatroom.reportStatementsNum({ count: 1 });
  • 响应
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}

3.25 删除聊天消息

// 撤回消息
const recall = async () => {
  const [error, res] = await chatroom.recall({
    fromUserId: 'user_00000068',
    msgId: 'd39f037bb2c6ae35add99877a475b43d',
    msgTimeTag: 1664347261676,
  });
  console.log(error, res);
};

// 监听删除消息回调
chatroom.addListener(
  Chatroom.EVENTS.deleteChatroomMsg,
  function ({ idClient }) {
    console.log(idClient);
  }
);

3.26 切换聊天室

// 先销毁
chatroom.destroy();
// 重新执行初始化
IMSDk.Chatroom.initialize({
  ...
})

3.27 触发敏感检查

const handleSend = async () => {
  const [error, msg] = await chatroom.sendText('草');
  if (error === null) {
    message.success('发送成功');
    content.value = '';
  } else {
    console.log(error); // { code: "hasForbidden", message: "聊天内容包含敏感词" },
  }
};

3.28 设置聊天室普通成员

const [error, result] = await chatroom.markChatroomCommonMember({
  account: '13305',
});

3.29 获取成员信息

  • 请求
const getChatroomMembersInfo = async () => {
  const [error, result] = await chatroom.getChatroomMembersInfo({
    accounts: ['42909'],
  });
  console.log(error, result);
};
  • 响应
 {
  accounts: ['42909'],
  members: [
    {
      "type": "common",
      "roomId": "2457143158",
      "nick": "Nets",
      "accId": "42909",
      "avatar": "http://ksimage.mashibing.com/132643d814514734bf0d5e4eb63e0e63.jpg",
      "enterTime": 1665403446414,
      "isBlacklisted": false,
      "isMuted": false,
      "ext": {
          "banChat": 0,
          "blacklisted": 0,
          "globalSpeakCount": 43,
          "globalViewDuration": 257,
          "inTime": 1665403511595,
          "nickName": "应届生  21 对Java感兴趣的",
          "phone": "13055199735",
          "role": 0,
          "saleTeacherBzId": "32767",
          "saleTeacherNickName": "栀晓",
          "source": 1
      },
      "isOnline": true,
      "isRobot": false,
      "isTempMuted": false
    }
  ]
 }

二 私聊

1. 初始化

  • env 环境变量
  • token 登录凭证
import IMSDK from '@msbfe/im-sdk';
const [error, im] = await IMSDk.NIM.initialize({
  env: 'test',
  token: userinfo.token,
});

if (!error) {
  // im 创建成功
  im.addListener(IMSDK.NIM.EVENTS.connect, () => {
    console.log('登录成功');
  });
  // 监听会话列表更新
  im.addListener(IMSDK.NIM.EVENTS.updateSessions, (arr: Session[]) => {
    console.log('会话更新', sessions);
    sessions.value = arr;
  });
} else {
  console.log(error);
}

2. 创建本地会话

  • to 聊天对象, 账号或群 ID
const [error, session] = await im.insertLocalSession({
  to: id, // 用户ID
});

3. 删除本地会话

  • sessionId 会话 ID
const [error, session] = im.deleteLocalSession(sessionId);

4. 同时删除本地和服务端会话

const [error, session] = im.syncDeleteSession({
  sessionId: item.id,
  to: item.to,
});

5. 切换会话

5.1 设置当前会话

  • 如果是已经存在的会话记录, 会将此会话未读数置为 0, 开发者会收到 onupdatesession 回调
  • 之后此会话在收到消息之后不会更新未读数
im.setCurrSession('sessionid');

5.2 重置会话未读数

  • 如果是已经存在的会话记录, 会将此会话未读数置为 0, 那么会收到 onupdatesession 回调
  • 之后此会话在收到消息之后依然会更新未读数
im.resetCurrSession();

6. 获取会话历史消息

const [error, result] = await im.getMsgs({
  scene: 'p2p', // 点对点
  to: item.to, //
  limit: 10, // 限制条数
});

响应

[
  {
    "id": "p2p-13187", // 会话ID
    "scene": "p2p", // 会话场景
    "to": "13187", // 用户ID
    "updateTime": 1666267793516, // 会话更新时间
    // 会话最近一条消息
    "lastMsg": {
      "scene": "p2p",
      "from": "13305",
      "fromNick": "Nets",
      "fromClientType": "Web",
      "fromDeviceId": "a018a1f6f66044b5ed3d392b31acb209",
      "to": "13187",
      "time": 1666267793516,
      "type": "text",
      "text": "121212121212122323",
      "isHistoryable": true,
      "isRoamingable": true,
      "isSyncable": true,
      "cc": true,
      "isPushable": true,
      "isOfflinable": true,
      "isUnreadable": true,
      "isReplyMsg": true,
      "needPushNick": true,
      "needMsgReceipt": false,
      "isLocal": false,
      "resend": false,
      "idClient": "640077c0b7976f0b7cd394990fe6dc91",
      "userUpdateTime": 1663925973486,
      "status": "success",
      "target": "13187",
      "sessionId": "p2p-13187",
      "flow": "out",
      "idServer": "4379177879259"
    },
    "unread": 0, // 未读消息
    "nick": "邓澎波", // 聊天对象昵称
    "avatar": "https://oss-cdn.mashibing.cn/user/afca7d8dbd2a375b7a1f3765b4fee370.jpg" // 聊天对象头像
  }
]

7. 分页查询历史消息

查询分页消息时,需要传入两个参数 lastMsgIdendTimebeginTime,具体传入 endTimebeginTime, 取决于传入的 reverse.

  • reverse: false (默认)
lastMsgId: item.idServer;
endTime: item.time;
  • reverse: true
lastMsgId: item.idServer;
endTime: item.time;

根据前面返回值,案例如下:

const [error, result] = await im.getMsgs({
  scene: 'p2p', // 点对点
  to: item.to, // 用户
  limit: 10, // 限制条数
  lastMsgId: 4379177879259, // 消息 idServer
  time: 1666267793516, // 消息时间 time
});

8. 发送消息

// 发送消息之前消息具柄
const msg = im.sendText({
  to: 'userNo',
  text: imContent.value,
  done: (error, msg) => {
    if (!error) {
      history.value.unshift(msg);
    }
  },
});

9. 发送图片

const input = document.querySelector('#input');
im.sendFile({
  to: accid,
  fileInput: input,
  beginupload(upload) {
    // 通过这个 upload 对象来中断上传  upload.abort()
  },
  uploadprogress(obj) {
    console.log(obj);
  },
  beforesend(obj) {},
  uploaddone(error, file) {},
  done(error, msg) {
    console.log(error, msg);
  },
});

10. 未读消息

const unread = computed(() => {
  return sessions.value.reduce((prev, current) => {
    prev += current.unread;
    return prev;
  }, 0);
});

11. 更新备注

const [error, result] = await im.updateRemark({
  courseId: '', // 课程ID
  userId: '', // 用户ID
  nickName: '', // 昵称(可选)
  label: '', // 用户标签(可选)
});

12. 获取用户详情

const [error, result] = await im.getUserInfo({
  userId: '', // 用户ID
});
  • 响应
{
  "speakCount": 0,
  "viewDuration": 0,
  "nickName": ""
}

13. 注销

im.destroy();