プロトアウトスタジオという、プログラミングスクールではなく、プロトタイピングをアウトプットするというスクールに参加し始めた人の記事です。
前回の投稿で、LINE bot とAPIを繋げる宿題を達成できず、講師の方に対応策をご指南いただきました。
※前回投稿:ド素人がプロトタイピングスクールに入ったらどうなったか&宿題公開
https://qiita.com/hiromae0213
繋げ先のAPIは、「リクエストをもらったらランダムに柴犬画像を返す」というAPIを使っています。
※API:
https://shibe.online/
下記記事を参考にしています。
物知りLINE BOTを作ろうとしたらfugaしか答えない残念な奴になった話
https://qiita.com/zgw426/items/a5196ab7f26b785479ec
'use strict';
const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const PORT = process.env.PORT || 3000;
const config = {
channelSecret: 'xxxx',
channelAccessToken: 'xxxx'
};
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);
function handleEvent(event) {
if (event.type !== 'message' || event.message.type !== 'text') {
return Promise.resolve(null);
}
let mes = 'ちょっとまってね'; // 待ってねってメッセージだけ先に処理
getQiitaTag(event.source.userId , event.message.text); // スクレイピング処理が終わったらプッシュメッセージ
return client.replyMessage(event.replyToken, {
type: 'text',
text: mes
});
}
const getQiitaTag = async (userId,tag) => {
let mes = '';
try {
const res = await axios.get('http://shibe.online/api/shibes?count=1&urls=true&httpsUrls=true' );
const item = res.data;
mes = item[0];
} catch (error) {
// 該当しないものは404でエラーになる
const {
status,
statusText
} = error.response;
console.log(`Error! HTTP Status: ${status} ${statusText}`);
if( status == 404 ){
mes = 'Qiitaのタグ「' + tag + '」の記事はありませんでした';
} else {
mes = `Error! HTTP Status: ${status} ${statusText}`;
}
}
await client.pushMessage(userId, {
type: 'text',
text: mes,
});
}
app.listen(PORT);
console.log(`Server running at ${PORT}`);
LINEで何かを入力したら柴犬画像を返すAPIを呼び出して、柴犬画像のURLがLINE上に表示されました。
流れ的には下記のようなイメージを持っていますが、
今の私のレベルではわからない領域が多くてなぜ上記コードが
上手く動いているかは理解できていません。
プロトアウトスタジオ第2回の宿題は、
「今日学んだこと(APIの仕組み)やLine Botを発展させる」です。
LINE Botは現状わからないことが多すぎて無理そうなので、まずは自分が理解できる領域で何かできないか考えてみました。
Progateを通じてHTMLとJavaScriptの基本中の基本はわかってきたことをふまえ、
下記のような形で、APIで取得した画像をHTML上に表示させる仕組みの実装にチャレンジしました。
が、エラー!
理由は、「axiosはサーバ側で動かすものなのでフロント側で使うものではない」そうです。
ただ、HTML上のscriptタグで記載しておけば使えることは使えるそうで、下記のような形で再チャレンジしました。
が、再度エラー。
理由としては、取得した画像データを直接フロント側で読み込むのは何とかオリジン(←名前忘れた、、、)の制約に引っかかるケースが多く難しいそうです。
最終的にはその制約に引っかからないAPIを講師の方に見繕っていただき、つなぐことができました!
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>犬の画像を呼び出す</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<button id="btn">ボタン</button>
<img src="#" id="shiba">
<script src="app.js"></script>
</body>
</html>
let dogImage='';
document.querySelector('button').addEventListener('click',()=>{
axios.get('https://dog.ceo/api/breeds/image/random')
.then(function (response) {
dogImage=response.data.message;
document.getElementById('shiba').src= dogImage;
})
.catch(function (error) {
// handle error
console.log(error);
});
})
ということで、
ProgateのHTML/CSSとJavaScriptを2周やった程度でもAPIを呼んで取得した情報を表示させる、までは何とかたどり着けました。
これを作りながら、本当は下記のような形にできれば柴犬APIで取得した画像も表示できるのでは?と考えましたが、まだ時間が足りないのでこれから勉強します。