前回作成した関数に出力バインドを追加します。
関数の「統合」メニューで「+新しい出力」をクリックし、「Azure Queue Storage」のバインドを選択します。
「Azure Queue Storage output」の設定でキューを格納するStorage Accountとキュー名を設定し、保存をクリックします。
パッケージのインストール
メッセージを連携する画像処理用Functionでは、画像をBlob Storageに保存します。保存パスには、ランダムな文字列としてuuidを設定するため、「uuid」のパッケージをインストールします。
関数の「プラットフォーム機能」メニューで「高度なツール(Kudu)」をクリックします。
Kuduの画面で「Debug Console」→「CMD」を選択してコンソールを開き、パッケージをインストールする関数のディレクトリまで移動してnpmの初期化を実行します。
npm init
npmの初期化を行ったら「uuid」のパッケージをインストールします。
npm install --save uuid
スクリプト
スクリプトは以下のように作成しました。
// 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 imgurl of urllist){
body.imgurl = imgurl;
// 6. Blob出力パスの設定
var urlparsed = url.parse(imgurl);
var urlpathname = urlparsed.pathname.split("/")
var imgname = urlpathname[url_pathname.length-1]
var img_id = uuid()
body.blobpath = imgid + "/" + 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();
}
スクリプトの説明
1. モジュールの読み込み
必要なモジュールを読み込みます。
2. 特定文字のアンエスケープ関数
クエリのアンパサンド等decodeURIComponentでエスケープされてしまう文字をアンエスケープします。
3. メッセージ内のURLを抽出
正規表現を使って、メッセージ内のすべてのURLを配列として抽出します。
メッセージはURLエンコードされているため、デコードとアンエスケープをしてからURLを抽出します。
4. メッセージ内のURL有無のチェック
メッセージ内にURLがない場合は処理を中断します。
5. メッセージとURLをJSONで配列に格納
メッセージをQueue Storageバインドに渡すために、URLごとにメッセージとURLをJSON化して配列に格納します。
Queue Storageバインドに配列を渡すと、要素ごとにキューを追加できるため、複数URLが投稿された場合でも対応できます。
6. Blob出力パスの設定
URLを解析して画像を保存するBlob Storageのパスを設定します。保存パスは「{uuid}/{ファイル名}」の形になるようにしています。
7. メッセージをQueue Storageに出力
メッセージ内容、URLのJSONをQueue Storageに追加します。
実行結果
Slackの設定したチャンネルにまずはURLでないテキストを投稿します。
前回同様に「テスト」のテキストを投稿しても、BOTからのレスポンスはありません。
続いてURLを投稿すると、BOTから開始のメッセージが返されました。
Azure Storageを確認すると、Slackにメッセージを投稿した同時刻に、指定したキューにメッセージが格納されていることがわかりました。
まとめ
Queue StorageはAzure Functionsの関数間連携の方法として一般的なものとなります
出力バインドにより容易にメッセージを追加でき、それトリガーに他の関数を発火できるため、関数間連携としてきわめて容易に構成することができます。
次回は、Slackに投稿した画像のURLをもとに画像のダウンロードとBlob Storageへの保存を行う関数を作成し、今回作成したキューメッセージで連携させてみます。