transrec について zapier で出来ること以上のことをGoogle Apps Script を使ってやろうとしたら分かったこと
前回、Google Apps Script (GAS) が安価でちょっとしたことをするのに使えて便利、的なことを書いてみましたが、実際、APIを叩いて情報を得て、自分の思うように加工しながら便利に使える、というのは、とても気持ちがよいことで(笑)、それを zapier に求めていたはずなのですが、それ以上の柔軟性を求めるならば自分でコードを書く、しかないんですよね。
ということで、Zapier を使ってクラウド系留守番電話サービス、transrec を使い倒そうとして出来なかったこと、というのをちょっと頑張って実現してみようとしたのですが、ある程度のところで壁にぶつかったので、この顛末を恥ずかしながらご紹介してみようかと思います。
例えば、録音された音声メッセージは、ファイル形式でtransrec のサーバーから Get することは可能なのですが、Zapier 側でダウンロードしても次のストレージサービスにハンド・オーバーすることが出来ないのでした(メールの添付ファイルならば出来るのに。。。)
また、Zapier から Google Contact にアクセスしても、発信者番号から名前を探すというサービスがないので名前を引っ張り出すことが出来ないのです。Google Contacts APIでは可能なのですが。。。
ということで、なんとなく満たされない仕上がり、でもここが Zapier の限界なんだよな、と思っていたのでした。
そこで、今さら出会った GAS でなら普通に URLを叩いてファイルをダウンロードして Google Drive に保存できることや、Contacts APIを叩けるのが分かったら。。。やりたくなりますよ、満たされたくなりますよ。ということで、やってみました。一応自分でのテストまでは出来ちゃいました(笑)
どういう状態まで出来たか、というと。。。
transrec が留守番メッセージを受け取るとping で通知することから、まずウェブアプリケーションとして get でパラメーターを送ってくる、という前提で全体のプログラムをかいてみました。GASにURLを叩いて情報を送ってきたものを受け取るには。。。doGet(e) です。まぁ、transrec は GET でも POST でも送ってくることは可能なのですが。。。
そこで、パラメータとして受け取った留守番メッセージに対してユニークに与えられるrecordId と相手の発信番号 fromId を使って
ということを出来るようにしてみたのがこんなコードです。
これをウェブアプリケーションとして設定(スクリプトエディターの「公開」-「ウェブアプリケーションとして公開」を選ぶ)して、ウェブアプリケーションとしてのURLが表示されることから、そのURLの終わりの ... /exec に "?recordid=foofoo&from=hoohoo" と、transrec が ping することを想定した形にしてテストしてみると。。。おお、ちゃんと音声ファイルはGoogle Driveの指定されたところに格納されているし、Pushover からアクセスできるし、電話も発信できるし、それ以上に誰からの電話かもわかるし、とよく出来てるー
あとは実戦でPingを飛ばせば。。。
安全性を確保する Sandbox のなかで走らせている世界なので、Google の外とのやり取りはかなり限定されます。例えば、外部の画像をウェブアプリケーション上で表示させることは出来ない、とか、今回動かなかった原因というのは、Google Apps Script を Get なりでスタートさせるには、OAuth 2.0でのユーザー認証が必要になる、というものなのです。これは、ウェブアプリケーションじゃなくAPIにしたら当然更に難しいですよね(だから、誰もがget で叩けるウェブアプリケーションで作っちゃえ、と思ったのですが。。。)。
あと、本当は最終的にやりたかったこととして、留守番メッセージをGoogle Cloud Speech API に投げてより精度の高いと言われている解析の結果のテキストを引っ張り出したかった(出来れば複数言語対応で。。。)、のですが、GASで POST する時にmultipart 化出来ないのでファイルデータを送ることが出来なさそう(ファイルをbase64化してmultipart を使わずに、という方法もあるのですが、Speech APIには使えない)なのなのです。
ということで、OAuth 2.0 のないpingを使っても動かないわけです。変なbotを作られても困りますからね。
と言って、メールが来たらアクションをするようにコードを書くことも可能でしょうけど、それだとメールのチェックが1時間ごとですので即時性に欠けますよね。ということで、今回が技術的には色々と面白いことが出来たのですがセキュリティの面で難しかった、と、こういうコードをネットで動かすときに気をつけなければいけないことを思い出させてくれた、というところでいかがでしょ?(笑)
いやぁ、今回はこれくらい高かった。。。 |
おさらい
その1- transrec って?
transrec というのは数年前から立ち上がったクラウド系のサービスの一つで、留守番電話サービス、ではあるものの- 吹き込んでもらった留守番メッセージをメールで配信してくれる
- そんな留守番メッセージの文字起こしをしてメールで教えてくれる
- 留守番メッセージは事実上無制限の件数を保存してくれる
- APIを通じて過去のメッセージを自由に引っ張り出すことが出来る
もし興味が出たら紹介コードQ55PN8を使ってぜひ申し込んでくださいね。
その2 - transrec と zapier を組み合わせる
普通に契約して使っても、メッセージを録音されたらメールで文字起こししたものと音声ファイルがメールに添付して届くので、それだけでも充分、ではあるものの、せっかく APIを使えるのだから、と、ウェブサービスを繋げるサービスである Zapier を使ってメール以外に通知してもらえる方法を作ってみよう、と思って作ったのがこちらの記事。元々何かしらのウェブサービスからの通知を受け取るべく、Pushover というサービスを使っていたので、そこに留守番メッセージが届いたら通知が出るようにしよう、というもの。で、何が不満だったの?
通知だけならばこれで十分、かもしれないのですが、録音された音声メッセージにアクセスできない、発信者番号だけで相手が誰だったかわからないことも多いので何とかしたい、という Zapier のサービスでなんとかなりそうなことが、実際にやってみたら出来なかった、のです。例えば、録音された音声メッセージは、ファイル形式でtransrec のサーバーから Get することは可能なのですが、Zapier 側でダウンロードしても次のストレージサービスにハンド・オーバーすることが出来ないのでした(メールの添付ファイルならば出来るのに。。。)
また、Zapier から Google Contact にアクセスしても、発信者番号から名前を探すというサービスがないので名前を引っ張り出すことが出来ないのです。Google Contacts APIでは可能なのですが。。。
ということで、なんとなく満たされない仕上がり、でもここが Zapier の限界なんだよな、と思っていたのでした。
GAS だから出来ちゃったこと
そこで、今さら出会った GAS でなら普通に URLを叩いてファイルをダウンロードして Google Drive に保存できることや、Contacts APIを叩けるのが分かったら。。。やりたくなりますよ、満たされたくなりますよ。ということで、やってみました。一応自分でのテストまでは出来ちゃいました(笑)
どういう状態まで出来たか、というと。。。
transrec が留守番メッセージを受け取るとping で通知することから、まずウェブアプリケーションとして get でパラメーターを送ってくる、という前提で全体のプログラムをかいてみました。GASにURLを叩いて情報を送ってきたものを受け取るには。。。doGet(e) です。まぁ、transrec は GET でも POST でも送ってくることは可能なのですが。。。
そこで、パラメータとして受け取った留守番メッセージに対してユニークに与えられるrecordId と相手の発信番号 fromId を使って
- Google Contact にある発信者名を取り出す
- transrec でテキスト化したメッセージ情報を取り出す
- transrec に保存されている音声データを Google Drive に格納する
- Pushover に誰からどんなメッセージが届いたか、またGoogle Drive の音声データや、発信者番号で折り返し掛けられるように表示する
ということを出来るようにしてみたのがこんなコードです。
あ、余談ですが、発信者を特定するのに callernames = ContactsApp.getContactsByPhone(fromId.slice(1))と、電話番号の最初の一文字、通常だと 0 を外した形で検索しているのは、Google Contact のなかでは国番号 + 0を除いた電話番号、という形で保管されているとかなんとか、ということで、最初の一文字を削除して検索したらほぼいい確率でヒットしたことからこうしています。function doGet(e) { var recordId = e.parameter.recordid; var fromId = e.parameter.from; if (e.parameter == undefined) { //パラメータ不良の場合はundefinedで返す var getvalue = "undefined" }else{ var callernames = ContactsApp.getContactsByPhone(fromId.slice(1)); var callerFullname; for (var i in callernames){ callerFullname = callernames[i].getFullName(); } var getvalue = JSON.parse(fetchText(recordId)); } var voiceUrl = fetchFile(recordId, fromId); return pushoverMessenger (callerFullname + " (" + fromId + ") からの留守番電話があります。", getvalue.message, getvalue.calledDate, voiceUrl); } function fetchFile(recordId, fromId){ var FOLDER_ID = 'your Drive folder ID'; //保存するフォルダ var SID = 'your transrec SID'; var Token = 'your transrec Token'; var myFolder = DriveApp.getFolderById(FOLDER_ID); //フォルダを取得 var date = new Date(); var url = "https://api.transrec.net/v1/mp3/" + recordId; var options = { "headers" : {"Authorization" : " Basic " + Utilities.base64Encode(SID + ":" + Token)} }; if (UrlFetchApp.fetch(url, options).getResponseCode() == 200) { var myBlob = UrlFetchApp.fetch(url, options).getBlob(); myBlob.setName("voicemessage_from_" + fromId + "_" + Utilities.formatDate(date, 'JST', 'yyyyMMddHHmmss') + ".mp3") myFolder.createFile(myBlob); var files = DriveApp.getFilesByName("voicemessage_from_" + fromId + "_" + Utilities.formatDate(date, 'JST', 'yyyyMMddHHmmss') + ".mp3"); var fileUrl; while (files.hasNext()) { var file = files.next(); fileUrl = file.getUrl() } return fileUrl; } else { return "failure" }; } function fetchText(recordId){
var url = "https://api.transrec.net/v1/record/" + recordId; var options = { "headers" : {"Authorization" : " Basic " + Utilities.base64Encode(SID + ":" + Token)} }; if (UrlFetchApp.fetch(url, options).getResponseCode() == 200) { return UrlFetchApp.fetch(url, options) } else { return "failure" }; } function pushoverMessenger (title, message, timestamp, targetUrl) { var url = "https://api.pushover.net/1/messages.json"; var POToken = 'your pushover Token'; var POUser = 'your pushover user ID'; var payload = { "token": POToken, "user": POUser, "title": title, "message" : message, "timestamp" : timestamp, "url" : targetUrl }; var options = { "method" : "POST", "payload" : payload }; UrlFetchApp.fetch(url, options); }var SID = 'your transrec SID'; var Token = 'your transrec Token';
これをウェブアプリケーションとして設定(スクリプトエディターの「公開」-「ウェブアプリケーションとして公開」を選ぶ)して、ウェブアプリケーションとしてのURLが表示されることから、そのURLの終わりの ... /exec に "?recordid=foofoo&from=hoohoo" と、transrec が ping することを想定した形にしてテストしてみると。。。おお、ちゃんと音声ファイルはGoogle Driveの指定されたところに格納されているし、Pushover からアクセスできるし、電話も発信できるし、それ以上に誰からの電話かもわかるし、とよく出来てるー
あとは実戦でPingを飛ばせば。。。
GASだから実は出来なかったこと
さて、実際に自分で留守番メッセージを残してpingを飛ばしたのですがZapier の処理しか上がってきませんでした。実はその他のあれこれテストした結果でもあるのですが、安全性を確保する Sandbox のなかで走らせている世界なので、Google の外とのやり取りはかなり限定されます。例えば、外部の画像をウェブアプリケーション上で表示させることは出来ない、とか、今回動かなかった原因というのは、Google Apps Script を Get なりでスタートさせるには、OAuth 2.0でのユーザー認証が必要になる、というものなのです。これは、ウェブアプリケーションじゃなくAPIにしたら当然更に難しいですよね(だから、誰もがget で叩けるウェブアプリケーションで作っちゃえ、と思ったのですが。。。)。
あと、本当は最終的にやりたかったこととして、留守番メッセージをGoogle Cloud Speech API に投げてより精度の高いと言われている解析の結果のテキストを引っ張り出したかった(出来れば複数言語対応で。。。)、のですが、GASで POST する時にmultipart 化出来ないのでファイルデータを送ることが出来なさそう(ファイルをbase64化してmultipart を使わずに、という方法もあるのですが、Speech APIには使えない)なのなのです。
ということで、OAuth 2.0 のないpingを使っても動かないわけです。変なbotを作られても困りますからね。
と言って、メールが来たらアクションをするようにコードを書くことも可能でしょうけど、それだとメールのチェックが1時間ごとですので即時性に欠けますよね。ということで、今回が技術的には色々と面白いことが出来たのですがセキュリティの面で難しかった、と、こういうコードをネットで動かすときに気をつけなければいけないことを思い出させてくれた、というところでいかがでしょ?(笑)
0 件のコメント:
コメントを投稿