# @utoolkits/im-sdk

> ## 一 聊天室

Latest version **0.0.15** (published 2023-07-09) · 0 weekly downloads

## Install

```sh
npm install @utoolkits/im-sdk
pnpm add @utoolkits/im-sdk
yarn add @utoolkits/im-sdk
bun add @utoolkits/im-sdk
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.15 |
| Published | 2023-07-09 |
| First published | 2023-04-30 |
| Weekly downloads | 0 |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 7 |
| Unpacked size | 150.7 KB |
| Known vulnerabilities | 0 (+23 in 1 direct dependencies) |
| Install scripts | no |
| Maintainers | wang92 |

## Links

- npm: https://www.npmjs.com/package/@utoolkits/im-sdk
- npm.io page: https://npm.io/package/@utoolkits/im-sdk

## Dependencies (7)

- [ms](https://npm.io/package/ms.md) ^2.0.0
- [axios](https://npm.io/package/axios.md) ^0.27.2
- [fastscan](https://npm.io/package/fastscan.md) ^1.0.6
- [eventemitter3](https://npm.io/package/eventemitter3.md) ^4.0.7
- [current-device](https://npm.io/package/current-device.md) ^0.10.2
- [lodash.clonedeep](https://npm.io/package/lodash.clonedeep.md) ^4.5.0
- [@yxim/nim-web-sdk](https://npm.io/package/@yxim/nim-web-sdk.md) ^8.9.113

## Recent versions

- 0.0.15 (latest) — 2023-07-09
- 0.0.14 — 2023-07-03
- 0.0.13 — 2023-06-29
- 0.0.12 — 2023-06-26
- 0.0.11 — 2023-06-14
- 0.0.10 — 2023-06-14
- 0.0.9 — 2023-05-21
- 0.0.8 — 2023-05-21
- 0.0.7 — 2023-05-20
- 0.0.6 — 2023-05-20
- 0.0.5 — 2023-05-12
- 0.0.4 — 2023-05-11
- 0.0.3 — 2023-05-04
- 0.0.2 — 2023-05-01
- 0.0.1 — 2023-04-30

## README

# IM-SDK

## 一 聊天室

### 1. 安装

```shell
yarn add @utoolkits/im-sdk
```

### 2. 初始化

```ts
import IMSDK from '@utoolkits/im-sdk';
const [error, chatroom] = await IMSDk.Chatroom.initialize({
  debug: true, // 打印日志，通常开发环境开启
  env: 'test', // 当前环境变量
  liveRoomId: '4454', // 直播房间ID
  token: userinfo.token, // 登录Token
  chatroomNick: '', // 昵称
  chatroomAvatar: '', // 头像
  tags: [], // 用户标签-助教端登录必须传入 assistant
});
```

### 3. 功能

- 登录 ✅
- 查询聊天室信息 ✅
- 修改聊天室信息 ✅
- 查询成员列表 ✅
- 查询全部历史消息 ✅
- 分页查询历史消息 ✅
- 进入聊天室 ✅
- 离开聊天室 ✅
- 发送文本消息 ✅
- 发送文件消息 ✅
- 接收聊天室消息 ✅
- 聊天室禁言 (调用服务端接口) ✅
- 单个禁言 ✅
- 踢出(发、收) ✅
- 更新学员备注 (调用服务端接口) ✅
- 拉黑 (自定义消息) ✅
- 取消拉黑 (自定义消息) ✅
- 查询直播间拉黑列表 ✅
- 上报观看时长 (调用服务端接口) ✅
- 删除聊天消息 (删除聊天消息) ✅
- 切换聊天室 ✅

#### 3.1 登录

```ts
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 查询聊天室信息

- 发送请求

```ts
const [error, obj] = await chatroom.getChatroom();
if (!error) {
  console.log(obj);
}
```

- 响应结果:

```ts
{
  "id": "2302150639",
  "name": "公告更新", // 公告名称
  "announcement": "公告更新测试",  // 公告内容
  "custom": "",
  "createTime": 1663321877624,
  "updateTime": 1663741386352,
  "queuelevel": "1",
  "creator": "0",
  "onlineMemberNum": 3, // 在线人数
  "mute": false, // 聊天室禁言中，只有管理人员可以发消息
  "broadcastUrl": ""
}
```

#### 3.3 修改聊天室信息

- 请求

```ts
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, 表示公告修改不通知聊天室其它人. 反之通知 |

- 响应结果

```ts
// obj 对应内容
{
    "chatroom": {
        "name": "公告更新",
        "announcement": "公告更新测试"
    },
    "needNotify": true,
    "custom": "{\"announcement\":\"公告更新测试\"}",
    "antispamTag": {}
}
```

- 学员端监听公告更新

```ts
// 聊天室信息更新
chatroom.addListener(Chatroom.EVENTS.updateChatroom, function (res) {
  console.log('updateChatroom', res);
});
```

接收到 `res` 内容如下:

```json
{ "announcement": "公告更新测试", "chatroomId": "4139878055" }
```

#### 3.4 查询全量成员列表

- 请求

```ts
const members = await chatroom.getAllChatroomMembers();
console.log(members);
```

- 响应

```json
[
  {
    "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 查询全部历史消息

- 请求

```ts
chatroom
  .getAllHistoryMsgs({
    msgTypes: [], //可选, 默认值 [text、video、file、image、audio、geo、custom]，需要其他可以看下面云信消息列表
    customMsgSubTypes: [], // 可选 默认值为 []，也就是返回全部自定义消息。例如只要机器人消息，可以传递 [IMSDk.Chatroom.EVENTS.robotMessage],
    notificationMsgSubTypes: [], // 可选，默认值为 [], 用于过滤通知子类型消息，注意⚠️，默认情况下 msgTypes 不包含通知消息的
  })
  .then((res: any) => {
    history.value = res;
  });
```

- 响应

```json
[
  {
    "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.6 分页查询历史消息

- 请求

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

- 参数

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

#### 3.7 进入聊天室

```ts
// 成员进入
/**
 * {
 * userId: "账号",
 * }
 */
chatroom.addListener(Chatroom.EVENTS.join, function (res) {
  console.log('join', res);
  message.info(`[${res.attach.fromNick}] 进入聊天室`);
});
```

#### 3.8 离开聊天室

```ts
// 离开聊天
/**
 * {
 * userId: "账号",
 * }
 */
chatroom.addListener(Chatroom.EVENTS.exit, function (res) {
  console.log('exit', res);
  message.info(`[${res.attach.fromNick}] 离开聊天室`);
});
```

#### 3.9 发送文本消息

##### 3.9.1 云信发送文本消息

```ts
const handleSend = async () => {
  const [error, msg] = await chatroom.sendText({
    text: content.value,
    custom: JSON.stringify({}), // 助教端使用的扩展字段
  });
  if (error === null) {
    message.success('发送成功');
    content.value = '';
  }
};
```

##### 3.9.2 内部发送文本消息

```ts
// C端发送消息
const handleSend = async () => {
  const [error, msg] = await chatroom.sendInnerMsg(content.value);
  if (error === null) {
    message.success('发送成功');
    content.value = '';
  }
};

// 助教端将接收审核消息,
chatroom.addListener(Chatroom.EVENTS.audit, function (data) {
  /**
   * 把消息加入审核消息列表中
   */
});

// 当审核通过后，其它助教端将接收审核通过
chatroom.addListener(Chatroom.EVENTS.pass, function () {
  // 把消息从审核消息列表中
});

// 当审核拒绝后，其它助教端接收审核拒绝
chatroom.addListener(Chatroom.EVENTS.reject, function () {
  // 把消息从审核消息列表中
});

// 审核通过后，C端将接收上屏消息
chatroom.addListener(Chatroom.EVENTS.userSpeech, function (res) {
  console.log('userSpeech message', res);
  history.value.push(res);
});
```

#### 3.10 发送文件消息

```html
<input id="test" type="file" />
```

```ts
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) => {},
  custom: JSON.stringify({
    userId: '',
  }), // 扩展字段
});
```

#### 3.11 发送自定义消息

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

#### 3.12 接收聊天室消息

#### 3.12.1 云信消息分类

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

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

#### 3.12.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（机器人消息） |

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

#### 3.12.3 接收普通消息

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

#### 3.13 聊天室禁言

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

#### 3.14 单禁言

```ts
const [error, obj] = chatroom.mute({
  userId: '****',
});
if (error === null) {
  console.log('禁言');
}

const [error, obj] = chatroom.unMute({
  userId: '****',
});
if (error === null) {
  console.log('取消禁言');
}

// 禁言
chatroom.addListener(Chatroom.EVENTS.mute, function () {});
// 移除禁言
chatroom.addListener(Chatroom.EVENTS.unMute, function () {});
```

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

```ts
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.17 拉黑

- 请求

```js
const [error, result] = chatroom.black({
  userId: '',
});
```

- 响应

```json
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}
```

#### 3.18 取消拉黑

- 请求

```js
const [error, result] = chatroom.unblack({
  userId: '',
});
```

- 响应

```json
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}
```

#### 3.19 聊天室禁言

- 请求

```js
const [error, result] = await chatroom.muteRoom({
  isMute: true, // 禁言: true  取消禁言: false
});
console.log(error, result);

chatroom.addListener(Chatroom.EVENTS.muteRoom, function (res) {
  console.log(res); // {avatar: '', nickname: '我是最新的管理员哦', userId: '6', chatroomId: '4139878055'}
  message.info('聊天室禁言');
});

chatroom.addListener(Chatroom.EVENTS.unmuteRoom, function (res) {
  console.log(res); // {avatar: '', nickname: '我是最新的管理员哦', userId: '6', chatroomId: '4139878055'}
  message.info('聊天室解除禁言');
});
```

- 响应

```json
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}
```

#### 3.20 上报观看时长

- 请求

```js
const [error, result] = await chatroom.reportWatchTime();
```

- 响应

```json
{
  "code": "SUCCESS",
  "message": "操作成功",
  "traceId": "",
  "data": true
}
```

#### 3.21 删除聊天消息

```js
// 撤回消息
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); // 消息ID
  }
);
```

#### 3.22 切换聊天室

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

## 二 私聊

### 1. 初始化

- env 环境变量
- token 登录凭证

```js
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

```js
const [error, session] = await im.insertLocalSession({
  to: id, // 用户ID
});
```

### 3. 删除本地会话

- `sessionId` 会话 ID

```js
const [error, session] = im.deleteLocalSession(sessionId);
```

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

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

### 5. 切换会话

#### 5.1 设置当前会话

- 如果是已经存在的会话记录, 会将此会话未读数置为 0, 开发者会收到 onupdatesession 回调
- 之后此会话在收到消息之后不会更新未读数

```js
im.setCurrSession('sessionid');
```

#### 5.2 重置会话未读数

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

```js
im.resetCurrSession();
```

### 6. 获取会话历史消息

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

#### 响应

```json
[
  {
    "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. 分页查询历史消息

查询分页消息时，需要传入两个参数 `lastMsgId`、`endTime` 或 `beginTime`，具体传入 `endTime` 或 `beginTime`, 取决于传入的 `reverse`.

- reverse: false (默认)

```js
lastMsgId: item.idServer;
endTime: item.time;
```

- reverse: true

```js
lastMsgId: item.idServer;
endTime: item.time;
```

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

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

### 8. 发送消息

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

### 9. 发送图片

```js
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. 未读消息

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

### 11. 更新备注

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

### 12. 获取用户详情

```js
const [error, result] = await im.getUserInfo({
  userId: '', // 用户ID
});
```

- 响应

```json
{
  "speakCount": 0,
  "viewDuration": 0,
  "nickName": ""
}
```

### 13. 注销

```js
im.destroy();
```

---
_Source: https://npm.io/package/@utoolkits/im-sdk · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
