こんばんは、さっきまでAVでVJしたいなと思ってFANZAでWEBスクレイピングしたりサンプル動画を無限に取得してました。
これを応用して、
Alexa、キーワードのえっちぃ動画を紹介してと頼んだら紹介してくれるやつを作ります
書きながら作ります。ほんとはdialogflowとgoogle homeでやりたいところですが
google homeをもっていませんのでAlexaでやります。誰かください。
せっかくなのでAlexa SDK V2で作ります。
あとなんか久々にlambdaを触ったらレイヤー機能というものがあったので使います
##Lambda関数を作ろう
どうやらSDKV2はローカルに落としてきて、入れてあげないといけないみたいです。
なのでとりあえず設計図からalexa-skill-kit-sdk-factskillを選んで
こんな感じでlambda関数を作成します。
##SDKV2を入れよう(レイヤーを使って)
Lambdaにいつのまにか登場していたレイヤー機能がすごい便利!!
他の関数から呼び出せる関数みたいなイメージです。
これさえあれば10MB制限でインラインエディタ使えないみたいなこともない!!
ということでSDKV2レイヤーを作ります
$ mkdir sdkv2
$ cd sdkv2
$ yarn add ask-sdk
$ cd ..
$ zip -r nodejs.zip nodejs
というZIPを作成し
Lambda > layer > レイヤーの作成
リクエストモジュールも使うのでついでにリクエストモジュールレイヤーも作っておいてください
const alexa = require('ask-sdk');
const request = require(`request`);
//const iconvLite = require('iconv-lite');
let skill;
exports.handler = async function (event, context) {
if (!skill) {
skill = alexa.SkillBuilders.custom()
.addRequestHandlers(LaunchRequestHandler,SerchHandler)
.create();
}
return skill.invoke(event);
}
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak('ウェルカム!')
.getResponse();
}
};
テンプレートテストから Alexa Start Session を選択し、実行してみよう!
**動いた!!**こんな感じのインテントを作ります。
searchqueryを使いたかったのですが、日本語対応してないみたいでビルドエラーおきたのでactorで妥協・・・
エンドポイントの設定とかはググってください
#FANZA APIを使おう
FANZAのAPIめちゃくちゃ充実してて、適当にリクエスト投げてあげるだけでなんでもできちゃいます。
アフィリエイトIDが必要なので、取得して使ってみてください
#できた
現状キーワード検索して一番上をひっぱってきてるだけです。
echobotディスプレイに対応したりLINEにサンプル動画送ってくれたり、次へっていったら次の動画になったりしたかったのですが、それはおいおい
最終的なコードです。
const alexa = require('ask-sdk');
const request = require(`request`);
//const iconvLite = require('iconv-lite');
let skill;
exports.handler = async function (event, context) {
if (!skill) {
skill = alexa.SkillBuilders.custom()
.addRequestHandlers(LaunchRequestHandler,SerchHandler)
.create();
}
return skill.invoke(event);
}
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak('ウェルカム!')
.getResponse();
}
};
const SerchHandler = {
//サーチハンドラ
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'FANZAintent';
},
handle(handlerInput) {
//console.log(handlerInput.requestEnvelope.request.intent.slots.actor.value)
let keyword = handlerInput.requestEnvelope.request.intent.slots.actor.value
const opts = {
url: "https://api.dmm.com/affiliate/v3/ItemList?api_id=" + process.env.APPID + "&affiliate_id=" + process.env.AFFILIATEID + "&site=FANZA&service=digital&floor=videoa&hits=1&sort=date&keyword=" + encodeURIComponent(keyword) + "&output=json",
headers: {
"Content-type": "charset=UTF-8",
},
json: true
}
//この辺から検索
return new Promise((resolve, reject) => {
doRequest(opts).then((body) => {
if(body.result.items[0].title != undefined){
var title = body.result.items[0].title
console.log(title)
resolve(handlerInput.responseBuilder
.speak(title)
.getResponse())
}
else{
reject(handlerInput.responseBuilder
.speak('取得できませんでした')
.getResponse())
}
})
})
}
}
//resolve返せるリクエストにしてあげる関数
function doRequest(options) {
return new Promise(function (resolve, reject) {
request(options, function (error, res, body) {
if (!error && res.statusCode == 200) {
resolve(body);
} else {
reject(error);
}
});
});
}
SDK V1 では以下のようにインテントごとに処理をしていましたが
const handlers = {
'hogeintent' : function() {
//hogehoge
},
V2では各ハンドラの入り口で処理をするみたいです
const hogeIntentHandler = {
canHandle(handlerInput) {
// インテント名がhogeIntentの時に処理する
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'hogeIntent';
},
handle(handlerInput) {
// 処理の内容
}
};
利点として同一インテント名に対するハンドラをまとめて処理できたり、処理わけが簡単だったりします。
[日本語Alexa] Alexa SDK for Node.js Ver2入門(その1)はじめの一歩
https://dev.classmethod.jp/cloud/alexa-sdk-v2-first/
が参考になりました。
#まとめ
IoTじゃなくてVUIになってしもた