はじめに
Qiita内にはNode.jsやFace APIを使って画像を認識させるLine Botの記事が少ない印象でした。
今回は下記記事を参考にしました。
GitHub
からソースコードを引っ張ってきて、実装しました。
下準備
下記記事を参考にLine Botを使用できる状態にします。
npm init -y
npm i @azure/cognitiveservices-face @azure/ms-rest-azure-js
でAzureを使えるようにします。
全体像
'use strict';
const fs = require("fs");
// Azure Face APIを使うための準備
const { FaceClient } = require("@azure/cognitiveservices-face");
const { CognitiveServicesCredentials } = require("@azure/ms-rest-azure-js");
const faceKey = ""; //個人のKey
const faceEndPoint = ""; //個人のEndPoint
const cognitiveServiceCredentials = new CognitiveServicesCredentials(faceKey);
const faceClient = new FaceClient(cognitiveServiceCredentials, faceEndPoint);
//APIを叩ける
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
const config = {
channelSecret: 'Lineのシークレットチャネル',
channelAccessToken: 'Lineのアクセストークン'
};
const app = express();
app.post('/webhook', line.middleware(config), (req, res) => {
console.log(req.body.events);
Promise
.all(req.body.events.map(handleEvent))
.then((result) => res.json(result));
});
const client = new line.Client(config);
async function handleEvent(event) {
let message = {
type: 'text',
text: null
};
if(event.message.type === "image"){
console.log("画像を検出しました");
try{
//画像を取得
const image = await downloadContent(event.message.id);
// 画像を取得し終わったらFace APIに送信して、顔検出を行う
const faceList = await faceClient.face.detectWithStream(image, {
returnFaceAttributes: ["age", "smile", "makeup", "glasses", "facialHair"], // ここにカンマ(,)区切りでパラメータを追加する
});
message = {
type: 'text',
text: ' 年齢 :'+faceList[0].faceAttributes.age+'歳'
+'\n 笑顔 :'+ faceList[0].faceAttributes.smile * 100 + '点'
+'\n ひげ :'+ faceList[0].faceAttributes.facialHair.beard
+'\nメイク:'+ faceList[0].faceAttributes.makeup.eyeMakeup
+'\nメガネ:'+ faceList[0].faceAttributes.glasses
};
return client.replyMessage(event.replyToken, message);
}catch (e) {
console.error(e);
return client.replyMessage(event.replyToken, {
type: "text",
text: "画像取得or画像分析中にエラーが発生しました。",
});
}
}else{
message = {
type: 'text',
text: '申し訳ありません。個別メッセージには対応しておりません。',
};
return client.replyMessage(event.replyToken, message);
}
}
async function downloadContent(messageId, downloadPath = "./image.png") {
const data = [];
return client.getMessageContent(messageId).then(
(stream) =>
new Promise((resolve, reject) => {
const writable = fs.createWriteStream(downloadPath);
stream.on("data", (chunk) => data.push(Buffer.from(chunk)));
stream.pipe(writable);
stream.on("end", () => resolve(Buffer.concat(data)));
stream.on("error", reject);
})
);
}
app.listen(PORT);
console.log(`Server running at ${PORT}`);
Line Botに対して、image
タイプのメッセージが送信されたら、動く仕様です。
それ以外のタイプには、申し訳ありません。個別メッセージには対応しておりません。
と出力されます。
今回は「笑顔」をメインとしていますが、他にもいろいろあるみたいです。
追記
■GitHubからソースコードをコピーしたときの注意点
・1時間でLINE Botを作るハンズオン
のサイトを参考にBot作成をした場合、
ソースコード115行目:
app.post("/", line.middleware(config), (req, res) => {
↓
app.post("/webhook", line.middleware(config), (req, res) => {
へと変更が必要です。(2021/11/23)