• 製品
  • 価格
  • リソース
  • サポート

AI 対話 IM シグナリング ソリューション

IM SDK の統合

iOS
Android
Web & ミニプログラム

IM SDK を統合

IM SDK の統合には、CocoaPodsを使用した自動ロード方式を選択することをお勧めします。
1. CocoaPodsをインストールします。ターミナルウィンドウで以下のコマンドを入力します(MacにRuby環境を事前にインストールする必要があります)。
sudo gem install cocoapods
2. Podfileファイルを作成します。プロジェクトのパスに移動し、次のコマンドラインを入力すると、プロジェクトパスにPodfileファイルが作成されます。
pod init
3. Podfileファイルを編集します。以下の方法でPodfileファイルを設定してください。
platform :ios, '8.0'
source 'https://github.com/CocoaPods/Specs.git'

target 'App' do
# 完全版のIM SDKを統合する場合、バージョン番号は'8.1.6129'以上にする必要があります
pod 'TXIMSDK_Plus_iOS','8.1.6129'
# または、ボリュームを削減したIM SDK(AIシグナリング関連機能のみを含む)を統合する場合、バージョン番号は'8.2.6361'以上にする必要があります
pod 'TXIMSDK_Plus_SignalingSDK','8.2.6361'
end
4. SDKを更新してインストールします。
ターミナルウィンドウで以下のコマンドを入力して、ローカルライブラリファイルを更新し、IM SDKをインストールします。
pod install
または、以下のコマンドを使用してローカルライブラリのバージョンを更新します。
pod update
注意:
上記の操作を行っても問題が解決しない場合は、Xcode 統合のよくある問題 ドキュメントをご参照ください。

IM SDK を引用

プロジェクトコードでSDKを使用するには2つの方法があります。
Xcode > Build Setting > Header Search Paths でSDKヘッダーファイルのパスを設定し、プロジェクトでSDK APIを使用する必要があるファイルに具体的なヘッダーファイルを導入します。
#import "ImSDK_Plus.h"
プロジェクトでSDK APIを使用する必要があるファイルに具体的なヘッダーファイルを導入します。
#import <ImSDK_Plus/ImSDK_Plus.h>

SDK(aar)を統合

IM SDK の統合には、Gradle を使用した自動ロード方式を選択することをお勧めします。
1. SDK依存関係を追加。
1.1 appのbuild.gradleを見つけて、repositoriesにmavenCentral()の依存関係を追加します。
repositories {
google()
// mavenCentral リポジトリを追加
mavenCentral()
}
1.2 次に、dependenciesにIM SDKの依存関係を追加します。
dependencies {
// 完全版のIM SDKを統合する場合、バージョン番号は'8.1.6129'以上にする必要があります
api 'com.tencent.imsdk:imsdk-plus:8.1.6129'
// または、ボリュームを削減したIM SDK(AIシグナリング関連機能のみを含む)を統合する場合、バージョン番号は'8.2.6361'以上にする必要があります
api 'com.tencent.imsdk:signalingsdk:8.2.6361'
}
2. Appで使用するアーキテクチャを指定します。defaultConfigで、Appで使用するCPUアーキテクチャを指定します(IM SDK 4.3.118バージョン以降から、armeabi-v7a、arm64-v8a、x86、x86_64をサポート)。
defaultConfig {
ndk {
abiFilters "arm64-v8a"
}
}
3. SDKの同期。ネットワークがmavenに接続されていることを確認し、Sync ボタンをクリックすると、SDKが自動的にダウンロードされてプロジェクトに統合されます。




App 権限の設定

AndroidManifest.xmlで App の権限を設定します。IM SDK には以下の権限が必要です。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

難読化ルールの設定

proguard-rules.proファイルで、IM SDK関連のクラスを難読化除外リストに追加します。
-keep class com.tencent.imsdk.** { *; }

IM SDK 統合

npm 方式で IM SDK を Web やミニプログラムに統合することをお勧めします。
// バージョン番号v3.4.5以上
npm install @tencentcloud/chat
説明:
依存関係の同期中に問題が発生した場合は、npmのソースを切り替えてから再度お試しください。
npm config set registry http://r.cnpmjs.org/

モジュールを導入

import TencentCloudChat from '@tencentcloud/chat';

SDKを初期化

iOS
Android
Web & ミニプログラム
1. 初期化インターフェースを呼び出します。
// 1. ChatコンソールからアプリケーションのSDKAppIDを取得します。
// 2. configオブジェクトを初期化します
V2TIMSDKConfig *config = [[V2TIMSDKConfig alloc] init];
// 3. log出力レベルを指定します。
config.logLevel = V2TIM_LOG_INFO;
// 4. V2TIMSDKListenerのイベントリスナーを追加します。selfはid<V2TIMSDKListener>の実装クラスです。IM SDKのイベントを監視する必要がない場合、このステップを省略できます。
[[V2TIMManager sharedInstance] addIMSDKListener:self];
// 5. IM SDKを初期化し、このインターフェースを呼び出した後、すぐにログインインターフェースを呼び出すことができます。
[[V2TIMManager sharedInstance] initSDK:sdkAppID config:config];
2. ログイン。
NSString *userID = @"your user id";
NSString *userSig = @"userSig from your server";
[[V2TIMManager sharedInstance] login:userID userSig:userSig succ:^{
NSLog(@"success");
} fail:^(int code, NSString *desc) {
// 以下のエラーコードが返された場合、UserSigが期限切れであることを示します。新しく発行された UserSig を使用して再度ログインしてください。
// 1. ERR_USER_SIG_EXPIRED(6206)
// 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001)
// 注意:他のエラーコードの場合は、ここでログインインターフェースを呼び出さないでください。IM SDK のログインが無限ループになるのを避けるためです。
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
1. 初期化インターフェースを呼び出します。
// 1. ChatコンソールからアプリケーションのSDKAppIDを取得します。
// 2. configオブジェクトを初期化します。
V2TIMSDKConfig config = new V2TIMSDKConfig();
// 3. log出力レベルを指定します。
config.setLogLevel(V2TIMSDKConfig.V2TIM_LOG_INFO);
// 4. V2TIMSDKListenerのイベントリスナーを追加します。sdkListenerはV2TIMSDKListenerの実現クラスです。IM SDKのイベントを監視する必要がない場合、このステップを省略できます。
V2TIMManager.getInstance().addIMSDKListener(sdkListener);
// 5. IM SDKを初期化し、このインターフェースを呼び出した後、すぐにログインインターフェースを呼び出すことができます。
V2TIMManager.getInstance().initSDK(context, sdkAppID, config);
2. ログイン。
String userID = "your user id";
String userSig = "userSig from your server";
V2TIMManager.getInstance().login(userID, userSig, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
// 以下のエラーコードが返された場合、UserSigが期限切れであることを示します。新しく発行された UserSig を使用して再度ログインしてください。
// 1. ERR_USER_SIG_EXPIRED(6206)
// 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001)
// 注意:他のエラーコードの場合は、ここでログインインターフェースを呼び出さないでください。IM SDK のログインが無限ループになるのを避けるためです。
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
1. 初期化インターフェースを呼び出します。
import TencentCloudChat from '@tencentcloud/chat';

let options = {
SDKAppID: 0 // 導入時には0をChatアプリケーションのSDKAppIDに置き換えてください
};
// SDKインスタンスを作成します。`TencentCloudChat.create()`メソッドは同じ`SDKAppID`に対して同じインスタンスのみを返します
let chat = TencentCloudChat.create(options); // SDKインスタンスは通常chatで表されます

chat.setLogLevel(0); // 通常レベル、ログ量が多く、導入時にはこの設定をお勧めします
// chat.setLogLevel(1); // release レベル、SDKは重要な情報を出力し、本番環境でこの設定をお勧めします
2. ログイン。
let promise = chat.login({userID: 'your userID', userSig: 'your userSig'});
promise.then(function(imResponse) {
console.log(imResponse.data); // ログイン成功
if (imResponse.data.repeatLogin === true) {
// アカウントがすでにログイン済みであり、今回のログイン操作は重複ログインです。
console.log(imResponse.data.errorInfo);
}
}).catch(function(imError) {
console.warn('login error:', imError); // ログイン失敗に関する情報
});
注意:
Real-Time Communication Engine(RTC Engine) と Chat の sdkAppIdsecretKey は同じでなければなりません。
メッセージを受信する受信者のIMはログイン成功、即ちオンライン状態である必要があります。
受信者のRTC EngineアカウントとChatアカウントは、同じuserIdでなければなりません(即ち、同じuserIdを使用してRTC Engineルームに入室し、IMにログインする必要があります)。

サーバー側からのダウンリンクメッセージを受信します

IM SDK の1対1チャットのカスタムメッセージ受信機能(iOS & Android / Web & ミニプログラム)を通じて、クライアント側でコールバックを監視することで、リアルタイム字幕とAI状態のデータを受信します。
type
说明
10000
リアルタイム字幕、翻訳の配信
10001
AI対話リアルタイム状態の配信
10010
大規模モデルメッセージのパススルー

リアルタイム字幕を受信

{
"type": 10000, // 10000はリアルタイム字幕の配信を示します
"sender": "user_a", // 発言者のuserid
"receiver": [], // 受信者useridリスト、このメッセージは実際にはルーム内でブロードキャストされます
"payload": {
"text":"", // 音声認識されたテキスト
"translation_text":"", // 翻訳されたテキスト
"start_time":"00:00:01", // この文の開始時間
"end_time":"00:00:02", // この文の終了時間
"roundid": "xxxxx" // 一連の対話を一意に識別します
"end": true // trueの場合、これは完全な文であることを示します
}
}

ボットの状態を受信

{
"type": 10001, // ボットの状態
"sender": "user_a", // 送信者userid、ここはボットのidです
"receiver": [], // 受信者useridリスト、このメッセージは実際にはルーム内でブロードキャストされます
"payload": {
"roundid": "xxx", // 一連の対話を一意に識別します
"timestamp": 123
"state": 1, // 1 聴取中 2 思考中 3 発言中 4 中断された
}
}

大規模モデルメッセージのパススルー受信

{
"type": 10010, // 大規模モデルメッセージのパススルー・ダウンリング
"sender": "user_a", // 送信者userid、ここはボットのidです
"receiver": [], // 受信者useridリスト、このメッセージは実際にはルーム内でブロードキャストされます
"payload": {
"id": "uuid", // メッセージID、uuidを使用可能、問題の調査に使用 オプション
"taskid":"xxxxxx", // このai対話のtaskid、必須
"timestamp": 123 // タイムスタンプ、問題の調査に使用、オプション
"data": {
"key": "value" //業務でカスタマイズされたjson形式
}
}
}

サンプルコード

iOS
Android
Web & ミニプログラム
// addSimpleMsgListenerを呼び出してイベントリスナーを設定します
V2TIMManager.sharedInstance().addSimpleMsgListener(listener: self)

/// 1対1チャットのカスタムメッセージを受信します
/// @param msgID メッセージID
/// @param info 送信者情報
/// @param data カスタムメッセージのバイナリ内容
func onRecvC2CCustomMessage(_ msgID: String!, sender info: V2TIMUserInfo!, customData data: Data!) {
do {
if let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
print("onRecvGroupCustomMessage: \(jsonObject)")
handleMessage(jsonObject)
} else {
print("The data is not a dictionary.")
}
} catch {
print("Error parsing JSON: \(error)")
}
}
// addSimpleMsgListenerを呼び出してイベントリスナーを設定します
V2TIMManager.getInstance().addSimpleMsgListener(sdkListener);

/**
* 1対1チャットのカスタムメッセージを受信します
* @param msgID メッセージID
* @param sender 送信者情報
* @param customData 送信内容
*/
public void onRecvC2CCustomMessage(String msgID, V2TIMUserInfo sender, byte[] customData) {
Log.i("onRecvC2CCustomMessage", "msgID:" + msgID + ", from:" + sender.getNickName() + ", content:" + new String(customData));
try {
String jsonString = new String(customData, "UTF-8");
JSONObject jsonObject = new JSONObject(jsonString);
System.out.println("onRecvGroupCustomMessage: " + jsonObject);
handleMessage(jsonObject);
} catch (UnsupportedEncodingException e) {
System.out.println("The data is not a dictionary.");
} catch (JSONException e) {
System.out.println("Error parsing JSON: " + e);
}
}
const onMessageReceived = (event) => {
const messageList = event.data;
messageList?.forEach((msg) => {
if (msg.type === TencentCloudChat.TYPES.MSG_CUSTOM) {
console.log('カスタムメッセージを受信しました', event);
const { data } = msg.payload;
try {
const jsonData = JSON.parse(data);
console.log(`receive custom msg from ${msg.from} data: ${data}`);
if (jsonData.type === 10000) {
console.log('字幕メッセージ', jsonData);
return;
}
if (jsonData.type === 10001) {
console.log('ボットの状態', jsonData);
return;
}
if (jsonData.type === 10010) {
console.log('大規模モデルメッセージのパススルー・ダウンリンク', jsonData);
return;
}
} catch (error) {
console.error('receive custom msg', data, error);
}
}
});
}

// メッセージを監視
chat.on(TencentCloudChat.EVENT.MESSAGE_RECEIVED, onMessageReceived);
説明:
デフォルトでは、1対1チャットのカスタムメッセージでリアルタイム字幕とAI状態のデータを受信します。1対1チャットが要件を満たさない場合、グループチャットのカスタムメッセージチャネルを開通する必要があります。その場合は当社までお問い合わせください

端末からアップリンクシグナリングを送信

カスタムシグナリングを送信することで、ASRプロセスをスキップし、直接AIとテキストコミュニケーションを行ったり、中断シグナリングを送信して中断を行ったり、大規模モデルにパススルー情報を直接送信したりできます。
type
说明
20000
ai_conversation_chat:AI対話テキストを送信
20001
ai_conversation_interrupt:手動で中断
20010
大規模モデルにパススルー情報を送信

アップリンクシグナリングを送信し、ASRプロセスをスキップして直接AIとテキストコミュニケーションを行います

{
"type": 20000,
"sender": "user_a", // 送信者useridであり、サーバー側はこのuseridが有効かどうかをチェックします
"receiver": ["user_bot"], // 受信者 userid リストであり、ボットのuseridを記入するだけで十分です。サーバー側でuseridが有効かどうかをチェックします
"payload": {
"id": "uuid", // メッセージidであり、uuidを使用可能、問題の調査に使用
"message": "xxx", // メッセージ内容
"timestamp": 123, // タイムスタンプ、問題の調査に使用
"taskid": "v2_20240920_xxxxx",
}
}

中断信号を送信して中断します

{
"type": 20001,
"sender": "userid", // 送信者のuseridであり、サーバー側はこのuseridが有効かどうかをチェックします
"receiver": ["user_bot"], // 受信者 userid リストであり、ボットのuseridを記入するだけで十分です
"payload": {
"id": "uuid", // メッセージidであり、uuidを使用可能、問題の調査に使用
"timestamp": 123 // タイムスタンプ、問題の調査に使用
"taskid": "v2_20240920_xxxxx",
}
}

大規模モデルにパススルー情報を送信

{
"type": 20010,
"sender": "userid",
"receiver": [
"robotid"
],
"payload": {
"id": "uuid",
"taskid": "v2_20240920_xxxxx",
"timestamp": 1234,
"data": {
"key": "value" //業務でカスタマイズされたjson形式
}
}
}

サンプルコード

iOS
Android
Web & ミニプログラム
@IBAction func interruptAi(_ sender: UIButton) {
let timestamp = Int(Date().timeIntervalSince1970 * 1000)
let payload = [
"id": userId + "_\(roomId)" + "_\(timestamp)", // メッセージidであり、uuidを使用可能、問題の調査に使用
"timestamp": timestamp, // タイムスタンプ、問題の調査に使用
"taskid": aiTaskId,
] as [String : Any]
let content = [
"type": 20001,
"sender": userId,
"receiver": [botId],
"payload": payload
] as [String : Any]
let contentData = try! JSONSerialization.data(withJSONObject: content, options: [])
let contentString = String(data: contentData, encoding: .utf8)!
let dataDict = [
"service_command": "trtc_ai_service.SendCustomCmdMsg",
"request_content": contentString
] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dataDict, options: [])
V2TIMManager.sharedInstance().callExperimentalAPI("sendTRTCCustomData", param: jsonData as NSObject) { _ in
print("sendTRTCCustomData success")
} fail: { code, desc in
print("sendTRTCCustomData error, \(code), \(desc ?? "null")")
}
} catch {
print("Error serializing dictionary to JSON: \(error)")
}
}
public void interruptAi() {
long timestamp = System.currentTimeMillis();
Map<String, Object> payload = new HashMap<>();
payload.put("id", userId + "_" + roomId + "_" + timestamp); // メッセージid、uuidを使用可能、問題の調査に使用
payload.put("timestamp", timestamp); // タイムスタンプ、問題の調査に使用
payload.put("taskid", aiTaskId);

Map<String, Object> content = new HashMap<>();
content.put("type", 20001);
content.put("sender", userId);
content.put("receiver", Collections.singletonList(botId));
content.put("payload", payload);

String contentString = new JSONObject(content).toString();

Map<String, Object> dataDict = new HashMap<>();
dataDict.put("service_command", "trtc_ai_service.SendCustomCmdMsg");
dataDict.put("request_content", contentString);

try {
byte[] jsonData = new JSONObject(dataDict).toString().getBytes("UTF-8");
V2TIMManager.getInstance().callExperimentalAPI("sendTRTCCustomData", jsonData, new V2TIMValueCallback() {
@Override
public void onSuccess(Object o) {
System.out.println("sendTRTCCustomData success");
}
@Override
public void onError(int code, String desc) {
System.out.println("sendTRTCCustomData error, " + code + ", " + (desc != null ? desc : "null"));
}
});
} catch (UnsupportedEncodingException e) {
System.out.println("Error serializing dictionary to JSON: " + e);
}
}
// 中断シグナルを送信
chat.callExperimentalAPI('sendTRTCCustomData', {
serviceCommand: 'trtc_ai_service.SendCustomCmdMsg',
data: {
type: 20001,
sender: "user_a", // 送信者useridであり、サーバー側はこのuseridが有効かどうかをチェックします
receiver: ["user_bot"], // 受信者 userid リストであり、ボットのuseridを記入するだけで十分です
payload: {
id: "uuid", // メッセージid、uuidを使用可能、問題の調査に使用
timestamp: 123, // タイムスタンプ、問題の調査に使用
taskid: "タスクのtaskid"
}
}
});
注意:
typesenderreceiver および payloadtaskididtimestamp は必須フィールドです。