1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。

はじめに

みなさん、こんにちは。
KDDIウェブコミュニケーションズのTwilioエバンジェリストの高橋です。

Twilio Flex Advent Calendar 2021の17日目の記事となります。
前回の記事では、Flexプラグインを使って着信音を鳴らす方法を紹介しました。着信音を鳴らすにはとくにUIに関するカスタマイズは不要でしたが、今回はいよいよUIをカスタマイズしていきましょう。

シナリオ

今回のカスタマイズの前提となるシナリオは以下のとおりです。

  • 顧客DBには、顧客の電話番号や名前、住所が含まれています。
  • 着信時に顧客情報を電話番号で検索します。
  • 顧客が存在する場合のみ、以下の処理を行います。
    • 着信者の名前を表示する。
    • 顧客の住所を地図にプロットして表示する。

スクリーンショット 2021-12-23 13.18.33.png

顧客DBとしては、こちらの記事で使用したGoogleSpreadsheetを流用し、住所情報を追加します。項目名は「住所」にしておいてください。
スクリーンショット 2021-12-23 13.22.41.png

地図情報と、住所情報を緯度経度に変換する(ジオコーディング)には、Google MapsAPIとGeoCodingAPIを利用します。GeoCodingAPIについては有料のAPIとなりますが、月$200の無料枠があります。Google Mapsの料金についてはこちらを参照してください。

なおGoogle GeoCoding APIは規約上、GoogleMapと一緒に利用しなくてはいけないため、ジオコーディングはFlexプラグイン内で行うこととし、Studioフローでは住所情報をTaskのAttributesに追加するのみとします。

Flex UIコンポーネント

まずは地図情報をFlexのどこに表示するかを設計する必要があります。
Flex UIコンポーネント(エージェント画面)は以下のように定義されています。

Overview-agentUI_2.width-800.png
https://www.twilio.com/docs/flex/developer/ui/components より引用

住所情報は、Taskに紐付いて通知されるため、⑪のTaskCanvasTabsに「位置情報」というタブを作って、そこに表示させるのが良さそうです。
タブの生成方法は以下の通りです。

    flex.TaskCanvasTabs.Content.add(
      <Tab label="位置情報" key="geolocation-tab">
        <GeoLocation key="geolocation-component" />
      </Tab>
    );

このコードを、プラグインのinit()の中に記載すればOKです。
なお、タブのコンテンツとなるGeoLocationは後ほどReactコンポーネントとして作成する必要があります。

ハンズオン

では早速プラグインを作成していきましょう。

プラグインの新規作成

CLIを使って、Flexプラグインプロジェクトの作成していきます。
どこか作業フォルダに移動して、以下のコマンドを入力します。

% twilio flex:plugins:create plugin-geolocation --install
・・・
% cd plugin-geolocation

GoogleのAPIキーを取得する

事前にGCP(Google Cloud Platform)のアカウントを取得しているものとします。

  • Google Cloud Platformにログインします。
  • APIとサービスの中のライブラリを選択します。
  • 「Maps」でサービスを検索します。
  • 「Maps JavaScript API」を選択します。

スクリーンショット 2021-12-23 7.51.20.png

  • 有効にするを押します。

Google Maps Platformの画面に遷移します。

スクリーンショット 2021-12-23 7.55.18.png

  • 認証情報を選択します。
  • 画面上部にある認証情報を作成を押します。
  • プルダウンメニューからAPIキーを選択します。

スクリーンショット 2021-12-23 7.58.11.png

  • APIキーが生成されるので、内容をメモ帳などにコピーしておきます。※必要に応じてキーの制限をかけておきましょう。

では次に、Geocoding APIを有効にします。

スクリーンショット 2021-12-23 8.01.10.png

  • APIを選択します。

  • APIの一覧からGeocoding APIを選択します。
    スクリーンショット 2021-12-23 8.03.59.png

  • 有効にするを押します。

  • 以下のように2つのAPIが有効になっていればOKです。
    スクリーンショット 2021-12-23 8.05.11.png

環境変数として登録

  • Flexプラグインのプロジェクトフォルダの直下に.envという名前のファイルを作成します。
  • 先程控えておいたAPIキーをFLEX_APP_GOOGLE_API_KEY=XXXXXXXXXXXXXXXXXXXXXと登録しておきます。

スクリーンショット 2021-12-23 11.43.49.png

なお、Flexプラグイン内で環境変数にアクセスするためには、以下の手順を行っておく必要があります。
Flexプラグイン Tips(環境変数の利用)

Google Maps APIのライブラリをインストール

今回はReact用の高機能なライブラリである、@react-google-maps/apiを利用したいと思います。
ただし、このライブラリはReact16.8以上を必要とするため、FlexのReactバージョン(React16.5.2)では動作しません。そこでFlex側もReact16.13.1に上げておきましょう。
以下のコマンドを使って、それぞれをインストールします。

% npm i -S react@16.13.1 react-dom@16.13.1
% npm i -S @react-google-maps/api

package.jsonは以下のようになります。

{
  "name": "plugin-geolocation",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "postinstall": "flex-plugin pre-script-check"
  },
  "dependencies": {
    "@react-google-maps/api": "^2.7.0",
    "flex-plugin-scripts": "4.2.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "devDependencies": {
    "@twilio/flex-ui": "^1",
    "dotenv-webpack": "^7.0.3",
    "react-test-renderer": "16.5.2"
  }
}

地図を表示するコンポーネントの作成

  • エディタを開き、src/componentsフォルダの配下に、GeoLocationフォルダを新規作成します。

  • 更にその配下にGeoLocation.jsxというファイルを作成します。
    スクリーンショット 2021-12-23 13.36.39.png

  • GeoLocation.jsに以下のコードを貼り付けます。

import React, { useCallback, useRef, useState } from 'react';
import { withTaskContext } from '@twilio/flex-ui';
import { GoogleMap, LoadScript, Marker } from "@react-google-maps/api";

const libraries = ["places"];
const mapContainerStyle = {
  height: "60vh",
  width: "100%",
};  // 地図の大きさ

const options = {
  disableDefaultUI: true,  // デフォルトUI(衛星写真オプションなど)をキャンセルします。
  zoomControl: true,
};

const GeoLocation = (props) => {
  if (!props.task) return null;

  const [center, setCenter] = useState({ lat: 35.6802117, lng: 139.7576692 });

  // 住所をtask.attributesから取得する
  const { address = null } = props.task.attributes;
  if (!address) return (<div>住所情報なし</div>);

  const mapRef = useRef();
  const onMapLoad = useCallback((map) => {
    mapRef.current = map;
    geoCode();
  }, []);

  // 住所から位置情報を取得
  const geoCode = () => {
    const geoCoder = new window.google.maps.Geocoder();
    geoCoder.geocode({
      address,
      region: 'jp',
    }, (results, status) => {
      setCenter({
        lat: results[0].geometry.location.lat(),
        lng: results[0].geometry.location.lng(),
      });
    });
  };

  return (
    <LoadScript googleMapsApiKey={process.env.FLEX_APP_GOOGLE_API_KEY}>
      <GoogleMap
        key="GeoLocation-map"
        id="map"
        mapContainerStyle={mapContainerStyle}
        zoom={17}
        center={center}
        options={options}
        onLoad={onMapLoad}
      >
        <Marker position={center} />
      </GoogleMap>
    </LoadScript>
   )
};

export default withTaskContext(GeoLocation);

コードの解説

Flexプラグインのコンポーネント内から、TaskのAttributesを参照するためには、コンポーネントに対して@twilio/flex-uiwithTaskContextをラップしてあげる必要があります。
コードの一番下に、

export default withTaskContext(GeoLocation);

と書かれている部分がそれです。
このようにすることで、コンポーネントのプロパティにtaskというオブジェクトが入ってきます。

コードの後半に地図を表示させる部分があります。

  return (
    <LoadScript googleMapsApiKey={process.env.FLEX_APP_GOOGLE_API_KEY}>
      <GoogleMap
        key="GeoLocation-map"
        id="map"
        mapContainerStyle={mapContainerStyle}
        zoom={17}
        center={center}
        options={options}
        onLoad={onMapLoad}
      >
        <Marker position={center} />
      </GoogleMap>
    </LoadScript>
   )

まず、<LoadScript>タグを使ってGoogleMapsAPIの認証を行うとともに、windowオブジェクト内にgoogleオブジェクトが生成されます。このgoogleオブジェクトを使ってジオコーディングを行います。

const geoCoder = new window.google.maps.Geocoder();

このようにしてジオコーダーのインスタンスを生成します。
実際のジオコーディングは、<GoogleMap>がロードされたときのイベント内で実行するようにしています。
なお、ジオコーディングの公式ドキュメントはこちらにあります。

GeoLocationコンポーネント呼び出す

つぎに、src/GeolocationPlugin.jsをエディタで開きます。

import React from 'react';
import { VERSION, Tab } from '@twilio/flex-ui';
import { FlexPlugin } from 'flex-plugin';

import GeoLocation from './components/GeoLocation/GeoLocation';
import reducers, { namespace } from './states';

const PLUGIN_NAME = 'GeolocationPlugin';

export default class GeolocationPlugin extends FlexPlugin {
  constructor() {
    super(PLUGIN_NAME);
  }

  /**
   * This code is run when your plugin is being started
   * Use this to modify any UI components or attach to the actions framework
   *
   * @param flex { typeof import('@twilio/flex-ui') }
   * @param manager { import('@twilio/flex-ui').Manager }
   */
  async init(flex, manager) {
    this.registerReducers(manager);

    flex.TaskCanvasTabs.Content.add(
      <Tab label='Location' key='GeoLocation-tab'>
        <GeoLocation key='GeoLocation-component' />
      </Tab>,
    );
  }

  /**
   * Registers the plugin reducers
   *
   * @param manager { Flex.Manager }
   */
  registerReducers(manager) {
    if (!manager.store.addReducer) {
      // eslint-disable-next-line
      console.error(
        `You need FlexUI > 1.9.0 to use built-in redux; you are currently on ${VERSION}`,
      );
      return;
    }

    manager.store.addReducer(namespace, reducers);
  }
}

自動的に作成される余計なコードを削除しています。
また、5行目でGeoLocationコンポーネントをインポートしています。
TaskCanvasにタブを追加するのは25行目からです。

    flex.TaskCanvasTabs.Content.add(
      <Tab label='Location' key='GeoLocation-tab'>
        <GeoLocation key='GeoLocation-component' />
      </Tab>,
    );

Studioフローの修正

では最後に、住所をTaskのAttributesに入れる部分を作りましょう。

今回は次のようなフローを作成しました。

スクリーンショット 2021-12-23 14.01.00.png

  • Run Functionウィジェットを使って、GoogleSpreadsheetから住所を取得します。
  • Functionは、こちらの記事で作成したものをそのまま利用しています。

TaskRouterへの引き渡しは以下のとおりです。

スクリーンショット 2021-12-23 13.59.13.png

  • WORKFLOWは、「Assign to Anyone」にしていますが、どのワークフローでも構いません。
  • ATTRIBUTESの中で、addressパラメータにFunctionで取得した住所(widgets.getCustomer.parsed['住所'])を入れています。

電話番号への紐付け

今作成したStudioフローを着信番号に割り当てれば、とりあえず設定はすべて終了です。

テスト

  • GoogleSpreadsheetに住所を設定します。
  • ローカルでプラグインを起動してみましょう。
% twilio flex:plugins:start

localhost:3000でFlexが起動しますので、設定した電話番号からFlexに架電をしてみましょう。

スクリーンショット 2021-12-23 13.18.33.png

  • 着信が来たら、着信タスクをクリックします(着信ボタンを押さなくても位置情報は確認できます)。
  • 右側にタスクの詳細パネルが開きます。
  • LOCATIONタブを選択すると図のように住所に合わせた地図が表示されます。

なお、このプラグインを本番環境にデプロイしようとするとReactのバージョンが合わないがどうするかと聞かれてしまいます。
そのため、サーバー側もReactのバージョンを上げておく必要があります。

  • 管理者権限を持ったユーザがFlexにログインします。

スクリーンショット 2021-12-23 14.31.20.png

  • ダッシュボードパネルから、DEVELOPER SETUPEDITボタンを押します。

スクリーンショット 2021-12-23 14.28.54.png

  • Reactのバージョンを選択できるので、最新の「16.13.1」にあげておきましょう。

まとめ

今回はかなり大掛かりなカスタマイズでしたが、うまくいきましたでしょうか。
Flex UIがカスタマイズできるようになると、かなりいろいろなことができるのがおわかりいただけたかと思います。
Flexの魅力はなんといってもカスタマイズ性の高さになります。ReactやUIコンポーネントなど細かいところは色々と勉強しなくてはいけないですが、その可能性は非常に大きいです。

★次の記事
Twilio Flexで営業時間判定


Twilio(トゥイリオ)とは

https://cloudapi.kddi-web.com
Twilioは音声通話、メッセージング(SMS/チャット)、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウドAPIサービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。

自己紹介  
高橋克己(Katsumi Takahashi) 自称「赤い芸人
グローバル・インターネット・ジャパン株式会社 代表取締役
株式会社KDDIウェブコミュニケーションズ Twilio事業部エバンジェリスト

2001年より大手通信事業者の法人サービスの教育に携わり、企業における電話のしくみや重要性を研究。2016年よりTwilio事業部にジョインし、Twilioを使ったスマートコミュニケーションの普及活動を精力的に行っている。
2019 Twilio Champions
1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?