これは、Discordでの顧客エンゲージメントに関する3部構成シリーズの最終記事です。最初のブログ記事”顧客エンゲージメントの新フロンティア”では、Discordの普及と、ブランドが独自のオンラインコミュニティを作成・参加するための新しい機会について議論しました。第2部”ブランドのためのDiscordコミュニティとボットの作成方法”では、ブランドのためのDiscordサーバーの作成方法と、サーバー管理、アナウンス、ユーザーフィードバックなどを管理するボットの統合方法を紹介しました。最後に、このブログでは、Seasalt.aiがDiscordサーバーに完全な機能を持つコンタクトセンターを統合し、ブランドがプラットフォームでのカスタマーサービスのすべての側面を処理できるようにする方法を実証します。
目次
Discordカスタマーサービスデモ
要点に直行して最終製品を見たい場合は、まず最終デモビデオをお見せします:
私たちの目標は、Discordを既存のカスタマーサービスソフトウェア(この場合はTwilio Flex)に統合して、公式ブランドサーバーに追加価値を提供する方法を実証することです。実装の詳細な理解のために、読み続けてください。
Twilio Flex
Twilioは、SMS、電話、メール、チャットメッセージなどを管理するためのAPIを提供する成熟した通信企業です。FlexはTwilioの主力製品の1つで、任意のソースからのメッセージとコールを仮想エージェントとライブエージェントにルーティングできるスケーラブルなクラウドベースのコンタクトセンターです。Facebook、SMS、WhatsAppなどの様々なチャンネルで既に優れたサポートを提供しているため、コンタクトセンター統合の基盤としてFlexを選択しました。
SeaX
SeaXは、生産性と顧客満足度の向上を支援する高度なAI機能と深く統合されたクラウドコンタクトセンターです。SeaXはSeasalt.aiの主力製品の1つで、150以上の国々の顧客に展開されています。SeaXコンタクトセンタープラットフォームはTwilio Flex上に構築され、ライブエージェントが顧客をより適切に支援するのに役立つ様々な追加機能が含まれています。最も有用な機能には、内部テキスト読み上げと音声認識、AI駆動のナレッジベース、統合ケース管理システムなどがあります。SeaXプラットフォームのすべての機能の詳細については、SeaXホームページをご覧ください。
デモサーバー
次に、Discordサーバーの設定方法を紹介します。デモ目的で、私たちのサーバーがPokémon Go!のようなゲームのコミュニティとして使用されるシナリオを想定しました。以下の表は、デモDiscordサーバーで実証する機能の概要を示しています。

デモDiscordサーバーの機能概要。
1対多のヘルプ: 公式チャンネル
サーバー内のいくつかのチャンネルは、公式管理者/開発者とプレイヤー間の直接ストリームを提供するために設定されています。 アナウンスチャンネルは管理者とモデレーターのみが投稿でき、Twitterアカウント、ウェブサイト、その他の公式ソースからの(手動または自動)投稿を含むことができます。

Discordサーバーのデモ#announcementsチャンネル。
バグ報告チャンネルでは、プレイヤーがバグやゲームを破綻させる問題について議論できます。管理者はこのチャンネルを密接に監視して、対処すべきゲーム内の問題を特定できます。さらに、ユーザーはチャンネル内で/bug
スラッシュコマンドを使用して公式バグ報告を送信できます。

送信されたバグ報告を含むDiscordサーバーのデモ#bug-reportチャンネル。
機能リクエストチャンネルでは、プレイヤーがゲームプレイの変更、生活の質の向上、コンテンツの追加など、ゲームで見たい変更について議論できます。バグリクエストチャンネルと同様に、Discordモデレーターが彼らの入力を確認でき、/new_feature
スラッシュコマンドを使用して公式リクエストを送信できます。

スラッシュコマンドを実行するユーザーを含むDiscordサーバーのデモ#feature-requestチャンネル。
1対1のヘルプ: カスタマーサービスエージェント
プレイヤーは/helpme
スラッシュコマンドを使用してエージェントとのダイレクトメッセージをトリガーできます。カスタマーサービスエージェントは自動化(仮想エージェント)またはライブエージェントによって操作できます。
デモでは、企業のナレッジベースを照会してユーザーに関連記事の提案を提供するシンプルなFAQボットを設定しました。ユーザーはライブエージェントをリクエストすることもでき、同じチャットセッションでSeaXのライブエージェントに転送されます。

DMをトリガーするユーザーを含むDiscordサーバーのデモ#feature-requestチャンネル。
ナレッジベース
ユーザーが仮想サービスエージェントにクエリを送信すると、エージェントはユーザーをナレッジベースの関連記事に紹介できます。
ライブエージェント転送
ユーザーがボットとのダイレクトメッセージを開始すると、ライブエージェントをリクエストできます。ケースが作成され、ライブエージェントに転送されていることを即座に通知されます。ライブエージェントがチャットに参加すると、通知も受け取ります。

ナレッジベース記事の提案、ライブエージェント転送、ケース管理を含むカスタマーサービスとのダイレクトメッセージ。
バックエンドでは、ライブエージェントは単一のプラットフォームを通じてすべてのチャンネル(SMS、Facebook、Discord、音声通話など)からのコールとチャットメッセージを処理できます。この場合、バックエンドプラットフォームはSeaXです。

Discordユーザーとの会話のライブエージェントビューを示すSeaXインターフェース。
ケース管理
このデモで強調したい機能の1つはケース管理です。Seasalt.aiのDiscordソリューションはSeaXケース管理システムと統合され、ユーザーの様々なケースを適切に追跡します。ユーザーがDiscordボットと対話するとき(ライブエージェントをリクエストしたりバグを報告したりするなど)、新しいケースを自動的に開き、ユーザーと彼らが経験している問題に関するすべての重要な情報を記録できます。これにより、ライブエージェントが報告されたすべての問題に簡単にアクセスでき、ケースが解決されるまでユーザーを追跡することを保証します。

SeaXケース管理システムで新しいケースを作成。

SeaXケース管理システムで既存のケースを表示。
技術的詳細
今、最終製品とサーバーメンバーと彼らを支援するライブエージェントが利用できるすべての機能を見ました。しかし、すべてが実際にどのように実装されているのでしょうか?前回のブログ記事”ブランドのためのDiscordコミュニティとボットの作成方法”では、ブランドのためのDiscordサーバーの作成方法とDiscordボットを統合して管理する方法を紹介しました。このより高度なデモをサポートするために、SeaChat、Seasalt.aiの会話型AIエンジンも使用して、Discordボットがユーザーの自然言語クエリを処理できるシンプルなチャットボットを構築しました。
SeaX側では、チームはTwilioと密接に協力して、Twilio Flex上に構築された機能豊富なコンタクトセンターソリューションを作成しました。Twilio Flexとセットアッププロセスの動作についての詳細は、Twilio Flexクイックスタートガイドをご覧ください。
Discordサーバー、Discordボット、チャットボットを設定し、動作するSeaXインスタンスがあることを確認した後、最大の課題は、SeaX上のユーザー、ボット、ライブエージェント間でメッセージを適切にルーティングする方法でした。Twilioはメッセージルーティングの処理に優れているため、Discordボットサーバー内のすべてのスラッシュコマンドを処理し、他のすべてのメッセージ(チャットボットやライブエージェントに送信されるダイレクトメッセージなど)をTwilioに転送することを目標としました。
Flexフローの定義
最初のステップは、Twilioに送信するすべてのメッセージが正しい場所にルーティングされることを確認することです。ユーザーがライブエージェントをリクエストしたかどうかを最初にチェックし、そうであれば後続のメッセージをSeaXに転送するシンプルなTwilioフローを設定しました。ユーザーがライブエージェントをリクエストしていない場合、メッセージをチャットボットに転送して応答を得ます。フローの設定についての詳細は、Twilio Studio Flowドキュメントをご覧ください。

受信メッセージをチャットボットまたはSeaXにルーティングするシンプルなFlex Studioフロー。
カスタムチャンネルの作成
今、受信メッセージがどのようにルーティングされるかを理解しています。しかし、DiscordはTwilioによってネイティブにサポートされているチャンネルではありません。幸い、TwilioにはTwilio Flexにカスタムチャットチャンネルを追加する方法に関する詳細なチュートリアルがあります。Twilioで新しいカスタムチャンネルを設定するガイドに従った後、実際にDiscordからTwilioにメッセージを転送する必要があります。
まずTwilioクライアントを設定します:
from twilio.rest import Client
twilio_client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)
今、Discordから受信メッセージを受け取ると、Twilioクライアントを通じてそのメッセージをTwilioに転送できます。まず、ユーザーが既にTwilioシステムに存在し、既にオープンチャットチャンネルを持っているかどうかをチェックする必要があります。
# ユーザーが存在するかどうかをチェックするget_userメソッドを呼び出し、存在しない場合は新しいユーザーを作成
user = await get_user(user_id, twilio_client, TWILIO_SERVICE_SID)
# ユーザーのチャンネルを取得
user_channels = twilio_client.chat \
.services(TWILIO_SERVICE_SID) \
.users(user_id) \
.user_channels \
.list()
ユーザーが既存のオープンチャットチャンネルを持っている場合、チャット履歴にアクセスできるようにそれを使用する必要があります。既存のチャットチャンネルがない場合、ユーザーのために新しいものを作成します:
if user_channels:
channel_sid = user_channels[-1].channel_sid
else:
channel = twilio_client.flex_api \
.channel \
.create(
flex_flow_sid=FLEX_FLOW_ID,
chat_user_friendly_name=username,
chat_friendly_name=chat_name, # -> チャットチャンネルのフレンドリ名
target=conversation_id, # -> チャットユーザーを一意に識別するID
identity=conversation_id, # -> ユーザー、例 / Discord DM ID
)
channel_sid = channel.sid
最後に、DiscordユーザーとTwilioの間にオープンチャットチャンネルがあると、受信メッセージをTwilio Studioフローに転送できます。
message = twilio_client.chat \
.services(TWILIO_SERVICE_SID) \
.channels(channel_sid) \
.messages \
.create(
body=message_text,
from_=user_id,
x_twilio_webhook_enabled='true',
attributes=json.dumps(message_json) # 後でアクセスできるようにヘッダーを属性として送信
)
今、Discordユーザーからの受信メッセージをTwilio Flexフローに直接転送できます。Discordボット側では、すべてのダイレクトメッセージがTwilioに転送されることを確認してください。今、Discordボットにダイレクトメッセージを送信してみて、Twilio Studioフローログに表示されるはずです - しかし、まだ終わっていません!
より複雑なルーティングをサポートするHTTPサーバーの作成
送信メッセージWebhook
今、受信メッセージがどのようにルーティングされるかを理解しています。しかし、まだいくつかの部分が不足しています。まず、今Twilioにメッセージを送信できることを知っていますが、Discord上のユーザーにどのように返信するのでしょうか?私たちのDiscordボットは、Discordサーバーとユーザーにメッセージを送信する唯一の認可されたものであり、TwilioもメッセージをDiscordサーバーに戻す方法を知りません。解決策は、Twilioチャットチャンネルに新しいメッセージがあるたびにトリガーされる送信メッセージWebhookを設定する必要があることです。そのWebhookで、Discordボットを使用してメッセージをサーバーに転送できます。
このために、Discordボットをより強力なHTTPサーバーに統合します。FastAPIを使用して、送信メッセージWebhookとして機能するシンプルなPOSTエンドポイントを設定しました。サーバーを設定し、Discordボットがそれと一緒に動作すると、POSTエンドポイントを定義できます。
このエンドポイントはチャットチャンネルに追加されるすべてのメッセージを受け取るため、まずSeaXからの送信メッセージ以外のすべてを除外する必要があります。次に、メッセージをどこに転送するかを知るために、メッセージ本文から正しいチャンネルIDを取得する必要があります。最後に、Discordクライアントを使用してメッセージをDiscordチャンネルに転送できます。
@app.post("/forward-to-discord", status_code=200)
async def forward_discord_message(request: Request, response: Response) -> None:
raw_body = await request.body()
body = urllib.parse.parse_qs(raw_body.decode())
# SDKからのメッセージのみに焦点を当てる(Flex、他のすべてのメッセージはAPIから来る)
if not body.get('Source') == ['SDK']:
return
# Flexからのメッセージには元のメッセージのconversationIdが含まれていない
# GBM上の会話にメッセージを戻すためにconvIdが必要
# 前のメッセージを取得してconversationIdを抽出
message = twilio_client.chat \
.services(TWILIO_SERVICE_SID) \
.channels(body.get("ChannelSid")[0]) \
.messages.list(limit=1)[0]
attributes = json.loads(message.attributes)
channel = discord_client.get_channel(attributes.get("channel", {}).get("id"))
if channel:
await channel.send(body.get("Body", [""])[0].get("text"))
else:
logger.error(f"ID {get_channel_id(req)}のDiscordチャンネルが見つかりません!")
response.status_code = 400
最後に、メッセージをエンドポイントに送信するために、Twilioに新しいWebhookが何であるかを知らせる必要があります。各チャットチャンネルは独自のWebhookを設定する必要があります。したがって、元々ユーザーのために新しいチャットチャンネルを作成した場所に戻ると、Webhookを設定するための追加コードを追加できます:
webhook = twilio_client.chat \
.services(TWILIO_SERVICE_SID) \
.channels(channel_sid) \
.webhooks \
.create(
type='webhook',
configuration_url=f"{SERVER_HOST}/forward-to-discord",
configuration_method="POST",
configuration_filters=["onMessageSent", "onMessageUpdated", "onMediaMessageSent"]
)
ボット統合
今、SeaXからの送信メッセージが正しくDiscordサーバーにルーティングされるはずです。しかし、まだチャットボットに行くメッセージを処理していません。Twilio Studioフローからトリガーされ、ユーザーメッセージを受け取り、ボットにクエリを実行し、応答をDiscordに戻す最終エンドポイントを設定する必要があります。
@app.post("/chatbot-to-discord", status_code=200)
async def receive_discord_message(request: Request, response: Response):
"""TwilioからのPOSTリクエストを受け取り、ボットにクエリを実行し、応答をDiscordに戻す。"""
req = await request.body()
# 元のメッセージ本文をtwilioコンテンツから分離
twilio_body, original_message_body = separate_original_message_body(req.decode())
bot_response = await query_bot(original_message_body, bot_info)
if bot_response:
channel = discord_client.get_channel(original_message_body.get("channel_id"))
if channel:
for item in bot_response:
await channel.send(item.get("text"))
Twilio Studioフローがメッセージをボットにルーティングする正しいWebhookを持っていることを確認してください。今、メッセージルーティングが完了しました!この図でメッセージルーティングのトップレベルビューを見ることができます:

メッセージルーティング図。
まとめ
要約すると、このブログシリーズでは、Discordの普及と、ブランドが顧客と対話するための新しいプラットフォームとしてもたらす機会について議論しました。ブランドが独自のオンラインコミュニティを構築する方法を示すために、Discordの基本的な機能をいくつか紹介し、ブランドがDiscordボットを使用してサーバーでのモデレーションとカスタマーサポートを自動化できるより高度な機能も紹介しました。最後に、DiscordをカスタマーサービスプラットフォームSeaXと統合し、ライブエージェント転送、ケース管理、AI駆動のナレッジベース検索などの高度な機能をDiscordコミュニティにもたらす方法を共有しました。 個人的なデモや、Seasalt.aiが特定のビジネスニーズを満たすのにどのように役立つかを学ぶために、“デモを予約”フォームにご記入ください。Flex/Discord統合の詳細やお問い合わせについては、Seasalt.aiのTwilioパートナーリストをご覧ください。