Twilio ConversationsとVue.jsでチャットアプリケーションを作る(後編)
Time to read:
フロントエンドを構築する
フロントエンド側はVueコンポーネントを使って構築します。このチャットアプリケーションで使用するコンポーネントはシングルファイルコンポーネント(Single file component)と呼ばれる、.vue拡張子のコンポーネントです。シングルファイルコンポーネントを使うと、HTMLテンプレート、JavaScriptのロジック、CSSのスタイリングを一つのファイルにまとめることができます。
まずはVue CLIがデフォルトで作成するHelloWorld.vueコンポーネントを削除し、Chat.vueとConversation.vueコンポーネントを作成します。ターミナルで新しいウィンドウを開き、プロジェクトのルートディレクトリから以下のコマンドを実行してください。
Chat.vueを作成する
まずは、チャット画面全体を構成するコンポーネントとなるChat.vueを構築します。
シングルファイルコンポーネントは<template>、<script>、<style>の3つの部分に分かれています。まずはチャット画面のHTMLを<template>で定義します。
テキストエディタでChat.vueを開き、以下のコードをペーストしてください。
次に、HTMLに<style>を使ってCSSスタイルを追加します。<template>ブロックの下に以下のコードを追加してください。
<style scoped>のscoped属性は現在のコンポーネントの要素にのみCSSを適用するために使用されます。
次に、JavaScriptのロジックを<script>を使って追加していきます。<template>ブロックと<style>ブロックの間に以下のコードを追加します。
このコードでは、Twilio Conversationsの機能にアクセスするためのスタート地点となる@twilio/conversationsのClientオブジェクトと、子コンポーネントとして使用するConversationコンポーネントをインポートしています。
また、dataメソッドでアプリケーション上で随時変化するデータをオブジェクトとして登録することにより、変更が起こるたびにVue.jsが検知して再レンダリングが行われるようにしています。
次に、これらのデータを操作するための関数をmethodsオブジェクトで定義します。methodsはユーザーのアクションなどDOM上で発生するイベントに対する処理を行う関数です。
まず、Clientオブジェクトを初期化するためのinitConversationsClientメソッドを作成します。initConversationsClientはユーザー名が入力されたタイミングで実行されるようにします。export defaultの配下、data()メソッドの下に、以下のコードをペーストしてください。
一番最初にユーザー名を入力したユーザーが「メインユーザー」として扱われ、ConversationsClient.create(token)でクライアントを割り当てます。
Conversationsクライアントを作成するには、アクセストークンが必要です。アクセストークンを取得するgetToken()メソッドの処理が終わってからクライアントを作成する必要があるため、initConversationsClientメソッドはasync/awaitを使って非同期関数として定義しています。
また、conversationsClient.onイベントリスナーを使って、チャットへの接続ステータスが変更する度にUIに表示するメッセージを変更します。
次に、サーバー側で設定した/auth/user/:userエンドポイントにGETリクエストを送り、ユーザーごとのアクセストークンを取得するためのgetTokenメソッドを作成します。
initConversationsClientメソッドの下に、以下のコードを追加します。
getTokenメソッドも/auth/user/:userエンドポイントからのレスポンスが返ってくるまで待つ必要があるため、async/awaitの非同期処理を使用します。
次にユーザー名を登録するためのregisterNameメソッドを作成します。getTokenメソッドの下に以下のコードを追加します。
このメソッドは、initConversationsClientの処理が終わった後にユーザーがユーザー名を入力したことを表すnameRegisteredプロパティを更新します。
次に、新しい会話を作成するためのcreateConversationメソッドを作成します。registerNameメソッドの下に以下のコードを追加します。
このメソッドでは、try...catchでメインユーザー以外のユーザーである「User1」、「User2」がクライアントを保持しているかをgetUserメソッドで確認します。もしまだ保持していない場合、「Waiting for User1 and User2 client sessions」エラーメッセージを出力します。
次にnewConversation.join()を使って非同期処理で新しい会話を作成し、「User1」と「User2」をjoinedConversation.addで会話に追加します。すでに会話が存在する場合は、activeConversationをgetConversationByUniqueNameで取得した既存の会話に設定します。
これでChat.vueコンポーネントが完成しました!Chat.vueコンポーネントが正しく表示されるよう、App.vueルートコンポーネントを編集しましょう。
テキストエディターでApp.vueコンポーネントを開き、内容を以下のコードに変更します。
Chat.vueの表示を確認しましょう。ターミナルの二つ目のウィンドウで、以下のコマンドを実行してください。
一つ目のターミナルのウィンドウでサーバーが引き続き動いていることを確認してから、http://localhost:8080/をブラウザで開いてください。以下のような画面が表示されます。
あなたの名前を入力して「Register name」をクリックしてみてください。すると、以下のように画面がアップデートされます。
これでユーザーが入場するまでの画面の準備ができました。次にチャット部分を構築するConversation.vueにコードを追加していきましょう。
Conversation.vueを作成する
テキストエディターでConversation.vueを開きます。まずはChat.vueと同様にHTMLテンプレートを追加します。以下のコードをペーストしてください。
次に、CSSを追加します。<template>ブロックの下に以下のコードをペーストしてください。
次にJavaScriptロジックを追加します。<template>ブロックと<style>ブロックの間に以下のコードを追加します。
ここでは、propsをインポートしています。Propsは親コンポーネントから子コンポーネントにデータを渡すために使われます。このチャットアプリケーションでは、Chat.vueが親コンポーネント、Conversations.vueが子コンポーネントです。Chat.vueを確認すると、<template>で以下のように現在ユーザーが入場しているチャットactiveConversationとユーザー名のnameを受け渡しています。
次に、過去に受信したユーザーからのメッセージを表示し、新しく送信されるメッセージに対するイベントリスナーを設定する処理を追加します。export defaultの配下、data()メソッドの下に、以下のコードをペーストしてください。
ここではmounted()を使用しています。mounted()は、Vue.jsのライフサイクルフックの一つで、コンポーネントがDOMに追加されたタイミングで呼び出されます。ユーザーがチャットに入場し、チャット画面がDOMに追加されたタイミングでこれまでに送信されたメッセージを取得し、画面に表示させます。また、activeConversation.onイベントリスナーを設定し、これから送信されるメッセージを受け取る準備をします。新しく送信されたメッセージは分割代入 (Destructuring assignment)を使ってmessages配列に追加します。
次に、ユーザーがメッセージを送信した際の処理を定義します。mounted()の下に次のコードをペーストしてください。
methodsでsendMessageメソッドを定義します。メッセージの送信処理を行い、処理完了後にメッセージ入力のためのテキストエリアを空にするためにmessageTextを空文字列に設定します。
お疲れ様でした!以上でConversation.vueの設定が完了しました!それでは完成したアプリケーションを検証してみましょう。
チャットアプリケーションを動作検証する
ターミナルの一つ目のウィンドウでサーバーが引き続き動いていて、二つ目のウィンドウでVue CLIが起動していることを確認してください。
すでに開いているブラウザのウィンドウに加えて、ウィンドウをさらに2つ開き、http://localhost:8080/にアクセスします。
新しく開いた一つ目のウィンドウからユーザー名「User1」と、二つ目のウィンドウからユーザー名「User2」を入力し、それぞれ「Register name」をクリックしユーザーを作成てください。
次に、メインユーザー、「User1」と「User2」それぞれの画面で「Join chat」をクリックしてください。
すると、チャット画面が表示されます。
もし「Join chat」をクリックしても何も起こらない場合は、メインユーザーのウィンドウでブラウザの開発者コンソールを開いてみてください。「Join chat」をクリックすると「Waiting for User1 and User2 client sessions」メッセージが表示される場合、「User1」と「User2」にクライアントが存在しないことを意味します。ウィンドウを2つ開き、「User1」と「User2」を登録してから再度「Join chat」を試してください。
それではメッセージを送ってみましょう。メインユーザーの画面からメッセージをフォームに入力し、「Send message」ボタンをクリックしてください。
「User1」の画面を開くと、メインユーザーからのメッセージが確認できます。
「User1」からもメッセージを送ってみましょう。メッセージをフォームに入力し、「Send message」ボタンをクリックしてください。
「User2」の画面を開くと、メインユーザーと「User1」からのメッセージが確認できます。
次のステップ
お疲れ様です。Twilio ConversationsとVue.jsを使ったチャットアプリケーションが完成しました。さらに開発を進めたい方は、このアプリケーションにTwilio Syncを追加してオンラインステータスを共有できるようにしてみたり、Typing Indicatorを使ってユーザーがタイピングしている時に「User1がタイピングしています」などのステータスを表示させてみてはいかがでしょうか?
これまでに使用したコードはすべてGithubリポジトリでご確認いただけます。また、Vue.jsについてもっと知りたい方は、Vue.js公式ドキュメントを参照してください。
Twilio Blogに投稿してみたい方や、フィードバック、登壇、勉強会のお誘いなど気軽にsnakajima[at]twilio.comまでご連絡ください。開発中のプロジェクトに関してはGithub(smwilk)を覗いてみて下さい。