LINE Botの勉強を始め、おうむ返し は作れました。更に応用することを考えたときにAPIとの連携ができることを知り、作ってみました。
下準備
① まずはこちらの記事を参考にLine Botを作る。
おうむ返しまで完了させる。
https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d
② obnizを扱うので、Visual Studio Codeのターミナルに、npm install obniz
(今後マトリックスLEDを扱うならば npm install canvas も)を入力し
実行しておく。
③ obnizスターターキットの用意
obnizの端子にパーツを接続
LED信号:gnd:0, green:1, yellow:2, red:3
④ OpenWeatherMapのAPIキーを取得(以下のHPを参照)
https://yuukiyg.hatenablog.jp/entry/2019/11/17/182410
実行
Visual Studio Codeに、以下のコードを入力し、各サーバーを立ち上げ、
LINE Developersの設定を行う。
①ターミナルに、
cd mylinebot を実行(mylinbotフォルダ内に入る)。
node server.js を実行。
②もう一つターミナルを開いて、
npx ngrok http 3000(npm ngrok http 3000 の方もいる)を実行。
③npx ngrok http 3000(又はnpm ngrok http 3000)サーバーに表示された
URL(HTTPSの方)をコピーして、LINE DEpelopersのHPの、Messaging APIタグの、
Webhook設定のWebhook URLに張り付け、後ろに「/webhook」をつける。
//【”天気”と入れると、今の天気・雲の様子・気温を返し、obinzの天気に対応するLED信号を点灯させる。】
'use strict';
const Obniz = require("obniz");
var obniz = new Obniz("xxxx-xxxx"); //obninzのIDを入力
obniz.onconnect = async function () {
//event(この場合はLineへの入力)よりも先にobniz.onconnectをしておく必要がある。
//全体をobnizの"{ }"で括ると扱いやすい様子。
var light = obniz.wired("Keyestudio_TrafficLight", {gnd:0, green:1, yellow:2, red:3});
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
const config = {
channelSecret: '{自分のchannelSecret}',
channelAccessToken: '{自分の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 === '天気'){
const axios = require('axios');
const main = async () => {
try {
let cname = 'Tokyo'
const res = await const res = await axios.get('http://api.openweathermap.org/data/2.5/weather?q=Tokyo&units=metric&APPID={自分のAPIキー}'); // URLを書き換える
console.log(res.data); // データ全体を表示する(なくてもOK)
let currentWeather = res.data.weather[0].main;
let description = res.data.weather[0].description;
let temp = res.data.main.temp;
let temp_max = res.data.main.temp_max;
let temp_min = res.data.main.temp_min;
let city = res.data.name;
var currentDate=new Date();
var y=currentDate.getFullYear();
var mo=currentDate.getMonth();
var d=currentDate.getDate();
var h=currentDate.getHours();
var m=currentDate.getMinutes();
var today=y + '年' + mo + '月' + d + '日'
var str=h+":"+m;
const RED_WEATHERS = [
"Rain",
"Snow",
"Thunderstorm",
"Drizzle",
"Fog",
"Squall"
];
const YELLOW_WEATHERS = [
"Clouds",
"Mist",
"Smoke",
"Dust",
"Haze",
"Sand",
"Ash",
"Tornado"
];
const GREEN_WEATHERS = ["Clear"];
let weather = res.data.weather[0].main;
let weather_ja = '晴れ'
switch (weather){
case 'Clear':
weather_ja = '晴れ';
break;
case 'Clouds':
weather_ja = 'くもり';
break;
case 'Mist':
weather_ja = 'もや';
break;
case 'Smoke':
weather_ja = '煙';
break;
case 'Dust':
weather_ja = 'ほこり';
break;
case 'Haze':
weather_ja = 'かすみ';
break;
case 'Sand':
weather_ja = '砂';
break;
case 'Ash':
weather_ja = '灰';
break;
case 'Tornado':
weather_ja = '竜巻';
break;
case 'Rain':
weather_ja = '雨';
break;
case 'Snow':
weather_ja = '雪';
break;
case 'Thunderstorm':
weather_ja = '雷雨';
case 'Drizzle':
weather_ja = '霧雨';
break;
case 'Fog':
weather_ja = '霧';
break;
case 'Squall':
weather_ja = 'スコール';
break;
}
let description_ja = 'なし'
switch (description){
case 'thunderstorm with light rain':
description_ja = '小雨で雷雨';
break;
case 'thunderstorm with rain':
description_ja = '雨で雷雨';
break;
case 'thunderstorm with heavy rain':
description_ja = '大雨で雷雨';
break;
case 'light thunderstorm':
description_ja = '軽い雷雨';
break;
case 'thunderstorm':
description_ja = '雷雨';
break;
case 'heavy thunderstorm':
description_ja = '激しい雷雨';
break;
case 'ragged thunderstorm':
description_ja = '不規則な雷雨';
break;
case 'thunderstorm with light drizzle':
description_ja = '軽い霧雨と雷雨 ';
break;
case 'thunderstorm with drizzle':
description_ja = '霧雨と雷雨';
break;
case 'thunderstorm with heavy drizzle':
description_ja = '激しい霧雨で雷雨';
break;
case 'light intensity drizzle':
description_ja = '弱い霧雨';
break;
case 'drizzle':
description_ja = '霧雨';
break;
case 'heavy intensity drizzle':
description_ja = '強い霧雨';
break;
case 'light intensity drizzle rain':
description_ja = '弱い霧雨';
break;
case 'drizzle rain':
description_ja = '霧雨';
break;
case 'heavy intensity drizzle rain':
description_ja = '激しい霧雨';
break;
case 'shower rain and drizzle':
description_ja = 'にわか雨と霧雨';
break;
case 'heavy shower rain and drizzle':
description_ja = '強いにわか雨と霧雨';
break;
case 'shower drizzle':
description_ja = 'にわか霧雨';
break;
case 'light rain':
description_ja = '小雨';
break;
case 'moderate rain':
description_ja = '中程度の雨';
break;
case 'heavy intensity rain':
description_ja = '大雨';
break;
case 'very heavy rain':
description_ja = '強い大雨';
break;
case 'extreme rain':
description_ja = 'とても強い大雨';
break;
case 'freezing rain':
description_ja = '凍雨';
break;
case 'light intensity shower rain':
description_ja = '弱いにわか雨';
break;
case 'shower rain':
description_ja = 'にわか雨';
break;
case 'heavy intensity shower rain':
description_ja = '激しいにわか雨';
break;
case 'ragged shower rain':
description_ja = '不規則なにわか雨';
break;
case 'light snow':
description_ja = '軽い雪';
break;
case 'Snow':
description_ja = '雪';
break;
case 'Heavy snow':
description_ja = '大雪';
break;
case 'Sleet':
description_ja = '霙(みぞれ)';
break;
case 'Light shower sleet':
description_ja = '弱いにわか霙(みぞれ)';
break;
case 'Shower sleet':
description_ja = 'にわか霙(みぞれ)';
break;
case 'Light rain and snow':
description_ja = '小雨と雪';
break;
case 'Rain and snow':
description_ja = '雨と雪';
break;
case 'Light shower snow':
description_ja = '弱いにわか雪';
break;
case 'Shower snow':
description_ja = 'にわか雪';
break;
case 'Heavy shower snow':
description_ja = '強いにわか雪';
break;
case 'mist':
description_ja = '靄(もや)';
break;
case 'Smoke':
description_ja = '煙';
break;
case 'Haze':
description_ja = '霞(かすみ)';
break;
case 'sand/ dust whirls':
description_ja = '砂/塵旋風';
break;
case 'fog':
description_ja = '霧(きり)';
break;
case 'sand':
description_ja = '砂';
break;
case 'dust':
description_ja = ' 塵';
break;
case 'volcanic ash':
description_ja = '火山灰';
break;
case 'squalls':
description_ja = 'スコール';
break;
case 'tornado':
description_ja = '竜巻';
break;
case 'clear sky':
description_ja = '澄んだ空';
break;
case 'few clouds':
description_ja = '少しの雲';
break;
case 'scattered clouds':
description_ja = '散乱雲';
break;
case 'broken clouds':
description_ja = '壊れた雲';
break;
case 'overcast clouds':
description_ja = '曇り雲';
break;
}
//LINE Botへの返信 の後に処理を記載すると、「到達できないコード」とエラーがでるので、先に記載をする。
if (currentWeather === undefined || currentWeather === null) {
light.green.off();
light.yellow.off();
light.red.off();
}
if (RED_WEATHERS.includes(currentWeather) === true) {
light.red.on();
} else if (YELLOW_WEATHERS.includes(currentWeather) === true) {
light.yellow.on();
} else if (GREEN_WEATHERS.includes(currentWeather) === true) {
light.green.on();
} else {
light.green.off();
light.yellow.off();
light.red.off();
}
let mes = ''; //LINE Botへの返信
mes = today + ' ' + str + ' ' + city + '\n' + '現在の天気は「'+ weather_ja +'」です。\n'+ '詳細:' + description_ja +'\n' + '気温は' + temp +'℃です。';
return client.replyMessage(event.replyToken, {
type: 'text',
text: mes,
});
} catch (error) {
console.error(error);
}
}
main();
}else if (event.message.text === 'オフ'){
light.green.off();
light.yellow.off();
light.red.off();
}else {
return client.replyMessage(event.replyToken, {
type: 'text',
text: '”天気” と入れてください。',
});
}
//返信コードはここまで
}
app.listen(PORT);
console.log(`Server running at ${PORT}`);
} //obniz.onconnectの閉じカッコ。
下のコードは、上コードを作成するベースに使ったコード
(obnizと連携させる前の、LINE BotとAPIの連携のみのコード)
//【”天気”と入れると、日時、今の天気・雲の様子・気温を返す。】
'use strict';
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
const config = {
channelSecret: '{自分のchannelSecret}',
channelAccessToken: '{自分の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 === '天気'){
const axios = require('axios');
const main = async () => {
try {
let cname = 'Tokyo'
const res = await axios.get('http://api.openweathermap.org/data/2.5/weather?q=Tokyo&units=metric&APPID={自分のAPIキー}'); // URLを書き換える
console.log(res.data); // データ全体を表示する(なくてもOK)
let currentWeather = res.data.weather[0].main;
let description = res.data.weather[0].description;
let temp = res.data.main.temp;
let temp_max = res.data.main.temp_max;
let temp_min = res.data.main.temp_min;
let city = res.data.name;
var currentDate=new Date();
var y=currentDate.getFullYear();
var mo=currentDate.getMonth();
var d=currentDate.getDate();
var h=currentDate.getHours();
var m=currentDate.getMinutes();
var today=y + '年' + mo + '月' + d + '日'
var str=h+":"+m;
let weather = res.data.weather[0].main;
let weather_ja = '晴れ'
switch (weather){
case 'Clear':
weather_ja = '晴れ';
break;
case 'Clouds':
weather_ja = 'くもり';
break;
case 'Mist':
weather_ja = 'もや';
break;
case 'Smoke':
weather_ja = '煙';
break;
case 'Dust':
weather_ja = 'ほこり';
break;
case 'Haze':
weather_ja = 'かすみ';
break;
case 'Sand':
weather_ja = '砂';
break;
case 'Ash':
weather_ja = '灰';
break;
case 'Tornado':
weather_ja = '竜巻';
break;
case 'Rain':
weather_ja = '雨';
break;
case 'Snow':
weather_ja = '雪';
break;
case 'Thunderstorm':
weather_ja = '雷雨';
case 'Drizzle':
weather_ja = '霧雨';
break;
case 'Fog':
weather_ja = '霧';
break;
case 'Squall':
weather_ja = 'スコール';
break;
}
let description_ja = 'なし'
switch (description){
case 'thunderstorm with light rain':
description_ja = '小雨で雷雨';
break;
case 'thunderstorm with rain':
description_ja = '雨で雷雨';
break;
case 'thunderstorm with heavy rain':
description_ja = '大雨で雷雨';
break;
case 'light thunderstorm':
description_ja = '軽い雷雨';
break;
case 'thunderstorm':
description_ja = '雷雨';
break;
case 'heavy thunderstorm':
description_ja = '激しい雷雨';
break;
case 'ragged thunderstorm':
description_ja = '不規則な雷雨';
break;
case 'thunderstorm with light drizzle':
description_ja = '軽い霧雨と雷雨 ';
break;
case 'thunderstorm with drizzle':
description_ja = '霧雨と雷雨';
break;
case 'thunderstorm with heavy drizzle':
description_ja = '激しい霧雨で雷雨';
break;
case 'light intensity drizzle':
description_ja = '弱い霧雨';
break;
case 'drizzle':
description_ja = '霧雨';
break;
case 'heavy intensity drizzle':
description_ja = '強い霧雨';
break;
case 'light intensity drizzle rain':
description_ja = '弱い霧雨';
break;
case 'drizzle rain':
description_ja = '霧雨';
break;
case 'heavy intensity drizzle rain':
description_ja = '激しい霧雨';
break;
case 'shower rain and drizzle':
description_ja = 'にわか雨と霧雨';
break;
case 'heavy shower rain and drizzle':
description_ja = '強いにわか雨と霧雨';
break;
case 'shower drizzle':
description_ja = 'にわか霧雨';
break;
case 'light rain':
description_ja = '小雨';
break;
case 'moderate rain':
description_ja = '中程度の雨';
break;
case 'heavy intensity rain':
description_ja = '大雨';
break;
case 'very heavy rain':
description_ja = '強い大雨';
break;
case 'extreme rain':
description_ja = 'とても強い大雨';
break;
case 'freezing rain':
description_ja = '凍雨';
break;
case 'light intensity shower rain':
description_ja = '弱いにわか雨';
break;
case 'shower rain':
description_ja = 'にわか雨';
break;
case 'heavy intensity shower rain':
description_ja = '激しいにわか雨';
break;
case 'ragged shower rain':
description_ja = '不規則なにわか雨';
break;
case 'light snow':
description_ja = '軽い雪';
break;
case 'Snow':
description_ja = '雪';
break;
case 'Heavy snow':
description_ja = '大雪';
break;
case 'Sleet':
description_ja = '霙(みぞれ)';
break;
case 'Light shower sleet':
description_ja = '弱いにわか霙(みぞれ)';
break;
case 'Shower sleet':
description_ja = 'にわか霙(みぞれ)';
break;
case 'Light rain and snow':
description_ja = '小雨と雪';
break;
case 'Rain and snow':
description_ja = '雨と雪';
break;
case 'Light shower snow':
description_ja = '弱いにわか雪';
break;
case 'Shower snow':
description_ja = 'にわか雪';
break;
case 'Heavy shower snow':
description_ja = '強いにわか雪';
break;
case 'mist':
description_ja = '靄(もや)';
break;
case 'Smoke':
description_ja = '煙';
break;
case 'Haze':
description_ja = '霞(かすみ)';
break;
case 'sand/ dust whirls':
description_ja = '砂/塵旋風';
break;
case 'fog':
description_ja = '霧(きり)';
break;
case 'sand':
description_ja = '砂';
break;
case 'dust':
description_ja = ' 塵';
break;
case 'volcanic ash':
description_ja = '火山灰';
break;
case 'squalls':
description_ja = 'スコール';
break;
case 'tornado':
description_ja = '竜巻';
break;
case 'clear sky':
description_ja = '澄んだ空';
break;
case 'few clouds':
description_ja = '少しの雲';
break;
case 'scattered clouds':
description_ja = '散乱雲';
break;
case 'broken clouds':
description_ja = '壊れた雲';
break;
case 'overcast clouds':
description_ja = '曇り雲';
break;
}
let mes = '';
mes = today + ' ' + str + ' ' + city + '\n' + '現在の天気は「'+ weather_ja +'」です。\n'+ '詳細:' + description_ja +'\n' + '気温は' + temp +'℃です。';
return client.replyMessage(event.replyToken, {
type: 'text',
text: mes,
});
} catch (error) {
console.error(error);
}
}
main();
}else {
return client.replyMessage(event.replyToken, {
type: 'text',
text: '”天気” と入れてください。',
});
}
//返信コードはここまで
}
app.listen(PORT);
console.log(`Server running at ${PORT}`);
仕様
●LINE Botに、”天気” と入力すると、今の天気・雲の様子・気温を返し、
obinzの天気に対応するLED信号を点灯させる。
●”オフ” と入力すると、LED信号を消灯する。
●その他の文字を入力すると、「”天気” と入れてください。」と返す。
工夫を要した箇所
① 「//返信コードはここから」~「 //返信コードはここまで」の間にLine Botへ
返信する内容を記載すれば実行できる。以前に作成した「Visual Studio Code
で、obnizに天気の情報を表示させ、天気に対応するLED信号を光らせる」
https://qiita.com/21HideK/items/9e8cf1a2ba3f1aae344e
を利用したので、作成自体は難しくはなかった。しかし記入の仕方が少し
違うだけでエラーが出てしまうのを修正するのに苦労した。
②obniz.onconnectを記載する場所が分からず、何度もエラーを生じた。
下記HPより、event(この場合はLineへの入力)よりも先にobniz.onconnectを
しておく必要があることが分かり、解決した。
③LINE Botへの返信の後に処理を記載すると、「到達できないコード」とエラー
がでるので、先に記載をする必要がある。
〔参考にしたHP〕
obnizとLineBotで防犯ツールを作ってみた(NO MORE XX 泥棒)
https://qiita.com/shima-07/items/e4d6a33c460da77e25ec?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items