プライベートチャットとチャットルームを管理する
注釈:本資料はAI技術を用いて翻訳されています。
概要
AccelByte Gaming Services (AGS) チャットを使用すると、ゲーム内でプレイヤー間のプライベートメッセージの送受信や、セッションまたはパーティのチャットルームでのメッセージ送受信を有効にできます。
この記事では、以下の方法について説明します:
- チャットをサポートするセッションテンプレートを構成する
- チャットルーム付きの新しいセッションを作成する
- セッションチャットルームを通じてメッセージを送信する
パーティは AGS Session によって管理されるため、セッションとパーティのプロセスは似ています。
この記事では、「トピック」という用語は「チャットルーム」と互換性があります。どちらもチャットメッセージを送信できるチャネルの表現です。プレイヤーはセッションに参加すると自動的にチャットルームにサブスクライブされ、退出すると削除されます。
前提条件
この記事のすべての手順を完了するには、以下が必要です:
- AGS Lobby、Session、および Chat に精通していること。
- ゲームに適切な SDK がインストールされていること。
- AGS 管理ポータルで適切なゲーム namespace へのアクセス権があること。
AGS チャットに接続する
- OSS
- Unity
プレイヤーがチャットメッセージを送受信できるようになる前に、まず AGS Identity によって認証される必要があります。これにより、ユーザーアカウントでチャットに自動的に接続されます。
AGS OSS プラグインを使用している場合は、DefaultEngine.ini ファイルで以下の設定値を有効にして、ログイン後にユーザーが自動的に AGS チャットに接続できるようにする必要があります。
[OnlineSubsystemAccelByte]
bAutoChatConnectAfterLoginSuccess=true
プレイヤーがチャットメッセージを送受信できるようになる前に、まず AGS Identity によって認証される必要があります。ユーザー API クライアントが認証されたら、チャットサービスの WebSocket に接続します。
var apiClient = AccelByteSDK.GetClientRegistry().GetApi();
Chat chatService = apiClient.GetChat();
apiClient.GetUser().LoginWithEmailV4(userEmailAddress, userPassword, (Result<TokenData, OAuthError> result) =>
{
if (result.IsError)
{
// ログインエラーを処理
return;
}
chatService.Connected += () =>
{
// チャット WebSocket 接続成功を処理
};
chatService.Connect();
});
プライベートメッセージを送信する
プレイヤーは他のユーザーに直接メッセージを送信できます。他のプレイヤーがプライベートメッセージまたはダイレクトメッセージを送信しているときにリッスンするために、適切なデリゲートを登録できます。
- Unreal Engine
- OSS
- Unity
// チャット通知デリゲートを設定します。このデリゲートは新しいメッセージがあるときに呼び出されます。
ApiClient->Chat.SetChatNotifDelegate(
Api::Chat::FChatNotif::CreateLambda([](const FAccelByteModelsChatNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("チャットを受信! From[%s] content: [%s]"),
*Result.From, *Result.Message);
})
);
// 「トピックに追加」通知デリゲートを設定します。これはプレイヤーがトピックに追加されたときに呼び出されます。
ApiClient->Chat.SetAddToTopicNotifDelegate(
Api::Chat::FAddRemoveFromTopicNotif::CreateLambda([](const
FAccelByteModelsChatUpdateUserTopicNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("トピック [%s] にユーザー [%s] によって追加されました"),
*Result.TopicId, *Result.SenderId);
})
);
// 個人トピックを作成します。
// ターゲットプレイヤーはトピックに追加されたという通知を受け取ります。
FApiClientPtr ApiClient = AccelByteOnlineSubsystemPtr->GetApiClient(TEXT("0"));
ApiClient->Chat.CreatePersonalTopic(TEXT("target_user_id"),
Api::Chat::FChatActionTopicResponse::CreateLambda(
[](const FAccelByteModelsChatActionTopicResponse& Result)
{
UE_LOG(LogTemp, Log, TEXT("個人トピックの作成に成功しました。作成された TopicID:
%s"), *Result.TopicId);
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT("エラーコード: %d\nエラーメッセージ:%s"), ErrorCode,
*ErrorMessage);
})
);
// 個人トピックが作成された後、プレイヤーはトピックにチャットメッセージを送信できます。
// ターゲットプレイヤーはチャット通知デリゲートで通知されます。
FApiClientPtr ApiClient = AccelByteOnlineSubsystemPtr->GetApiClient(TEXT("0"));
ApiClient->Chat.SendChat(TEXT("topic_id"), TEXT("送信するメッセージ"),
Api::Chat::FSendChatResponse::CreateLambda(
[](const FAccelByteModelsChatSendChatResponse& Result)
{
UE_LOG(LogTemp, Log, TEXT("トピックへのメッセージ送信に成功しました。"));
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT("エラーコード: %d\nエラーメッセージ:%s"), ErrorCode,
*ErrorMessage);
})
);
// 「プライベートメッセージ受信」通知をリッスンします。
auto ChatPrivateMessageReceivedHandle =
ChatInterface->AddOnChatPrivateMessageReceivedDelegate_Handle(
FOnChatPrivateMessageReceivedDelegate::CreateLambda(
[&ReceivedPrivateMessage](const FUniqueNetId& LocalUserId, const TSharedRef<FChatMessage>& ChatMessage)
{
ReceivedPrivateMessage = ChatMessage->GetBody();
}));
// チャットメッセージがサービスを通じて正常に送信されたかどうかをリッスンするために、このデリゲートをバインドします。
auto ChatRoomMessageSentHandle = ChatInterface->AddOnSendChatCompleteWithErrorDelegate_Handle(
FOnSendChatCompleteWithErrorDelegate::CreateLambda([](FString UserId, FString MsgBody, FString RoomId, bool bWasSuccessful, const FOnlineError& Error)
{
// ここで成功または失敗を処理します。
}));
TSharedPtr<const FUniqueNetId> LocalUserId;
FString TestPrivateMessage = TEXT("テストプライベートメッセージ");
// チャットインターフェースから SendPrivateChat を呼び出してプライベートメッセージを送信します。
// ターゲットユーザーの recipientId を取得している必要があります。
ChatInterface->SendPrivateChat(LocalUserId.ToSharedRef().Get(), recepientId, TestPrivateMessage);
// この例の前に、ユーザーの ApiClient が認証され、チャット WebSocket が接続されていることを確認してください。
var creatorApiClient = AccelByteSDK.GetClientRegistry().GetApi("0");
var memberApiClient = AccelByteSDK.GetClientRegistry().GetApi("1");
string topicId = null;
// 新しいメッセージがあるときにリッスンするために、このデリゲートをバインドします。
EventNewChat memberNewChat = null;
memberApiClient.GetChat().NewChatMessage += chat =>
{
Debug.Log("新しいチャットを受信 " + chat.message + " ユーザー ID " + chat.from + " から");
memberNewChat = chat;
};
// プレイヤーがトピックに追加されたときにリッスンするために、このデリゲートをバインドします。
creatorApiClient.GetChat().AddedToTopic += topic =>
{
Debug.Log("トピックに追加されました" + topic.topicId);
topicId = topic.topicId;
};
// 個人トピックを作成します。
// ターゲットプレイヤーはトピックに追加されたという通知を受け取ります。
var targetUserId = memberApiClient.GetUser().Session.UserId;
Result<Models.ChatActionTopicResponse> createPersonalTopicResult = null;
creatorApiClient.GetChat().CreatePersonalTopic(targetUserId, result =>
{
createPersonalTopicResult = result;
});
// 個人トピックが作成された後、プレイヤーはトピックにチャットメッセージを送信できます。
// ターゲットプレイヤーはチャット通知デリゲートで通知されます。
Result<Models.SendChatResponse> sendChatMessageResult = null;
creatorApiClient.SendChatMessage(topicId, "Hello World", result =>
{
if (result.IsError)
{
Debug.LogWarning($"メッセージの送信に失敗しました [{result.Error.Code}]:{result.Error.Message}");
return;
}
sendChatMessageResult = result;
Debug.Log(("チャットメッセージの送信に成功しました"));
});
セッションのチャットルームを有効にする
チャットルームはセッションレベルで管理され、セッションテンプレートの一部として有効にできます。チャットが有効なセッションテンプレートを構成するには、以下の手順に従って環境の API ドキュメントを使用する必要があります:
-
環境の Swagger ページを開きます。例: AccelByte Demo Environment。
-
新しいセッションテンプレートを作成するには POST を選択するか、既存のテンプレートを更新するには PUT を選択します。どちらのオプションでも、リクエストボディに適切な値を設定してください。
-
ゲームネームスペースをターゲットにし、
textChatをtrueに設定したリクエストボディを追加します。 -
リクエストを実行し、出力が正常に実行されたことを示していることを確認します。
サンプルリクエストボディ:
{
"name": "default",
"deployment": "default",
"inactiveTimeout": 60,
"inviteTimeout": 60,
"joinability": "OPEN",
"maxPlayers": 5,
"minPlayers": 1,
"type": "NONE",
"textChat": "true"
}
セッションチャットルームを作成する
一般的に、チャットが有効なテンプレートを使用してセッションを作成する場合、セッションのチャットルームを作成するための追加の手順は必要ありません。AGS を使用する場合、チャットルーム付きのセッションを作成する方法は 3 つあります:
-
matchmaking を通じて: マッチが見つかると、セッションテンプレートに基づいてゲームセッションが作成されます。セッションテンプレートでチャットが有効になっている場合、セッションチャットルームが自動的に作成されます。
-
セッションテンプレート: テンプレートでチャットが有効になっている限り、セッションチャットルームが自動的に作成されます。
-
セッションテンプレートなしでセッションを作成する: これには、チャットを
trueに設定することを含む、必要なセッション設定を渡す必要があります。
テンプレートなしでセッションを作成する必要がある場合は、以下のコードサンプルを使用して、チャットを有効にして CreateSession を呼び出す前にセッション設定を定義する方法を確認できます。
- Unreal Engine
- OSS
- Unity
// この例は、チャットルーム/トピック付きのパーティセッションを手動で作成する方法を示しています。
FAccelByteModelsV2PartyCreateRequest CreatePartyRequest;
// セッションのテキストチャットを true に設定します。
CreatePartyRequest.TextChat = true;
// プレイヤーがセッションチャットルーム/トピックに追加されたときにリッスンするために、このデリゲートをバインドします。
ApiClient->Chat.SetAddToTopicNotifDelegate(
Api::Chat::FAddToTopicNotif::CreateLambda([](const FAccelByteModelsChatUpdateUserTopicNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("トピック [%s] にユーザー [%s] によって追加されました"), *Result.TopicId, *Result.SenderId);
})
);
// チャットルームまたはトピック付きの新しいセッションを作成します。
ApiClient->Session.CreateParty(CreatePartyRequest,
THandler<FAccelByteModelsV2PartySession>::CreateLambda(
[](const FAccelByteModelsV2PartySession& Result)
{
UE_LOG(LogTemp, Log, TEXT("パーティが作成されました"));
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT("エラーコード: %d\nエラーメッセージ:%s"), ErrorCode, *ErrorMessage);
})
);
// OSS はセッションインターフェースを使用してパーティとセッションを作成および管理します。
// 作成するセッションのセッション設定を定義します。
FOnlineSessionSettings NewSessionSettings;
NewSessionSettings.NumPrivateConnections = 4;
NewSessionSettings.Set(SETTING_SESSION_JOIN_TYPE, TEXT("INVITE_ONLY"));
NewSessionSettings.Set(SETTING_SESSION_TYPE, SETTING_SESSION_TYPE_PARTY_SESSION);
NewSessionSettings.Set(SETTING_SESSION_TEMPLATE_NAME, ConfigurationTemplateName);
// セッション設定でテキストチャットを true に設定します。
NewSessionSettings.Set(SETTING_SESSION_TEXTCHAT, true);
// 新しいセッションの作成が成功したときにリッスンするために、デリゲートをバインドします。
FName SessionNameResponse = FName(TEXT(""));
auto OnCreateSessionCompleteDelegate = SessionInterface->AddOnCreateSessionCompleteDelegate_Handle(
FOnCreateSessionCompleteDelegate::CreateLambda([&SessionNameResponse](FName SessionName, bool bWasSuccessful)
{
SessionNameResponse = SessionName;
}));
// プレイヤーがセッションチャットルーム/トピックに追加されたときにリッスンして、ルームに関する情報を取得するために、このデリゲートをバインドします。
FString InTopicId;
auto TopicAddedHandle = ChatInterface->AddOnTopicAddedDelegate_Handle(
FOnTopicAddedDelegate::CreateLambda([&InTopicId](FString ChatTopicName, FString TopicId, FString SenderId)
{
InTopicId = TopicId;
}));
// チャットルーム/トピック付きの新しいセッションを作成します。
SessionInterface->CreateSession(LocalUserId.ToSharedRef().Get(), NAME_Session, NewSessionSettings);
// この例は、チャットルーム/トピック付きのパーティセッションを手動で作成する方法を示しています。
// この例の前に、ユーザーの ApiClient が認証され、チャット WebSocket が接続されていることを確認してください。
var apiClient = AccelByteSDK.GetClientRegistry().GetApiClient();
// プレイヤーがセッションチャットルーム/トピックに追加されたときにリッスンするために、このデリゲートをバインドします。
apiClient.GetChat().AddedToTopic += topic =>
{
Debug.Log("トピックに追加されました" + topic.topicId);
};
var createPartyRequest = new SessionV2PartySessionCreateRequest
{
configurationName = configurationTemplateName,
textChat = true // このセッションのテキストチャットを true に設定します。
};
// チャットルーム付きの新しいセッションを作成します。
Result<SessionV2PartySession> createPartySessionResult = null;
apiClient.GetSession().CreateParty(createPartyRequest, result =>
{
if (!result.IsError)
{
Debug.Log("パーティ作成成功");
}
});
返される ID (RoomId / TopicId) には、作成されたセッションのタイプに基づいてプレフィックスが付きます:
s.は V2 ゲームセッションチャットルーム/トピックに対応しますp.は V2 パーティセッションチャットルーム/トピックに対応します
セッションチャットルームに参加する
プレイヤーがセッションに参加すると、追加の作業なしで自動的にそのチャットルームにメンバーとしてサブスクライブされます。
他のプレイヤーがチャットルームに追加されたときにリッスンするために、適切なデリゲートを登録できます。
- Unreal Engine
- OSS
- Unity
// プレイヤーがセッションチャットルーム/トピックに追加されたときにリッスンするために、このデリゲートをバインドします。
ApiClient->Chat.SetAddToTopicNotifDelegate(
Api::Chat::FAddRemoveFromTopicNotif::CreateLambda([](const FAccelByteModelsChatUpdateUserTopicNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("トピック [%s] にユーザー [%s] によって追加されました"), *Result.TopicId, *Result.SenderId);
})
);
FString SessionV2RoomId;
// プレイヤーがセッションチャットルーム/トピックに追加されたときにリッスンするために、このデリゲートをバインドします。
ChatInterface->AddOnChatRoomMemberJoinDelegate_Handle(
FOnChatRoomMemberJoinDelegate::CreateLambda([&SessionV2RoomId](const FUniqueNetId& UserId, const FChatRoomId& RoomId, const FUniqueNetId& MemberId)
{
// ユーザーはセッションの作成または参加時に自動的にルーム/トピックに追加されます
const auto RoomType = FOnlineChatAccelByte::GetChatRoomType(RoomId);
if (RoomType == EAccelByteChatRoomType::PARTY_V2)
{
// これはセッション v2 ルームです
SessionV2RoomId = RoomId;
}
// 注: これはすべてのユーザーに対してトリガーされます
if (UserId == MemberId)
{
// 現在のユーザーがチャットルームに参加しました
}
else
{
// 別のユーザーがチャットルームに参加しました
}
}));
// プレイヤーがセッションチャットルーム/トピックに追加されたときにリッスンするために、このデリゲートをバインドします。
apiClient.GetChat().AddedToTopic += topic =>
{
Debug.Log("トピックに追加されました" + topic.topicId);
};
セッションチャットルームから退出する
プレイヤーがセッションから退出すると、AGS Session がチャットルームのメンバーとしてプレイヤーを削除する管理を行います。これには、セッションからキックアウトされたプレイヤーも含まれます。
プレイヤーがチャットルームから削除されたときにリッスンするために、適切なデリゲートを登録できます。
- Unreal Engine
- OSS
- Unity
// プレイヤーがセッションチャットルーム/トピックから削除されたときにリッスンするために、このデリゲートをバインドします。
ApiClient->Chat.SetRemoveFromTopicNotifDelegate(
Api::Chat::FAddRemoveFromTopicNotif::CreateLambda([](const FAccelByteModelsChatUpdateUserTopicNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("トピック [%s] からユーザー [%s] によって削除されました"), *Result.TopicId, *Result.SenderId);
})
);
// プレイヤーがセッションチャットルーム/トピックから削除されたときにリッスンするために、このデリゲートをバインドします。
FUniqueNetIdPtr ExitMemberId;
auto MemberExitRoomEventHandle = ChatInterface->AddOnChatRoomMemberExitDelegate_Handle(
FOnChatRoomMemberExitDelegate::CreateLambda([&ExitMemberId](const
FUniqueNetId& UserId, const FChatRoomId& RoomId, const FUniqueNetId& MemberId)
{
ExitMemberId = MemberId.AsShared();
}));
// プレイヤーがセッションチャットルーム/トピックから削除されたときにリッスンするために、このデリゲートをバインドします。
apiClient.GetChat().RemovedFromTopic += topic =>
{
Debug.Log("トピックから削除されました " + topic.topicId);
};
セッションチャットメッセージを送信する
プレイヤーがチャットルームに入ると、他のプレイヤーが受信できるようにルームにメッセージを送信し始めることができます。プレイヤーは複数のチャットルームにサブスクライブできるため、メッセージを送信するリクエストを行うときに、正しいセッションチャットルームに配信されるように、メッセージと共に適切なルーム/トピック ID を提供する必要があります。
- Unreal Engine
- OSS
- Unity
FApiClientPtr ApiClient = AccelByteOnlineSubsystemPtr->GetApiClient(TEXT("0"));
// チャットインターフェースから SendChat を呼び出してメッセージを送信します。
// プレイヤーがセッションチャットルーム/トピックに参加したときに ID を取得して保存しておく必要があります。
ApiClient->Chat.SendChat(TEXT("topic_id"), TEXT("送信するメッセージ"), Api::Chat::FSendChatResponse::CreateLambda(
[](const FAccelByteModelsChatSendChatResponse& Result)
{
UE_LOG(LogTemp, Log, TEXT("トピックへのメッセージ送信に成功しました。"));
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT("エラーコード: %d\nエラーメッセージ:%s"), ErrorCode, *ErrorMessage);
})
);
// チャットメッセージがサービスを通じて正常に送信されたかどうかをリッスンするために、このデリゲートをバインドします。
auto ChatRoomMessageSentHandle = ChatInterface->AddOnSendChatCompleteWithErrorDelegate_Handle(
FOnSendChatCompleteWithErrorDelegate::CreateLambda([](FString UserId, FString MsgBody, FString RoomId, bool bWasSuccessful, const FOnlineError& Error)
{
// ここで成功または失敗を処理します
}));
TSharedPtr<const FUniqueNetId> LocalUserId;
// チャットインターフェースから SendRoomChat を呼び出してメッセージを送信します。
// プレイヤーがセッションチャットルームに参加したときに RoomID を取得しておく必要があります。または、FOnlineChatAccelByte::GetJoinedRooms を呼び出して参加しているすべてのルームを取得できます。
ChatInterface->SendRoomChat(LocalUserId.ToSharedRef().Get(), RoomId, TestRoomMessage);
// チャットルーム/トピックに既に参加していて ID を保存している状態で SendChatMessage を呼び出します。
// プレイヤーがセッショントピックに参加したときに TopicId を取得して保存しておく必要があります。
apiClient.GetChat().SendChatMessage("topicId", "これはチャットメッセージです", result =>
{
if (result.IsError)
{
Debug.LogWarning($"メッセージの送信に失敗しました [{result.Error.Code}]:{result.Error.Message}");
return;
}
Debug.Log(("チャットメッセージの送信に成功しました"));
});
セッションチャットメッセージを受信する
他のプレイヤーからのチャットメッセージをリッスンするには、適切なデリゲートを登録します。新しいメッセージが利用可能になると、メッセージが送信された関連するルーム/トピック ID と共に呼び出されます。
- Unreal SDK
- Online Subsystem
- Unity SDK
// 他のプレイヤーから送信された新しいメッセージをリッスンするために、このデリゲートをバインドします。
ApiClient->Chat.SetChatNotifDelegate(
Api::Chat::FChatNotif::CreateLambda([](const FAccelByteModelsChatNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("チャットを受信! From[%s] content: [%s]"), *Result.From, *Result.Message);
})
);
FString ReceivedChatRoomMessage = TEXT("");
// 「チャットルームメッセージ受信」通知をリッスンします
auto ChatRoomMessageReceivedHandle = ChatInterface->AddOnChatRoomMessageReceivedDelegate_Handle(
FOnChatRoomMessageReceivedDelegate::CreateLambda(
[&ReceivedChatRoomMessage](const FUniqueNetId& UserId, const FChatRoomId& RoomId, const TSharedRef<FChatMessage> ChatMessage)
{
ReceivedChatRoomMessage = ChatMessage->GetBody();
}));
FString ReceivedPrivateMessage = TEXT("");
// 「プライベートメッセージ受信」通知をリッスンします
auto ChatRoomMessageReceivedHandle =
ChatInterface->AddOnChatPrivateMessageReceivedDelegate_Handle(
FOnChatPrivateMessageReceivedDelegate::CreateLambda(
[&ReceivedPrivateMessage](const FUniqueNetId& UserId, const TSharedRef<FChatMessage>& ChatMessage)
{
ReceivedPrivateMessage = ChatMessage->GetBody();
}));
// 他のプレイヤーから送信された新しいメッセージをリッスンするために、このデリゲートをバインドします。
apiClient.GetChat().NewChatMessage += chat =>
{
Debug.Log("新しいチャットを受信 " + chat.message + " ユーザー ID " + chat.from + " から");
};
チャット履歴を取得する
チャットサービスはチャット履歴にメッセージを保存し、モデレーターがレビューしたり、ユーザーが自分のメッセージを表示したりするためにアクセスできます。チャット履歴は以下のように管理されます:
- メッセージはトピック ID ごとに整理されており、トピックに基づいて簡単に取得できます。
- メッセージは毎秒記録され、1 秒の遅延後に取得可能になります。
- デフォルトでは、チャット履歴は 30 日間保持され、その後自動的に削除されます。
- ユーザーは、自分がメンバーであるトピックのチャット履歴のみにアクセスできます。
チャット履歴を取得するには、以下のパラメータを使用して queryChat WebSocket コマンドを使用します:
topicId: メッセージを取得するトピックの ID。limit: 取得するメッセージの最大数。lastChatCreatedAt: 取得するメッセージの最も古いタイムスタンプ。Unix 時間で指定します。