GAS de Vonage!! 

# はじめに
:christmas_tree:Merry Christmas:christmas_tree:
Advent Calenderがきっかけで、Vonageに初めて触れました。
つい先日まで、Vonageって何？そもそもCPaaS（Communication Platform as a Service）って何？っていう状態でしたが、触ってみると面白い。

今回はGAS（Google Apps Script）で実装をしていきます。ネット上にもGASで実装した記事はかなり少ないというかほとんど無かったので、誰かの参考になれば幸いです。
（GASで実装する機会はほとんどないかもしれないですが笑）

ちなみに、公式ドキュメントは様々な言語での参考コードが豊富にありますので、ご興味ある方は公式サイトのデベロッパーセンターをあたってみると良いです。

https://www.vonagebusiness.jp/developer-center/?icmp=megamenu|mainnav_gotothedevelopercenter_novalue

https://qiita.com/advent-calendar/2022/vonage

# 今回作ったもの
## 概要
GASで、VonageAPIを利用してSMS送信した後に、発生コストとVonage残高を、Facebook messengerからメッセージを送ります。
## 実行結果
### iPhone12の通知画面
![IMG_3405 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/0d45a8ab-b48b-51c7-b25a-02990502e8aa.png)
### SMSアプリ画面
![IMG_34072.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/fe5668bc-7077-076d-1053-688954121c53.png)
### Facebook Messengerアプリ画面
![IMG_34062.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/70cdb908-5e4d-784d-d196-509fc56aac39.png)

## コード全文
先に今回作成したコードを載せておきます。一部、秘匿情報があるので「***********」で潰してますが、ご了承ください。

```javascript:Google Apps Script
//メインシナリオ
const main = () => {
  //SMS送信先を指定
  const targetNumber = '***********'
  //FB送信元を指定
  const fromFBId = '***********'
  //FB送信先を指定
  const toFBId = '***********'

  //SMSメッセージ
  let messageSMS = `やっほー！Raptonyです！
Qiita Advent Calendar2022 盛り上がってるよ〜！`

  //SMS送信を実行
  const resultSMS = sendSMS(targetNumber,messageSMS) 

  //送信コストとVonage残高を取得
  let costSMS = parseFloat(resultSMS['messages'][0]['message-price'])
  let yourBalance = parseFloat(resultSMS['messages'][0]['remaining-balance'])

  //FB送信メッセージを生成
  let messageFB = `【コスト通知】
  SMSメッセージを送信しました！
  只今のSMS送信コストは${costSMS}€でした。
  Vonage残高は${yourBalance}€だよ！`

  //FacebookMessenger送信を実行
  const resultFBMessage = sendFBMessage(fromFBId,toFBId,messageFB)
}

//Vonage残高を取得
const getBalance = () => {
  //APIキーととシークレットキーをプロパティ変数から取得
  const apiKey = PropertiesService.getScriptProperties().getProperty('APIKEY')
  const apiSecretkey = PropertiesService.getScriptProperties().getProperty('APISECRETKEY')
  //APIエンドポイント
  const url = `https://rest.nexmo.com/account/get-balance?api_key=${apiKey}&api_secret=${apiSecretkey}`

  //RESTオプションを指定
  const options = {'method':'GET'}
  //フェッチする
  const resultJSON = UrlFetchApp.fetch(url,options)

  //JSONをパース
  result = JSON.parse(resultJSON.getContentText())
  //取得結果をコンソールに出力
  console.log(result['value'])  
}

//SMS送信
const sendSMS = (targetNumber,message) => {
  //APIキーととシークレットキーをプロパティ変数から取得
  const apiKey = PropertiesService.getScriptProperties().getProperty('APIKEY')
  const apiSecretkey = PropertiesService.getScriptProperties().getProperty('APISECRETKEY')
  //APIエンドポイント
  const url = 'https://rest.nexmo.com/sms/json'

  //ペイロードを作成
  const payload = {
    'from':'Vonage APIs',
    'text':message,
    'to':targetNumber,
    'type':'unicode',
    'api_key':apiKey,
    'api_secret':apiSecretkey
  }
  //RESTオプションを指定
  const options = {
    'method':'POST',
    'payload':payload
  }

  //フェッチする
  const resultJSON = UrlFetchApp.fetch(url,options)
  //JSONをパースして結果を格納
  const result = JSON.parse(resultJSON.getContentText())

  //結果を返す
  return result
}

//FacebookMessenger送信
const sendFBMessage = (fromFBId,toFBId,message) => {
  //APIキーととシークレットキーをプロパティ変数から取得
  const apiKey = PropertiesService.getScriptProperties().getProperty('APIKEY')
  const apiSecretkey = PropertiesService.getScriptProperties().getProperty('APISECRETKEY')
  //APIエンドポイント
  const url = 'https://messages-sandbox.nexmo.com/v1/messages'

  //REST Headerを作成(Basic認証)
  const requestHeaders = {
    'Authorization':'Basic ' + Utilities.base64Encode(apiKey + ':' + apiSecretkey),
    'Content-Type':'application/json',
    'Accept':'application/json',
    'muteHttpExceptions':'true'
  }

  //ペイロードを作成
  const payload = {
    'from':fromFBId,
    'to':toFBId,
    'message_type':'text',
    'text':message,
    'channel':'messenger'
  }

  //RESTオプションを指定
  const options = {
    'method':'POST',
    'headers':requestHeaders,
    'payload':JSON.stringify(payload)
  }

  //フェッチする
  const resultJSON = UrlFetchApp.fetch(url,options)
  //JSONをパースして結果を格納
  const result = JSON.parse(resultJSON.getContentText())

  //結果を返す
  return result
}
```

# 準備
## アカウントを作成
Vonage公式ページの右上にあるログインボタンを押して、各サービスのログインリンクが記載されたページにアクセスします。
![スクリーンショット 2022-12-22 5.55.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/d515c8f1-bc00-db05-feca-8f68a728776e.png)
次に、コミュニケーションAPIログインのリンクをクリックします。
![スクリーンショット 2022-12-22 5.49.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/59d0c5c0-adb8-2939-0408-02f7c367b766.png)
必要事項を埋めて、アカウントを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/e0bd419c-2ff2-7cd1-31ce-e9a81b164abc.png)
ログインするとVonageAPIのダッシュボードが表示されます。
![スクリーンショット 2022-12-22 6.00.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/7ab26cd6-12c7-1def-84f0-07d964000bca.png)

## Sandboxの準備
VonageにはFacebook Messenger用のサンドボックスが用意されていますので、今回はこちらを活用させていただきます。
左のツリー下部にデベロッパーツールがありますので、開くと「Messagesサンドボックス」メニューがありますので、そちらから設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/d60bd397-9491-6115-2081-0b10e8e789f8.png)
![スクリーンショット 2022-12-19 2.12.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/1000cde7-ed1f-f79f-b167-52d6b2068cc8.png)
サンドボックスボタンを押す。
![スクリーンショット 2022-12-22 5.26.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/3f917d3f-beba-76ba-244d-59093a85cd2d.png)
QRコードを読み込むと、FacebookのVonageプロフィールが表示されますので、「・・・」ボタンからメッセージを選択してFacebook Messengerに移動します。
![IMG_3422.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/e5e76872-c880-1bcb-498a-0c299b9e63dd.png)
次にQRコードが表示されたページに記載されているパスフレーズを入力して、セットアップ完了です。
![IMG_3423.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/892b4490-b139-50c8-2246-58f49500dd29.png)

# 実装
## 自分のアカウント残高を取得する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/f74eab92-47df-e69a-b6f0-85c378b70fed.png)
Vonageダッシュボードにログインすると左上に表示されている残高。まずはこれを取得して、VonageAPIに触れます。
getBalance関数は、Vonageアカウントに接続して、残高を取得します。
```javascript:Google Apps Script
//Vonage残高を取得
const getBalance = () => {
  //APIキーととシークレットキーをプロパティ変数から取得
  const apiKey = PropertiesService.getScriptProperties().getProperty('APIKEY')
  const apiSecretkey = PropertiesService.getScriptProperties().getProperty('APISECRETKEY')
  //APIエンドポイント
  const url = `https://rest.nexmo.com/account/get-balance?api_key=${apiKey}&api_secret=${apiSecretkey}`

  //RESTオプションを指定
  const options = {'method':'GET'}
  //フェッチする
  const resultJSON = UrlFetchApp.fetch(url,options)

  //JSONをパース
  result = JSON.parse(resultJSON.getContentText())
  //取得結果をコンソールに出力
  console.log(result['value'])  
}
```
### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/285043c6-7b80-e115-eace-276c45f28ba3.png)
正常に取得できました！
次に、今回の要件に必要な、関数をコーディングしていきます。

## SMSを送信する
sendSMS関数はSMSを送信します。

```javascript:Google Apps Script
//SMS送信
const sendSMS = (targetNumber,message) => {
  //APIキーととシークレットキーをプロパティ変数から取得
  const apiKey = PropertiesService.getScriptProperties().getProperty('APIKEY')
  const apiSecretkey = PropertiesService.getScriptProperties().getProperty('APISECRETKEY')
  //APIエンドポイント
  const url = 'https://rest.nexmo.com/sms/json'

  //ペイロードを作成
  const payload = {
    'from':'Vonage APIs',
    'text':message,
    'to':targetNumber,
    'type':'unicode',
    'api_key':apiKey,
    'api_secret':apiSecretkey
  }
  //RESTオプションを指定
  const options = {
    'method':'POST',
    'payload':payload
  }

  //フェッチする
  const resultJSON = UrlFetchApp.fetch(url,options)
  //JSONをパースして結果を格納
  const result = JSON.parse(resultJSON.getContentText())

  //結果を返す
  return result
}
```
### 引数
- `targetNumber`：送信先の電話番号を格納した文字列（電話番号は、E.164フォーマットで指定）
- `message`：送信内容を格納した文字列

:::note info
**E.164フォーマットとは**
国際的に送信先の電話番号を一意に定める表現形式です。国際電話をかけたことがある人には馴染みがあると思いますが、以下のように国番号、市外局番、電話番号をつなげた番号です。
`国番号` `市外局番の1文字目を削った番号` `電話番号`
例えば、日本（国番号81）の携帯番号が090-1234-5678だった場合は、次のようになります。
`+81` `90` `12345678`
:::


:::note warn
日本語を送信する場合は、typeオプションで`unicode`指定すると解決できます。
オプションをつけないと下の画像のように「?」で表示されますので注意。
![IMG_3402.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1499675/bb9aca19-1fb1-f2e7-42d7-3acfbccba013.png)
:::


## Facebook Messengerに送信する（Basic認証）
sendFBMessage関数はFacebook Messengerにメッセージを送信します。

```javascript:Google Apps Script
//FacebookMessenger送信
const sendFBMessage = (fromFBId,toFBId,message) => {
  //APIキーととシークレットキーをプロパティ変数から取得
  const apiKey = PropertiesService.getScriptProperties().getProperty('APIKEY')
  const apiSecretkey = PropertiesService.getScriptProperties().getProperty('APISECRETKEY')
  //APIエンドポイント
  const url = 'https://messages-sandbox.nexmo.com/v1/messages'

  //REST Headerを作成(Basic認証)
  const requestHeaders = {
    'Authorization':'Basic ' + Utilities.base64Encode(apiKey + ':' + apiSecretkey),
    'Content-Type':'application/json',
    'Accept':'application/json',
    'muteHttpExceptions':'true'
  }

  //ペイロードを作成
  const payload = {
    'from':fromFBId,
    'to':toFBId,
    'message_type':'text',
    'text':message,
    'channel':'messenger'
  }

  //RESTオプションを指定
  const options = {
    'method':'POST',
    'headers':requestHeaders,
    'payload':JSON.stringify(payload)
  }

  //フェッチする
  const resultJSON = UrlFetchApp.fetch(url,options)
  //JSONをパースして結果を格納
  const result = JSON.parse(resultJSON.getContentText())

  //結果を返す
  return result
}
```
### 引数
`fromFBId`：送信者のFacebookIDを格納している文字列
`toFBId`：送信先のFacebookIDを格納している文字列
`message`：送信内容を格納している文字列

## シナリオを実行する
main関数は「SMSを送信して、その結果発生したコストと、Vonageの残高をFacebook Messengerに送信する」というシナリオを実行します。
```javascript:Google Apps Script
//メインシナリオ
const main = () => {
  //SMS送信先を指定
  const targetNumber = '***********'
  //FB送信元を指定
  const fromFBId = '***********'
  //FB送信先を指定
  const toFBId = '***********'

  //SMSメッセージ
  let messageSMS = `やっほー！Raptonyです！
Qiita Advent Calendar2022 盛り上がってるよ〜！`

  //SMS送信を実行
  const resultSMS = sendSMS(targetNumber,messageSMS) 

  //送信コストとVonage残高を取得
  let costSMS = parseFloat(resultSMS['messages'][0]['message-price'])
  let yourBalance = parseFloat(resultSMS['messages'][0]['remaining-balance'])

  //FB送信メッセージを生成
  let messageFB = `【コスト通知】
  SMSメッセージを送信しました！
  只今のSMS送信コストは${costSMS}€でした。
  Vonage残高は${yourBalance}€だよ！`

  //FacebookMessenger送信を実行
  const resultFBMessage = sendFBMessage(fromFBId,toFBId,messageFB)
}
```

# 初めてVonageに触れての所感
普段使っている電話番号やFacebook Messengerに対してメッセージや画像を送信できた時はワクワクしました！！
ビジネスシーンでもかなり活用幅が広いと感じます。これまではWebサイト、メール、電話でのリーチがメインでしたが、SMSやFacebookへアプローチできるのは良い。
また、今回僕は試しませんでしたが、2段階認証もサクッと実装できて簡単にセキュアな認証を実装できるようなので、どこかで使ってみたい。

今回、Qiita Advent Calendarへの寄稿がVonageに触れたきっかけでしたが、とても良いサービスに触れることができたと思っています。
今後、プライベート、ビジネスに限らず活用して、実装スピード上げていきたいと思います。

最後まで読んでいただきありがとうございました！！