#ジェイソン・ステイサムとは?
イギリス出身のハリウッド俳優です。主にアクション映画に出演していて、代表作に「ワイルドスピード」シリーズ、「トランスポーター」シリーズなどがあります。スタントマンを使わず、自身でアクションシーンを演じることがほとんど。鍛えぬいた体が素晴らしいです。。。(参照:wikipedia )
#なぜジェイソン・ステイサムのBOTを作るのか
ステイサムを好きになって10年ほど経ちました。
ワイルドな顔とマッチョなボディはもちろんですが、
彼の声と演技、そしてストイックなプロ意識が大好きなのです。
近年その想いが加速し、やる気を出したいとき、疲れて癒されたいとき、キュンキュンしたいときなどに、
__ステイサムの画像を検索して、妄想するのが日課__になってしまいました。
どうせなら、そんな妄想を具現化して、さらなる高みを目指したいと思い、今回LINE BOTを作ることにしました。
(私の中のステイサムたんは、ちょっとSです。)
#環境
Visual Studio Code v1.47.0
node v14.5.0
@line/bot-sdk
#作り方
###LINE BOTアカウントを作成
「1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest」
https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d
▲こちらの記事を参考に、まずLINE BOTアカウントを作成
(きゃぁ、もうこれだけでもカッコイイ!)
###Node.jsでプロジェクト作成~トンネリング
先ほどの記事をまた参考にして、ngrokでトンネリングするところまで行いました!
###ジェイソン・ステイサムの画像を取得する
色んなステイサムに会いたいとなると、大量の画像が必要となります。
今回のLINE BOTで一番重要なポイントと言っても過言ではないでしょう。
「Google Chrome検索結果画像をコマンド使わず一括でダウンロードした話」
https://qiita.com/ka0ru19/items/64bfee2c7e904b9524d2
▲こちらの記事を参考に、ステイサムの画像をGoogleの画像検索から一括ダウンロードしました。
ファイル形式がJFIFになっていたのですが、LINE BOTではjpgのみしか使えないので、
コマンドプロンプトで一括でファイル形式を変換
(参考:Windows10 拡張子を一括で変更する方法 https://petitcc.exblog.jp/26140363/ )
キレイに全部jpgになりました!
画像URLも必要なので、はてなさんのサービスを使って、URLを作成しました。
https://f.hatena.ne.jp/
#ステイサムとの妄想をひたすら打ち込む
私が話しかけたら、画像とテキストで理想の答えが返ってくるように、
とにかく思いつくレパートリーをif文で打ち込みました。
if(event.message.text.match('おはよう')) {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184554.jpg',
previewImageUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184554.jpg',
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: 'おはよう。ラジオ体操の時間だ。',
}) //テキスト
}
if(event.message.text === '痩せたい') {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl: 'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081414.jpg',
previewImageUrl:'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081414.jpg'
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: '一緒に筋トレだ'
}) //テキスト
}
if(event.message.text === 'もうやだ') {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl: 'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184654.jpg',
previewImageUrl:'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184654.jpg'
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: '弱音を吐くな。死にたいのか?'
}) //テキスト
}
はぁ・・・最高すぎますね。
#おわりに
本当はAPI連携して、Wikiから情報引っ張ってきたり、
「本日のステイサム占い」でランダムに画像が出てくる仕様とかも試みたりしたのですが、うまくいかず…。
7月26日がステイサムの誕生日なので、それまでに完成できたらいいなと思っています。
最後にとりあえず今日までに作れたところまでコード全文載せておきます!
私利私欲に満ちた記事でしたが、最後までご覧いただきありがとうございました!!!
#サンプルコード全文
"use strict";
const express = require("express");
const line = require("@line/bot-sdk");
const PORT = process.env.PORT || 3000;
const config = {
channelSecret: "チャンネルシークレットをコピペ",
channelAccessToken: "アクセストークンをコピペ",
};
const app = express();
app.get("/", (req, res) => res.send("Hello LINE BOT!(GET)")); //ブラウザ確認用(無くても問題ない)
app.post("/webhook", line.middleware(config), (req, res) => {
console.log(req.body.events);
//ここのif分はdeveloper consoleの'接続確認'用なので削除して問題ないです。
if (
req.body.events[0].replyToken === "00000000000000000000000000000000" &&
req.body.events[1].replyToken === "ffffffffffffffffffffffffffffffff"
) {
res.send("Hello LINE BOT!(POST)");
console.log("疎通確認用");
return;
}
Promise.all(req.body.events.map(handleEvent)).then((result) =>
res.json(result)
);
});
const client = new line.Client(config);
async function handleEvent(event) {
if (event.type !== "message" || event.message.type !== "text") {
return Promise.resolve(null);
}
if(event.message.text.match('おはよう')) {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184554.jpg',
previewImageUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184554.jpg',
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: 'おはよう。ラジオ体操の時間だ。',
}) //テキスト
}
if(event.message.text === '痩せたい') {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl: 'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081414.jpg',
previewImageUrl:'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081414.jpg'
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: '一緒に筋トレだ'
}) //テキスト
}
if(event.message.text === 'もうやだ') {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl: 'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184654.jpg',
previewImageUrl:'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184654.jpg'
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: '弱音を吐くな。死にたいのか?'
}) //テキスト
}
if(event.message.text.match('かっこいい')) {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081123.jpg',
previewImageUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081123.jpg',
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: 'ほう。ご褒美の上裸だ。',
}) //テキスト
}
if(event.message.text === 'トランスポーター') {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl: 'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184550.jpg',
previewImageUrl:'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184550.jpg'
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: 'ルール1 契約厳守\nルール2 名前は聞かない\nルール3 荷物は開けない'
}) //テキスト
}
if(event.message.text === 'メカニック') {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl: 'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721190805.jpg',
previewImageUrl:'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721190805.jpg'
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: 'Victory Loves Preparation\n周到な準備が勝利を招く'
}) //テキスト
}
if(event.message.text.match('うしろ')) {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl: 'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081128.jpg',
previewImageUrl:'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081128.jpg'
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: 'え?'
}) //テキスト
}
if(event.message.text.match('好き')) {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081635.jpg',
previewImageUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721081635.jpg',
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: '彼女いるんで',
}) //テキスト
}
if(event.message.text.match('愛してる')) {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184638.jpg',
previewImageUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184638.jpg',
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: '子供いるんで',
}) //テキスト
}
if(event.message.text.match('罵って')) {
await client.pushMessage(event.source.userId, {
type: 'image',
originalContentUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184853.jpg',
previewImageUrl:
'https://cdn-ak.f.st-hatena.com/images/fotolife/u/unias_tawa/20200721/20200721184853.jpg',
}); //画像
return client.replyMessage(event.replyToken, {
type: 'text',
text: 'うわ~なんてだらしない体してんだ、10キロ泳いでこい',
}) //テキスト
}
}
app.listen(PORT);
console.log(`Server running at ${PORT}`);