im_plugin_tencent_web

A Flutter plugin that inherits from Tencent IM

聊天互动使用:@tencentcloud/lite-chat (无UI)进行集成

音视频通话使用:TUICallEngine (无UI)进行集成


预览示例

如果您或您的公司有现成可用的 腾讯IM 即时通讯 服务, 那么您可以点击下面的示例去看看效果。

使用 腾讯IM 即时通讯 的相关参数 登录后就能看到效果啦 🤩🤩🤩🤪

放心登录,这只是示例项目,不会记录任何您的个人资料信息,我保证 😁

👉 点击去查看示例效果


使用前准备

第一步

引入插件包

dependencies:
  im_plugin_tencent_web: 最新版本号

// 通过命令
flutter pub add im_plugin_tencent_web

第二步

下载并复制以下文件到项目的 web 目录下

im_plugin.bundle.js

第三步

在 web/index.html 的 head之间添加下面的代码

<script src="im_plugin.bundle.js" defer></script>

开始使用

共有两种使用方式(选择你需要的方式就可以)

仅 API 调用的方式

初始化IM

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';
import 'package:im_plugin_tencent_web/im/event_chat_listener_config.dart';
import 'package:im_plugin_tencent_web/im/event_call_listener_config.dart';

ImPluginTencentWeb.initSdk(
  sdkAppID: 0,
  initCall: true, // 是否同时初始化 im Call,默认 true
  eventChatListener: EventChatListenerConfig(),
  eventCallListener: EventCallListenerConfig(), // initCall 为 false 时,可以忽略
);

chat 可传入的事件列表

call 可传入的事件列表

登录IM

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    await ImPluginTencentWeb.login(
        userID: '',
        userSig: '',
    );
} catch(err) {
    print('登录出错:$err');
}

登出IM

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    await ImPluginTencentWeb.logout();
} catch(err) {
  print('登出出错:$err');
}

销毁IM

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    await ImPluginTencentWeb.destroy();
} catch(err) {
  print('销毁出错:$err');
}

查询自己的资料

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.getMyProfile();
} catch(err) {
  print('查询自己的资料出错:$err');
}

查询其他用户资料

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.getUserProfile(List<String> userIdList);
} catch(err) {
  print('查询其他用户资料出错:$err');
}

更新个人资料

官方文档

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.updateMyProfile(Map<String, dynamic> options);
} catch(err) {
  print('更新个人资料出错:$err');
}

获取会话列表

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';
import 'package:im_plugin_tencent_web/model/conversation_item_entity.dart';

try {
    final res = await ImPluginTencentWeb.getConversationList();
    List<dynamic> list = res['conversationList'];
    List<MessageItemEntity> getConversationList = list.map((item) => ConversationItemEntity.fromJson(item)).toList();
} catch(err) {
  print('获取会话列表出错:$err');
}

清空会话未读消息数

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

ImPluginTencentWeb.setMessageRead({
    required String conversationID // 会话ID
});

拉取消息列表

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';
import 'package:im_plugin_tencent_web/model/message_item_entity.dart';

try {
    final res = await ImPluginTencentWeb.getMessageList({
      required String conversationID, // 会话ID
      String? nextReqMessageID // 拉取下一页时传入。传入上一次请求拿到的 nextReqMessageID
    });

    List<dynamic> messageList = res['messageList'];
    String nextReqMessageID = res['nextReqMessageID'];
    List<MessageItemEntity> getMsgList = messageList.map((item) => MessageItemEntity.fromJson(item)).toList();
} catch(err) {
  print('拉取消息列表出错:$err');
}

发送消息

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';
import 'package:im_plugin_tencent_web/im/create_msg_info.dart';
import 'package:im_plugin_tencent_web/model/message_item_entity.dart';

try {
    final res = await ImPluginTencentWeb.sendMessage({
      required CreateMsgType createMsgType, // 发送消息的类型
      required CreateMsgInfo createMsgInfo, // 发送消息的数据构造
      Map<String, dynamic>? options // 发送消息的配置参数
    });

    Map<String, dynamic> msg = Map<String, dynamic>.from(res['message']);
    MessageItemEntity messageInfo = MessageItemEntity.fromJson(msg);
} catch(err) {
  print('发送消息出错:$err');
}

创建消息参考

拨打音视频通话

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.call({
      required CallType callType,
      required List<String> userIdList, // 邀请列表
      String? chatGroupId, // IM 群组 / 会话 ID
      String? roomId, // 房间号
      String? userData, // 扩展字段: 用于在邀请信令中增加扩展信息
      Map<String, dynamic>? offlinePushInfo
    });
} catch(err) {
  print('拨打音视频通话出错:$err');
}

接听通话邀请

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.acceptCall();
} catch(err) {
  print('接听通话邀请出错:$err');
}

拒绝通话邀请

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.rejectCall();
} catch(err) {
  print('拒绝通话邀请出错:$err');
}

主动加入通话

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.joinCall(String callId);
} catch(err) {
  print('主动加入通话出错:$err');
}

挂断通话

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.hangup();
} catch(err) {
  print('挂断通话出错:$err');
}

打开麦克风

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.openMicrophone();
} catch(err) {
  print('打开麦克风出错:$err');
}

关闭麦克风

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.closeMicrophone();
} catch(err) {
  print('关闭麦克风出错:$err');
}

打开自己的摄像头

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    // 该方法使用方式仅限于web端
    final res = await ImPluginTencentWeb.openSelfCamera(String renderCameraDomId);
} catch(err) {
  print('打开自己的摄像头出错:$err');
}

关闭自己的摄像头

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    final res = await ImPluginTencentWeb.closeSelfCamera();
} catch(err) {
  print('关闭自己的摄像头出错:$err');
}

渲染远端的摄像头

import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';

try {
    // 该方法使用方式仅限于web端
    final res = await ImPluginTencentWeb.openRemoteCamera(String userId, String renderRemoteCameraDomId);
} catch(err) {
  print('渲染远端的摄像头出错:$err');
}

带 UI 的使用方式

在使用UI之前, 你必须先进行IM的初始化与登录流程

在浏览器每次刷新都会执行的地方这样做

import 'package:im_plugin_tencent_web/im/init.dart';
import 'package:im_plugin_tencent_web/im/event_chat_listener_config.dart';
import 'package:im_plugin_tencent_web/im/event_call_listener_config.dart';

@override
void initState() {
  super.initState();

  WidgetsBinding.instance.addPostFrameCallback((_) async {
    try {
      // 下面方法其实可以不传入任何参数,不传参数时会从浏览器会话缓存中读取im相关参数,进行im初始化与im自动登录
      // 
      // 内部执行逻辑:
      // 
      // 1、先确认 sdkAppId
      //    sdkAppId = 传入的 sdkAppId ?? 浏览器会话缓存中的 sdkAppId;
      //    如果最终确认的 sdkAppId 为空,则进入 catch,错误码:101
      // 
      // 2、如果 sdkAppId 不为空,先执行 腾讯IM SDK 的初始化
      //    再从浏览器会话缓存中读取 IM登录信息,执行 腾讯IM 的登录
      //    读取不到浏览器会话缓存中的 IM登录信息,则进入 catch。如果仅需要实现初始化IM的步骤,那么该 catch 忽略即可
      //    错误码表:
      //       201    缓存中不存在 imLoginInfo
      //       202    解析 imLoginInfo 缓存出错
      //       203    执行腾讯IM官方登录接口报错
      // 
      // 如果在正式登录业务完成之前进入第二步的异常,可不处理
      // 如果在正式登录业务完成之后进入第二步的异常,则需要处理,进行重新登录IM的逻辑
      await setTencentImParamsAndLoginByCached(
        sdkAppId: 0,
        initCall: true, // 是否初始化音视频通话,默认 true
        eventChatListener: EventChatListenerConfig(), // 可不传。聊天事件监听
        eventCallListener: EventCallListenerConfig(), // 可不传。音视频通话事件监听
      );
    } catch (err) {
      // 收到 IM 初始化或登录异常的情况下,进行进一步处理
      // 比如:再次调用 setTencentImParamsAndLoginByCached 传入需要的参数,别让它走缓存了
      // 比如:重新进行IM的登录
    }
  });
}

在登录业务完成后

import 'package:im_plugin_tencent_web/im/init.dart';

try {
  await doImTencentWebPluginLogin(
    userId, // 登录 userId
    userSig, // 登录 userSig
  );
} catch (err) {
  // 收到 IM 登录异常的情况下,进行进一步处理
  // 比如:提示用户重试 或 提示登录im失败 或 提示登录im的账号信息有误
}

经典组合UI

经典组合UI的使用方式

import 'package:im_plugin_tencent_web/widget/conversation_list.dart';
import 'package:im_plugin_tencent_web/widget/chat.dart';

Row(
  children: [
    SizedBox(
      width: 300,
      child: ConversationListWidget(),
    ),
    Expanded(
      child: ChatWidget(),
    ),
  ],
)

会话列表

会话列表UI的使用方式

import 'package:im_plugin_tencent_web/widget/conversation_list.dart';

SizedBox(
    width: 300,
    child: ConversationListWidget(),
)

聊天窗口

聊天窗口UI的使用方式

import 'package:im_plugin_tencent_web/widget/chat.dart';

SizedBox(
    width: 800,
    child: ChatWidget(),
)