メニュー

Expand
Rate this page:

Thanks for rating this page!

We are always striving to improve our documentation quality, and your feedback is valuable to us. How could this documentation serve you better?

Worker.jsを使用してワーカー・アクティビティーを制御する担当者 UI をプロジェクトに追加する

担当者 UI を始めましょう。これまでこのチュートリアルの規約に従っていれば、作成する UI はウェブブラウザーを使ってアクセスできます。

http://localhost:8080/agent.cshtml?WorkerSid=WK01234012340123401234 (Alice の WorkerSid に書き換えてください)

デモでは複雑なユーザー管理を実装しなくても済むように、WorkerSid を URL に渡します。実際には、他のユーザー属性と一緒に、ユーザーの WorkerSid をデータベースに格納する可能性があります。

ここで、URLがリクエストされたときにレンダリングされる CSHTML ファイルを作成しましょう:

agent.cshtml

  @using System;
  @using System.Collections.Generic;
  @using Twilio;
  @using Twilio.Http;
  @using Twilio.Jwt.Taskrouter;

  @{
     class PolicyUrlUtils
    {
        const string taskRouterBaseUrl = "https://taskrouter.twilio.com";
        const string taskRouterVersion = "v1";

        readonly string _workspaceSid;
        readonly string _workerSid;

        public PolicyUrlUtils(string workspaceSid, string workerSid)
        {
            _workspaceSid = workspaceSid;
            _workerSid = workerSid;
        }

        public string AllTasks => $"{Workspace}/Tasks/**";

        public string Worker => $"{Workspace}/Workers/{_workerSid}";

        public string AllReservations => $"{Worker}/Reservations/**";

        public string Workspace =>
            $"{taskRouterBaseUrl}/{taskRouterVersion}/Workspaces/{_workspaceSid}";

        public string Activities => $"{Workspace}/Activities";

    }

  @{
        // put your Twilio API credentials here
        const string accountSid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        const string authToken = "your_auth_token";
        const string workspaceSid = "WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        const string workerSid = "WKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

        var updateActivityFilter = new Dictionary<string, Policy.FilterRequirement>
        {
            { "ActivitySid", Policy.FilterRequirement.Required }
        };

        var urls = new PolicyUrlUtils(workspaceSid, workerSid);

        var allowActivityUpdates = new Policy(urls.Worker,
                                              HttpMethod.Post,
                                              postFilter: updateActivityFilter);
        var allowTasksUpdate = new Policy(urls.AllTasks, HttpMethod.Post);
        var allowReservationUpdate = new Policy(urls.AllReservations, HttpMethod.Post);
        var allowWorkerFetches = new Policy(urls.Worker, HttpMethod.Get);
        var allowTasksFetches = new Policy(urls.AllTasks, HttpMethod.Get );
        var allowReservationFetches = new Policy(urls.AllReservations, HttpMethod.Get);
        var allowActivityFetches = new Policy(urls.Activities, HttpMethod.Get);

        var policies = new List<Policy>
        {
            allowActivityUpdates,
            allowTasksUpdate,
            allowReservationUpdate,
            allowWorkerFetches,
            allowTasksFetches,
            allowReservationFetches

        };

        var capability = new TaskRouterCapability(
            accountSid,
            authToken,
            workspaceSid,
            workerSid,
            policies: policies); 

        var workerToken = capability.ToJwt();
    }
  <!DOCTYPE html>
  <html>
  <head>
      <title>Customer Care - Voice Agent Screen</title>
      <link rel="stylesheet" href="//media.twiliocdn.com/taskrouter/quickstart/agent.css"/>
      <script src="//media.twiliocdn.com/taskrouter/js/v1.14/taskrouter.min.js"></script>
      <script type="text/javascript">
          /* Subscribe to a subset of the available TaskRouter.js events for a worker */
          function registerTaskRouterCallbacks() {
              worker.on('ready', function(worker) {
                  agentActivityChanged(worker.activityName);
                  logger("Successfully registered as: " + worker.friendlyName)
                  logger("Current activity is: " + worker.activityName);
              });

              worker.on('activity.update', function(worker) {
                  agentActivityChanged(worker.activityName);
                  logger("Worker activity changed to: " + worker.activityName);
              });

              worker.on("reservation.created", function(reservation) {
                  logger("-----");
                  logger("You have been reserved to handle a call!");
                  logger("Call from: " + reservation.task.attributes.from);
                  logger("Selected language: " + reservation.task.attributes.selected_language);
                  logger("-----");
              });

              worker.on("reservation.accepted", function(reservation) {
                  logger("Reservation " + reservation.sid + " accepted!");
              });

              worker.on("reservation.rejected", function(reservation) {
                  logger("Reservation " + reservation.sid + " rejected!");
              });

              worker.on("reservation.timeout", function(reservation) {
                  logger("Reservation " + reservation.sid + " timed out!");
              });

              worker.on("reservation.canceled", function(reservation) {
                  logger("Reservation " + reservation.sid + " canceled!");
              });
          }

          /* Hook up the agent Activity buttons to TaskRouter.js */

          function bindAgentActivityButtons() {
              // Fetch the full list of available Activities from TaskRouter. Store each
              // ActivitySid against the matching Friendly Name
              var activitySids = {};
              worker.activities.fetch(function(error, activityList) {
                  var activities = activityList.data;
                  var i = activities.length;
                  while (i--) {
                      activitySids[activities[i].friendlyName] = activities[i].sid;
                  }
              });

              /* For each button of class 'change-activity' in our Agent UI, look up the
               ActivitySid corresponding to the Friendly Name in the button’s next-activity
               data attribute. Use Worker.js to transition the agent to that ActivitySid
               when the button is clicked.*/
              var elements = document.getElementsByClassName('change-activity');
              var i = elements.length;
              while (i--) {
                  elements[i].onclick = function() {
                      var nextActivity = this.dataset.nextActivity;
                      var nextActivitySid = activitySids[nextActivity];
                      worker.update({"ActivitySid":nextActivitySid});
                  }
              }
          }

          /* Update the UI to reflect a change in Activity */

          function agentActivityChanged(activity) {
              hideAgentActivities();
              showAgentActivity(activity);
          }

          function hideAgentActivities() {
              var elements = document.getElementsByClassName('agent-activity');
              var i = elements.length;
              while (i--) {
                  elements[i].style.display = 'none';
              }
          }

          function showAgentActivity(activity) {
              activity = activity.toLowerCase();
              var elements = document.getElementsByClassName(('agent-activity ' + activity));
              elements.item(0).style.display = 'block';
          }

          /* Other stuff */

          function logger(message) {
              var log = document.getElementById('log');
              log.value += "\n> " + message;
              log.scrollTop = log.scrollHeight;
          }

          window.onload = function() {
              // Initialize TaskRouter.js on page load using window.workerToken -
              // a Twilio Capability token that was set from rendering the template with agents endpoint
              logger("Initializing...");
              window.worker = new Twilio.TaskRouter.Worker("@workerToken");

              registerTaskRouterCallbacks();
              bindAgentActivityButtons();
          };
      </script>
  </head>
  <body>
  <div class="content">
      <section class="agent-activity offline">
          <p class="activity">Offline</p>
          <button class="change-activity" data-next-activity="Idle">Go Available</button>
      </section>
      <section class="agent-activity idle">
          <p class="activity"><span>Available</span></p>
          <button class="change-activity" data-next-activity="Offline">Go Offline</button>
      </section>
      <section class="agent-activity reserved">
          <p class="activity">Reserved</p>
      </section>
      <section class="agent-activity busy">
          <p class="activity">Busy</p>
      </section>
      <section class="agent-activity wrapup">
          <p class="activity">Wrap-Up</p>
          <button class="change-activity" data-next-activity="Idle">Go Available</button>
          <button class="change-activity" data-next-activity="Offline">Go Offline</button>
      </section>
      <section class="log">
        <textarea id="log" readonly="true"></textarea>
      </section>
  </div>
  </body>
  </html>

お気づきのように、外部ファイルを 2 つ取り込みました。

  • taskrouter.min.jsは、プライマリーなTaskRouter.js JavaScriptファイルで、私達に代わってTaskRouterのインフラストラクチャーと通信します。 このURLを使い、本番アプリケーションにWorker.jsを取り込むことができますが、最新バージョンを取り込むために、まずリファレンスドキュメントを参照してください。
  • agent.css は、このクイックスタート用に作成された単純な CSS ファイルです。事前に定義された単純なスタイルを入力する手間を省きます。

以上で作業は完了です! Javaクラスをコンパイルし、サーバーを開始させましょう。

ブラウザーで http://localhost:8080/agent.cshtml?WorkerSid=WK01234012340123401234 を開くと、以下の画面が表示されます。パート 3 と同じ電話に発信した場合、予約を受け、タスクの処理に割り当てられた Alice のアクティビティーの遷移が画面に表示されます。

「Initializing...」と表示されたまま、何の進捗もない場合は、URL の「WorkerSid」リクエストパラメーターに正しい WorkerSid を指定したか確認してください。

詳細については、TaskRouter JavaScript SDKドキュメントを参照してください。

完成した担当者 UI

  • この単純な PoC は、IE 11. * など、一般的なブラウザーの最新バージョンでテスト済みです。

Rate this page:

ヘルプが必要ですか?

誰しもが一度は考える「コーディングって難しい」。そんな時は、お問い合わせフォームから質問してください。 または、Stack Overflow でTwilioタグのついた情報から欲しいものを探してみましょう。