Azure Functions実践活用[PR]

Azure Central Azure Functions実践活用[PR]

写真で年齢判定するサーバーレスなLINE Botを作ろう(Face API使用)[PR]

2017年3月6日

画像認識サービスを提供するCognitive Servicesと、低予算で手軽にプログラムが動かせるAzure Functionsを組み合わせれば、面白いLINE Botが手軽に作成できる。その開発方法を一通り説明する。

Japan Azure User Group 濱本 一慶(とある技術の開発日記
  • このエントリーをはてなブックマークに追加

 LINEのMessaging APIAzure Functionsを利用して、サーバーレスなBotを開発してみよう。本稿では、LINEのMessaging APIの登録方法から、Node.jsを使用してLINEのBotアプリケーションを作成する方法まで、サーバーレスなBotの開発方法についてまとめる。

 こんにち、メールに変わるコミュニケーション手段として、さまざまなメッセージングアプリケーションが登場している。FacebookメッセンジャーやSkypeやSlackなど多くのアプリケーションがリリースされているが、LINEも多くのユーザーから利用されているメッセージングアプリケーションである。

 LINEのAPIは「LINE BOT API」という名称で提供されていたが、2016年9月29日の「LINE DEVELOPER DAY 2016」において「Messaging API」として提供が開始された。Messaging APIには大きく2つの機能があり。LINEからユーザーにメッセージを送信するPush APIと、ユーザーのメッセージに応じてLINEが返答するReply APIが存在する。

 今回は、Messaging APIのReply APIの機能およびMicrosoft AzureのCognitive ServicesのFace APIと連携して、画像のURLを渡すと年齢を返すアプリケーションを作成する。図1はそのアプリケーション構成のイメージである。

図1 今回作成するBotアプリケーションの作成イメージ

今回作成するアプリケーション

 LINEユーザーから送信されたメッセージをMessaging APIで処理するためには、Webサーバーが必要となるが、今回はAzure FunctionsのFunction Appを使用する。

 Botアプリケーションの全体構成は前掲の図1に示したとおりになっており、具体的には、LINEのメッセージを受けてMessaging APIがFunction Appを呼び出し、Function App内でFace APIで解析した結果をMessaging APIのReply APIを利用してユーザーに送信する仕組みである。

 完成までの大まかな流れは以下のようになる。

  1. (1)Messaging APIへの登録と設定
  2. (2)Cognitive Services(Face API)のアカウント作成
  3. (3)Function Appの作成と設定
  4. (4)Function AppとMessaging APIの接続
  5. (5)Botアプリケーションの実行

 それではさっそく開発内容を説明していこう。

(1)Messaging APIへの登録と設定

Messaging APIへの登録

 まず、Messaging APIにユーザーを登録するために、LINE BUSINESS CENTERへアクセスし、提供サービスの[Messaging API]をクリックする(図2)。その後は、図3~図7の手順に沿って登録を進めてほしい。

図2 LINE BUSINESS CENTERの提供サービス

複数あるサービスの中から[Messaging API]をクリックする。

図3 Messaging APIの登録画面

[Developer Trialを始める]ボタンをクリックする。

 この時点でログインしていない場合は、LINEアカウントにログインが求められるのでログインを行う。ログイン後は、会社がすでに登録されている場合は、図4の下の▼までスキップする。

 会社が未登録の場合は会社情報の入力が求められるので(図4に示すとおり、会社といっても「法人」か「個人」かを選択できる)、適当な情報を入力して会社を作成・登録する(本稿ではAzureサンプル会社という法人を作成・登録した。ちなみにいったん「個人」で作成した後で、LINEアカウントに「法人」を追加することも可能である)。その次に表示されるページで、[サービスを利用開始]ボタンをクリックする。

図4 会社情報の作成

 [Messaging API Developer Trial]アカウント(以下、Developerアカウント)の作成画面になるので(図5)、[アカウント名]と[業種]を設定する(本稿では「FaceBot」というアカウント名を設定した)。

図5 Messaging API Developer Trialの作成

[確認する]ボタンをクリックすると確認ページが表示され、そこで問題なければ[申し込む]ボタンをクリックする。その次のページで[LINE@MANAGER]ボタンをクリックする。

図6 APIの有効化

[LINE@MANAGER]ページの[アカウント設定]-[Bot設定]をクリックすると、この[Bot設定]の画面が表示されるので、[APIを利用する]ボタンをクリックして、利用登録を完了させる。

図7 Bot設定画面

[Bot設定]画面がこのような表示に変わるので、以下の本文の内容を参考にBot設定を行う。

 図7の[Bot設定]画面で、今回は表1の内容でBotの動作設定を行った。

設定項目 設定値
Webhook送信 利用する
Botのグループトーク参加 利用しない
自動応答メッセージ 利用しない
友だち追加時あいさつ 利用しない
表1 Bot設定のキャプション

 正しく設定したことを確認して、[保存]ボタンをクリックする。あとは図8~図10の手順で、LINE Developersの設定ページを開いてChannel Access Tokenを取得する。

図8 API有効後のBot設定画面

[Bot設定]画面の[ステータス]が利用中になっているのを確認して、[LINE Developersで設定する]のリンクをクリックする。利用許諾が求められるので、内容を確認して(問題なければ)[AGREE]ボタンをクリックして同意する。

図9 LINE Developersの基本情報画面

LINE Developersの基本情報画面が表示される。

図10 Channel Access Tokenの取得

図9の下部ある[ISSUE]ボタンをクリックして[Channel Access Token]を取得する。この値は後々、Azure Functionの設定で使用するので控えておく。

 以上がLINEのMessaging APIを利用するための登録と設定手順である。次は画像認識を行うためのFace APIに関する設定を行う。

(2)Cognitive Services(Face API)のアカウント作成

 LINEに送信された画像を解析するために、Microsoft AzureのCognitive ServicesのFace APIを利用する。ここでは、Cognitive ServicesとFace APIを紹介し、Cognitive Servicesを利用するための設定方法を解説する。

Cognitive Servicesとは

 マイクロソフトは以前からProject Oxfordという機械学習APIを提供していたが、それらはCognitive ServicesとしてAzureのサービスの中に取り込まれた。Cognitive ServicesではさまざまなAPIが公開されており、現時点では5つのカテゴリ分けで、以下のようなAPIが公開されている。

  • 言語:
    • Language Understanding Intelligent Service(プレビュー)
    • Text Analytics API(プレビュー)
    • Web Language Model API(プレビュー)
    • Bing Spell Check API
    • Translator Text API
  • 音声:
    • Bing Speech API(プレビュー)
    • Speaker Recognition API(プレビュー)
    • Translator Speech API
    • Custom Speech Service(プレビュー)
  • 視覚:
    • Face AP(プレビュー)
    • Emotion API(プレビュー)
    • Computer Vision API(プレビュー)
    • Content Moderator(プレビュー)
  • 知識:
    • Recommendations API(プレビュー)
    • Academic Knowledge API(プレビュー)
  • 検索:
    • Bing Search API
    • Bing Autosuggest API

 今回のアプリケーションで利用するFace APIでは、画像を解析して顔の判定や人物の識別を行うことができる。Face APIを利用するには、APIエンドポイントを作成する必要があるため、以下ではその作成手順を解説する。

Face APIのアカウント作成方法

 まずはAzureポータルへログインする。Azureアカウントの新規作成時には、Microsoftアカウントの作成や、電話による本人確認、クレジットカードによる本人確認などが必要だったりするが、流れに沿って進めれば難しい点はないので、本稿では説明を割愛する。

 左上の[+]ボタンをクリックし、検索のテキストボックスに「Cognitive Services APIs」と入力する。そこから先は、図11~図12の手順で進めてほしい。

図11 Cognitive Services APIアカウントの作成

検索(フィルター)によりヒットした[Cognitive Services APIs (プレビュー)]という項目をクリックする。

図12 Cognitive Services accountの作成画面
  • 1表示された[Cognitive Services APIs (プレビュー)]ブレードの[作成]ボタンをクリックする。
  • 2Cognitive Services account(アカウント)を作成する画面に、以下の本文にある箇条書きのとおりに入力を行う。
  • 3最後に[作成]ボタンをクリックして、Cognitive Services accountの作成を完了させる。
  • [Account name]: 適当な名前を入力する
  • [サブスクリプション]: Cognitive Servicesを利用するサブスクリプションを選択する
  • [API type]: Face API(preview)を選択する
  • [場所]: 米国西部を選択する
  • [価格レベル]: F0を選択する
  • [Resource group]: 適当なリソースグループを選択あるいは新規作成する
  • [I have read and agree to the legal terms.]チェックボックス: チェックされていることを確認する

 今回は例として表2のように設定したので参考にしてほしい。

設定項目 設定値
Account name azure-central-face
API type Face API (Preview)
場所 米国西部(初期値)
価格レベル F0
Resource group azure-central-resourcegrp(新規作成)
表2 Cognitive Services account設定情報

Face APIのKEYを参照する

 Face APIを呼び出すためには、API KEYが必要となるため、Face APIのKEY(キー)の参照方法を以下に示す。

 左側のメニューから[リソース グループ]-[<先ほど作成したResource group名>]を開いて、図12で作成したCognitive Services accountの項目を選択すると、図13のような概要ページが表示される。[Keys]をクリックするとAPI KEYが表示されるので[KEY 1]の値を控えておく。

図13 Face APIのAPI KEY

1の[Keys]をクリックすると、[ACCOUNT NAME]と[KEY]が表示されるので、2の[KEY 1]の値を控えておく。

(3)Function Appの作成と設定

 LINEのMessaging APIとAzureのFace APIを動作させるには、冒頭でも述べたとおり、Webサーバーを用意する必要がある。今回の例では、Azure Functionsを利用してMessaging APIとFace APIを実行する。Azure Functionsの概要や作成方法については、本稿の趣旨とは異なるため詳細な説明は割愛するため、以前の記事である「サーバーレスアーキテクチャとは? Azure Functionsで初めての開発入門」を参照していただきたい。

HttpTriggerの関数を作成

 まず初めに、LINEからきたメッセージを処理する関数を作成する。新規Function Appを作成したうえで、図14を参考に「JavaScript」言語の「HttpTrigger」の関数を作成する。

図14 HttpTrigger関数の作成

以下の手順で関数を作成する。

  • 1[新しい関数]をクリックする。
  • 2[言語]はJavaScriptを、[シナリオ]はコアを選択する。これにより、テンプレートが絞り込まれる。
  • 3テンプレート一覧の中からHttpTrigger-JavaScriptを選択する。
  • 4[関数名の指定]は、適当な名前を入力する。今回は例としてHttpTriggerJS1と入力した。
    [承認レベル]は、Functionを選択されていることを確認する。
  • 5[作成]ボタンをクリックする。

 作成されたHttpTrigger関数(本稿の例ではHttpTriggerJS1)の[開発]タブを開いてindex.jsファイルに、リスト1のコードを入力して、[保存]ボタンをクリックする。コードの内容は、LINEからHTTP送信された内容をoutputQueueItemというキューに設定する処理である。

index.js
module.exports = function (context, req) {
  context.log('JavaScript HTTP trigger function processed a request. RequestUri=%s', req.originalUrl);
  context.log(req);
  context.bindings.outputQueueItem = req.body;
  res = { body : "" };
  context.done();
};
リスト1 LINEからHTTP送信された内容(body)をキュー(outputQueueItem)に登録するコード

 次に、右上にある[ファイルの表示]からfunction.jsonファイルを開き、リスト2の内容(=キューへのバインドを追記)を図15のように入力して、[保存]ボタンをクリックする。

図15 function.jsonファイルの内容を編集しているところ

番号の順に操作する。

function.json
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    },
    {
      "type": "queue",
      "name": "outputQueueItem",
      "queueName": "js-queue-items",
      "connection": "AzureWebJobsDashboard",
      "direction": "out"
    }
  ],
  "disabled": false
}
リスト2 キュー(outputQueueItem)へのバインド設定を追加する(太字部分)

キュー名(queueName)として指定しているjs-queue-itemsは、次節で作成するQueueTrigger関数で指定するものと一致させる必要がある。また、ストレージアカウント接続(connection)として指定しているAzureWebJobsDashboardもQueueTrigger関数作成時に指定したものと一致させること。

QueueTriggerの関数を作成

 次に、キューに設定された内容を処理する関数を作成する。キューに設定された内容からFace APIを呼び出し、結果をLINEのFace APIを利用してユーザーに返す処理を記述する。

図16 QueueTrigger関数の作成

以下の手順で関数を作成する。

  • 1[新しい関数]をクリックする。
  • 2[言語]はJavaScriptを、[シナリオ]はコアを選択する。これによりテンプレートが絞り込まれる。
  • 3テンプレート一覧の中からQueueTrigger-JavaScriptを選択する。
  • 4[関数名の指定]は、適当な名前を入力する。今回は例としてQueueTriggerJS1と入力した。
    [キュー名]は、入力に使うキューの名前を入力する。今回は例として、初期値のjs-queue-itemsと入力した(前述のリスト2の値はこれに一致させる)。
    [ストレージ アカウント接続]は、キューのストレージアカウントを選択する。今回は例として、初期値のAzureWebJobsDashboardが選択されていることを確認する(前述のリスト2の値はこれに一致させる)。
  • 5[作成]ボタンをクリックする。

 作成されたQueueTrigger関数(本稿の例ではQueueTriggerJS1)の[開発]タブを開いてindex.jsファイルに、リスト3のコードを入力して、[保存]ボタンをクリックする。コードの内容を簡単に説明すると、outputQueueItemというキューに設定された内容を取得して、それが画像のURLであればFace APIに渡してその実行結果を、それ以外であれば「画像のURLを投稿してください」という旨のメッセージを、LINEに送信する処理である。

index.js
var https = require("https");
var url = require("url");

function post_cognitive(context, event) {
  var post_data = JSON.stringify({
    "url": event.message.text
  });

  var parse_url = url.parse("https://westus.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses");
  var post_options = {
    host: parse_url.host,
    path: parse_url.path,
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Ocp-Apim-Subscription-Key': process.env.COGNITIVE_KEY
    }
  };
  var body_string = null;

  var post_req = https.request(post_options, (res) => {
    context.log('Request Done!!');
    context.log('STATUS: ' + res.statusCode);
    context.log('HEADERS: ' + JSON.stringify(res.headers));
    res.setEncoding('utf8');
    res.on('data', (chunk) => {
      context.log('BODY: ' + chunk);
      body_string = chunk;
    });
    res.on('end', function(){
      if (res.statusCode != 200) {
        body_string = 'Face APIの解析に失敗しました。画像のURLを投稿してください。'
      }
      context.log('body_string => ' + body_string);
      post_line_message(context, event, body_string);
    });
  });
  post_req.write(post_data);
  post_req.end();
  context.log('Post Cognitive !');
}

function post_line_message(context, event, msg) {
  var jObj = {};
  jObj.type = "text";
  jObj.id = event.message.id;
  jObj.text = msg;

  var post_data = JSON.stringify({
    "replyToken": event.replyToken,
    "messages": [jObj]
  });

  context.log('LINE Post Data =>' + post_data);
  var parse_url = url.parse("https://api.line.me/v2/bot/message/reply");
  var post_options = {
    host: parse_url.host,
    path: parse_url.path,
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer {' + process.env.LINE_CHANNEL_ACCESS_TOKEN + '}',
      'Content-Length': Buffer.byteLength(post_data)
    }
  };

  var post_req = https.request(post_options);
  post_req.write(post_data);
  post_req.end();
  context.log('Post LINE Message !');
}

function post_message(context, event) {
  context.log(event);
  var messageType = event.message.type;

  context.log(messageType);
  if (messageType == 'text') {
    post_cognitive(context, event);
  } else if (messageType == 'image') {
    post_line_message(context, event, '画像が投稿されました。画像のURLを投稿してください。');
  } else if (messageType == 'sticker') {
    post_line_message(context, event, 'スタンプが投稿されました。画像のURLを投稿してください。');
  } else {
    post_line_message(context, event, '分類できません。画像のURLを投稿してください。');
  }
}

module.exports = function (context, myQueueItem) {
  context.log('JavaScript queue trigger function processed work item', myQueueItem);
  myQueueItem.events.forEach(event => post_message(context, event));
  context.done();
};
リスト3 キューに設定された画像のURLをFace APIに渡して、その実行結果をLINEに送信する処理

process.env.~というコードは、プロセスの環境変数として設定した値を取得していることを意味する。COGNITIVE_KEYLINE_CHANNEL_ACCESS_TOKENという環境変数を取得しているが、これらの設定方法は次節で説明している。

アプリケーションの設定

 最後にFace APIやMessaging APIを実行するAPI KEYを、Function Appの環境変数に設定する。その手順を図17~図18に示す。

図17 [アプリケーション設定の構成]ページを開く手順
  • 1左下にある[Function Appの設定]をクリック。
  • 2[アプリケーション設定の構成]をクリックする。
図18 [アプリケーションの設定]ブレードの[アプリ設定]欄でAPI認証情報のキー(KEY)と値を設定する
  • 1Face APIとMessaging APIの認証情報を設定する。具体的には以下の本文を参考にしてほしい。
  • 2最後に[保存]ボタンをクリックする。

 [アプリケーションの設定]ブレードの[アプリ設定]にFace APIとMessaging APIのKEY情報(表3)を設定する。

キー
LINE_CHANNEL_ACCESS_TOKE 図10で取得した[Channel Access Token]の値
COGNITIVE_KEY 図13で取得したFace APIの[API KEY]の値
表3 [アプリケーションの設定]で入力するFace APIとMessaging APIのKEY情報

これらのキー(=環境変数)は、リスト3のコードで使われている。

 以上でFunction Appの作成と設定は完了である。

(4)Function AppとMessaging APIの接続

 このままでは、LINEにメッセージを投稿してもAzure FunctionsのFunction Appが実行されない。実行されるようにするには、Messaging APIのWebhookにFunction Appのエンドポイントを指定する必要がある。その手順を図19~図20に示す。

図19 Function App関数のURLをコピー

HttpTriggerJS1関数のindex.jsファイルに割り当てられている[関数のURL]をコピーする。コピーする際には、矢印で指し示しているボタンをクリックしてほしい。これによりURLがクリップボードにコピーされる。

図20 Webhook URLの設定

LINE developersのページを開いて、以下の手順を実行する。

  • 1[Basic information]をクリック。
  • 2[EDIT]ボタンをクリックして、編集状態にする。
  • 3[Webhook URL]に、前掲の図19でコピーした「Function App関数のURL」を設定して[SAVE]ボタンをクリックする。

 以上で本当に全ての開発作業が完了だ。

(5)Botアプリケーションの実行

 LINE developersのページを開いて、[Basic information]の[QR Code]に表示されたQRコードを、LINEの[友だち追加]にある[QRコードリーダー]で認識して、ここまでに作成したBotを友達として追加する。LINEの[トーク]を開いて、画像のURLを投稿すると、解析結果が表示されるはずだ。今回は図21の男性の画像(URL:http://re.buildinsider.net/pr-assets/microsoft/azure/solution02/man-face.jpg)を使って確認してみよう。

LINE Botに使用するサンプル画像
図21 LINE Botに使用するサンプル画像

メガネをかけた男性の画像を今回は使用する。

 図22が、実際の実行結果である。

作成したLINE Botの動作例
図22 作成したLINE Botの動作例

図21の画像をURLで渡すとBotアプリケーションがFace APIの解析結果を返してくる。

 返却された解析結果はインデントがなくて読みづらいので、リスト4にきれいに整形した内容を示しておこう。

JSON
[
  {
    "faceId": "8e2ad744-ba65-426a-8f95-f96fef67f96c",
    "faceRectangle": {
      "top": 362,
      "left": 671,
      "width": 210,
      "height": 210
    },
    "faceAttributes": {
      "smile": 1.0,
      "headPose": {
        "pitch": 0.0,
        "roll": -1.6,
        "yaw": 0.6
      },
      "gender": "male",
      "age": 35.0,
      "facialHair": {
        "moustache": 0.1,
        "beard": 0.2,
        "sideburns": 0.0
      },
      "glasses": "ReadingGlasses"
    }
  }
]
リスト4 Face APIの解析結果

 これを見ると"gender": "male""age": 35.0となっており、今回の例ではFace APIが「35歳の男性」という結果を返していることが分かる。それ以外にも、笑顔(smile)やメガネ(glasses)の状態なども出力されているので、(英語ではあるが)ぜひ写真と見比べながら、どんな顔判定がなされているのかを確認してみてほしい。

 以上、LINEのMessaging APIとAzure FunctionsとFace APIを利用して、LINEのBotアプリケーションを作成する方法を解説した。今回の例ではJavaScriptで記述したが、C♯などさまざまな言語で開発することが可能である。

 また、Cognitive Servicesを利用することで、機械学習を用いたアプリケーションを個人でも容易に作成することができるので、これを機に挑戦していただきたい。

※以下では、本稿の前後を合わせて5回分(第1回~第5回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

1. サーバーレスアーキテクチャとは? Azure Functionsで初めての開発[PR]

最近、注目を集めている「サーバーレスアーキテクチャ」の概要と、Azure Functionsを使ったサーバーレス開発の基礎をコンパクトに解説。トリガーや入力/出力のバインディングを作成してみよう。

2. 【現在、表示中】≫ 写真で年齢判定するサーバーレスなLINE Botを作ろう(Face API使用)[PR]

画像認識サービスを提供するCognitive Servicesと、低予算で手軽にプログラムが動かせるAzure Functionsを組み合わせれば、面白いLINE Botが手軽に作成できる。その開発方法を一通り説明する。

3. Visual Studioで始めるサーバーレス「Azure Functions」開発入門[PR]

最近注目されているサーバーレスの開発をVisual Studioで行おう! 環境準備から、Function App(関数アプリ)の作成、Azureへのデプロイと実行、さらに外部ライブラリや自作ライブラリの活用まで、基本的な開発方法を解説する。

4. サーバーレス「Azure Functions」をスケジュール実行する方法(cronジョブ構文)[PR]

バッチジョブなどでスケジュール実行したいというニーズは多いだろう。サーバーレスでFunctionをスケジュール実行する方法を解説。cron構文によるスケジュールの指定方法も説明する。

5. 設計時に使えるAzure/AWSサービス・アイコン集とダウンロード方法[PR]

クラウド上のシステムやサービスを設計する際には、視覚的に分かりやすいアイコンを使おう。アイコンセットのダウンロード方法を示し、各アイコンを用いてAzure/AWSサービスの対応一覧表をまとめる。

イベント情報(メディアスポンサーです)

Twitterでつぶやこう!


Build Insider賛同企業・団体

Build Insiderは、以下の企業・団体の支援を受けて活動しています(募集概要)。

ゴールドレベル

  • グレープシティ株式会社
  • 日本マイクロソフト株式会社