Michaelです。
「雑コラBOT」の作成の過程からAzure Functionsの設定方法を紹介する「雑コラBotを作ろう」の2回目です。
前回は、Azure FunctionsでSlackのオウム返しBOTを作成しました。今回は、Azure Functions同士を連携するために、受けたメッセージからURLを抽出してQueue Storageに格納する仕組みを追加します。
構成
Azure Functionsで受けたSlackのメッセージにURLが含まれる場合に、URLを抽出してメッセージとともにQueue Storageに格納します。
バインド設定
前回作成した関数に出力バインドを追加します。
関数の「統合」メニューで「+新しい出力」をクリックし、「Azure Queue Storage」のバインドを選択します。
「Azure Queue Storage output」の設定でキューを格納するStorage Accountとキュー名を設定し、保存をクリックします。
パッケージのインストール
メッセージを連携する画像処理用Functionでは、画像をBlob Storageに保存します。保存パスには、ランダムな文字列としてuuidを設定するため、「uuid」のパッケージをインストールします。
関数の「プラットフォーム機能」メニューで「高度なツール(Kudu)」をクリックします。
Kuduの画面で「Debug Console」→「CMD」を選択してコンソールを開き、パッケージをインストールする関数のディレクトリまで移動してnpmの初期化を実行します。
1 |
npm init |
npmの初期化を行ったら「uuid」のパッケージをインストールします。
1 |
npm install --save uuid |
スクリプト
スクリプトは以下のように作成しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
// 1. モジュールの読み込み var uuid = require("uuid/v4") var url = require("url") // 2. URLの特定文字のアンエスケープ関数 var unEscape = function (str) { return str.replace(/(&)/g, '&') .replace(/(<)/g, '<') .replace(/(>)/g, '>') .replace(/(")/g, '"') .replace(/(')/g, "'"); }; module.exports = function (context, data) { var body_elements = data.split('&') var body = {} for(let elem of body_elements){ elem = elem.split('=') body[elem[0]] = elem[1] } if (body.user_name != 'slackbot') { // 3. メッセージ内のURLを抽出 body.text = unEscape(decodeURIComponent(body.text)) var rx = new RegExp("(http|https)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)", "g"); var url_list = body.text.match(rx); context.log(url_list) // 4. メッセージ内のURL有無のチェック if (url_list) { // 5. メッセージとURLをJSONで配列に格納 var queueItems = [] for(let img_url of url_list){ body.img_url = img_url; // 6. Blob出力パスの設定 var url_parsed = url.parse(img_url); var url_pathname = url_parsed.pathname.split("/") var img_name = url_pathname[url_pathname.length-1] var img_id = uuid() body.blob_path = img_id + "/" + img_name; queueItems.push(JSON.stringify(body)); } // 7. メッセージをQueue Storageに出力 context.bindings.outputQueueItem = queueItems context.res = {text: 'BOT Start!'}; } else{ context.res = {}; } } else { context.res = {}; } context.done(); } |
スクリプトの説明
- モジュールの読み込み
必要なモジュールを読み込みます。 - 特定文字のアンエスケープ関数
クエリのアンパサンド等decodeURIComponentでエスケープされてしまう文字をアンエスケープします。 - メッセージ内のURLを抽出
正規表現を使って、メッセージ内のすべてのURLを配列として抽出します。
メッセージはURLエンコードされているため、デコードとアンエスケープをしてからURLを抽出します。 - メッセージ内のURL有無のチェック
メッセージ内にURLがない場合は処理を中断します。 - メッセージとURLをJSONで配列に格納
メッセージをQueue Storageバインドに渡すために、URLごとにメッセージとURLをJSON化して配列に格納します。
Queue Storageバインドに配列を渡すと、要素ごとにキューを追加できるため、複数URLが投稿された場合でも対応できます。 - Blob出力パスの設定
URLを解析して画像を保存するBlob Storageのパスを設定します。保存パスは「{uuid}/{ファイル名}」の形になるようにしています。 - メッセージをQueue Storageに出力
メッセージ内容、URLのJSONをQueue Storageに追加します。
実行結果
Slackの設定したチャンネルにまずはURLでないテキストを投稿します。
前回同様に「テスト」のテキストを投稿しても、BOTからのレスポンスはありません。
続いてURLを投稿すると、BOTから開始のメッセージが返されました。
Azure Storageを確認すると、Slackにメッセージを投稿した同時刻に、指定したキューにメッセージが格納されていることがわかりました。
まとめ
Queue StorageはAzure Functionsの関数間連携の方法として一般的なものとなります
出力バインドにより容易にメッセージを追加でき、それトリガーに他の関数を発火できるため、関数間連携としてきわめて容易に構成することができます。
次回は、Slackに投稿した画像のURLをもとに画像のダウンロードとBlob Storageへの保存を行う関数を作成し、今回作成したキューメッセージで連携させてみます。