PepperからTwilio経由で電話をかける

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

## はじめに

Twilioには、Pythonのヘルプライブラリがあるので、PepperのPython実行環境からRestAPI経由で電話をかけることができます。
コーディング自体は簡単ですが、準備がかなり多いので、忘れないように記事にしておきます。

### 前提条件

- Twilioのアカウントはすでに取得しているものとします。
 - AccountSID、AuthToken、発信用電話番号が必要です。トライアルアカウントでも利用は可能ですが、発信先電話番号は、認証済み電話番号のみとなります。 
- Pepperアプリ（Choregraphe）はすでにセットアップされているものとします。
 - 今回はMac版のVersion2.4.3を使います。Windowsでも動作します。 
- Python2.7.xの環境がセットアップされているものとします。 
 - 今回は、2.7.12を利用します。

## 手順

- TwilioのPythonヘルパーライブラリの準備します。
- 上記ライブラリに依存するライブラリの準備します。
- Choregrapheを使って、Pythonスクリプトを作成します。

### TwilioのPythonヘルパーライブラリを準備

1. TwilioのPythonヘルパーライブラリを[ダウンロード](https://github.com/twilio/twilio-python/zipball/master)します。
2. Zipファイルを解凍します。
3. 解凍されたフォルダの中のTwilioフォルダをどこかにコピーしておきます。

### 依存するライブラリを準備します。

Twilioのヘルパーライブラリは、いくつか別のライブラリを利用しています。
そのため、予め依存ライブラリをダウンロードしておきましょう。

#### httplib2

[httplib2のサイト](https://pypi.python.org/pypi/httplib2#downloads)から、最新版のzipファイルをダウンロードします。
今回は、httplib2-0.9.2.zipを利用します。
1. ダウンロードしたzipファイルを適当な場所に展開します。
2. 展開したフォルダに移動し、セットアップを実行します。

```lang:python
$ python setup.py install
```

インストールが完了すると、build¥libフォルダ内に、httplib2フォルダができるので、それをどこかにコピーしておきます。

#### pytz

[pytzのサイト](https://pypi.python.org/pypi/pytz/#downloads)から、最新版のzipファイルをダウンロードします。
今回は、pytz-2016.7.zipを利用します。
1. ダウンロードしたzipファイルを適当な場所に展開します。
2. 展開したフォルダに移動し、セットアップを実行します。

```lang:python
$ python setup.py install
```

インストールが完了すると、build¥libフォルダ内に、pytzフォルダができるので、それをどこかにコピーしておきます。

### Choregraphe上でPythonスクリプトを作成

#### ライブラリフォルダを設定する

Choregrapheのプロジェクトファイルウィンドウの「＋」ボタンを押し、「新規フォルダ...」を選択します。
<img width="254" alt="スクリーンショット 2016-11-05 16.33.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/2aad009e-e687-d6d9-4d28-70c6aca536af.png">

フォルダ名を「lib」にして、「Create」ボタンを押します。
<img width="205" alt="スクリーンショット 2016-11-05 16.33.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/19491b5c-96fe-b9c3-4d64-e40b3a2efbe7.png">

プロジェクトファイルウィンドウの「＋」ボタンを押し、「フォルダをインポート...」を選択します。
<img width="255" alt="スクリーンショット 2016-11-05 16.59.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/8dd3cded-b072-0843-7193-484e702b8dc9.png">

先程解凍しておいたTwilioフォルダを選択します。
同様の手順で、先程セットアップしておいたhttplib2フォルダとpytzフォルダも追加しておきます。
<img width="252" alt="スクリーンショット 2016-11-05 17.33.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/1868461d-a83a-d610-cf5d-1cc59618a197.png">

取り込んだフォルダをすべてlibフォルダの下に移動します。
<img width="253" alt="スクリーンショット 2016-11-05 17.48.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/f929cfb0-4f2b-295e-70d1-e72f72dcc58a.png">

#### ライブラリを読み込むスクリプトを作成する

ボックスライブラリのProgramming→Templatesから、「Python Scripts」をパネルにドラッグします。
<img width="862" alt="スクリーンショット 2016-11-05 18.09.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/f9457a86-d135-17bd-6881-621948a75f0d.png">

ドラッグしたボックスをダブルクリックし、スクリプトエディタを開きます。
<img width="802" alt="スクリーンショット 2016-11-05 18.14.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/ddf303c0-94fb-a596-b653-c41709fef775.png">

既存のコードをすべて削除し、以下のコードを貼り付けます。

```lang:Python
class MyClass(GeneratedClass):
    def __init__(self):
        GeneratedClass.__init__(self)

    def onLoad(self):
        self.pathModified = False

    def onUnload(self):
        if self.pathModified and self.folderName and self.folderName in sys.path:
            sys.path.remove(self.folderName)
        self.folderName = None

    def onInput_onStart(self):
        appFolder = self.behaviorAbsolutePath().replace(self.behaviorRelativePath(), "")
        self.folderName = os.path.join(appFolder, "lib")
        if self.folderName not in sys.path:
            sys.path.append(self.folderName)
            self.pathModified = True

        self.onStopped()

    def onInput_onStop(self):
        self.onUnload() #it is recommended to reuse the clean-up as the box is stopped
        self.onStopped() #activate the output of the box
```

これで、起動時にライブラリフォルダ（libフォルダ）が参照されるようになります。
*2017/1/4 コードに間違いがあったため、一部修正*

#### 電話をかけるスクリプトを作成する

先程と同じようにボックスライブラリから２つ目のPython Scriptsボックスをパネルにドラッグします。
<img width="1212" alt="スクリーンショット 2016-11-05 18.19.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/36520e9d-4113-90d1-87c2-0aafb9a38a72.png">

ドラッグしたボックスをダブルクリックして、スクリプトエディタ画面を表示します。
すでに書かれているコードは一度すべて消していただき、以下のコードを上書きします。

```lang:Python
class MyClass(GeneratedClass):
    def __init__(self):
        GeneratedClass.__init__(self)

    def onLoad(self):
        #put initialization code here
        pass

    def onUnload(self):
        #put clean-up code here
        pass

    def onInput_onStart(self):
        #self.onStopped() #activate the output of the box
        from twilio.rest import TwilioRestClient

        # put your own credentials here
        ACCOUNT_SID = 'ACXXXXXXXXXXX'
        AUTH_TOKEN = 'XXXXXXXXXXX'
        client = TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN)

        client.calls.create(to='+8190XXXXXXXX', from_='+8150XXXXXXXX', url='http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient')
        self.onStopped()

    def onInput_onStop(self):
        self.onUnload() #it is recommended to reuse the clean-up as the box is stopped
        self.onStopped() #activate the output of the box
```

ACCOUNT_SIDとAUTH_TOKENは、それぞれご自分のTwilioのアカウントSIDとAuthTokenを記載します。
client.calls.create関数の中にある、toは宛先電話番号、fromは発信者番号になります。発信者番号はTwilioで購入した番号を指定します。また、Twilioのトライアルアカウントをご利用の場合は、認証済みの番号にのみ発信が可能です。
urlは、TwiMLを返すためのWebHookになっています。今回は、予め用意してある保留音が流れるようになっています。

以上で準備は終了です。

### フローを作成してテストする

#### フローを作成する

パネル上で、以下の画像と同じようにフローの線を引きます。
<img width="617" alt="スクリーンショット 2016-11-05 18.32.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/9822d2c3-5e72-870c-b6d8-d6d7f6b2aba9.png">

#### テストする

Pepperと接続を行い、テストをしてみましょう。
しばらくすると電話がかかってくれば成功です。