1.作ったもの
朝7時にツイートを実行します。
①現在の全国の天気を画像でツイート
②現在の全国の天気と気温をテキストでツイート
③9時~24時までの3時間ごとの全国の天気と気温をテキストでツイート
④9時~24時までの3時間ごとの全国の天気を画像でツイート
(1)ツイート内容(2022/1/3のツイート)
(2)bot本体の仕様
以前作成した下記の星座占いbotに機能追加する形で実装しています。
[参考]【Node.js+heroku】Twitter星座占いbot作成
(3)設計書・プログラム
最新の設計書・プログラム等は下記のGoogleDriveに格納しています。
(過去の画像データ等が残ってしまっているため、GitHubは非公開設定です)
(4)天気情報の取得元
画像にもありますが、OpenWeatherMapからデータを取得しています。
2.設計
詳しくは設計書参照なのですが、簡単に説明すると以下の流れで処理しています。
(1)現在の全国の天気
①GoogleDriveから背景画像のデータを取得する
②OpenWeatherMapから各都市の現在の気象情報を取得する(weather指定)
③OpenWeatherMapから天候アイコン画像のデータを取得する
④天候アイコン画像のデータを背景画像に描画する
⑤編集した背景画像をツイート
⑥現在の気象情報テキストをツイート
(2)3時間ごとの全国の天気
①GoogleDriveから背景画像のデータを取得する
②OpenWeatherMapから各都市の3時間ごとの気象情報を取得する(forecast指定)
③3時間ごとの気象情報テキストをツイート
④OpenWeatherMapから天候アイコン画像のデータを取得する
⑤天候アイコン画像のデータを背景画像に描画する
⑥編集した背景画像をツイート
3.実装
(1)OpenWeatherMapのAPI呼出し
詳しくはプログラム参照なのですが、APIを呼び出す関数は本体から以下のソースに切り出しています。
request-promiseを使えば関数1つずつで済むのではないか、ということに後から気付きましたが、今後機会があれば修正したいと思います…
"use strict";
//----------external function declaration----------
const subs = require('./subFunc');
//----------const declaration----------
const request = require('request');
//----------OpenWeatherMap functions----------
function forecast(city, api_key) {
return new Promise(function(resolve, reject) {
callForecast(city, api_key, function (error, data) {
if (!error) {
resolve(data);
} else {
let error_msg = "OWM API(forecast) call error(" + city + ")." + subs.editErrMsg(error);
reject(error_msg);
}
});
});
}
function callForecast(city, api_key, callback) {
var url = 'http://api.openweathermap.org/data/2.5/forecast?q=' + city + ',jp&units=metric&cnt=6&lang=ja&appid=' + api_key;
request({ url: url, json: true }, function (error, response) {
if (!error) {
callback(null, response.body);
} else {
callback(subs.editErrMsg(error));
}
})
}
function weather(city, api_key) {
return new Promise(function(resolve, reject) {
callWeather(city, api_key, function (error, data) {
if (!error) {
resolve(data);
} else {
let error_msg = "OWM API(weather) call error(" + city + ")." + subs.editErrMsg(error);
reject(error_msg);
}
});
});
}
function callWeather(city, api_key, callback) {
var url = 'http://api.openweathermap.org/data/2.5/weather?q=' + city + ',jp&units=metric&lang=ja&appid=' + api_key;
request({ url: url, json: true }, function (error, response) {
if (!error) {
callback(null, response.body);
} else {
callback(subs.editErrMsg(error));
}
})
}
(2)天候アイコンの読込
天候アイコンの読込は以下のように行っています。
node-canvasのloadImageメソッドに天候アイコンのURLを渡す形で画像データを取得しています。
"use strict";
//----------external function declaration----------
const canvas = require('canvas');
//~省略~
function loadCanvasImage(load_data) {
return new Promise(async function(resolve, reject) {
try {
let res = await canvas.loadImage(load_data);
resolve(res);
} catch (error) {
reject("Data load error." + "Data:(" + load_data + ")" + editErrMsg(error));
}
});
}
(3)APIキーの設定
APIキーはherokuのコンフィグ管理画面から追加しています。
4.参考サイト
(1)OpenWeatherMap関連
[参考]Weather API - OpenWeatherMap
[参考]無料天気予報APIのOpenWeatherMapを使ってみる
[参考]Node.jsでお天気を取得してみよう
[参考]無料天気予報API【OpenWeatherMap】を使って天気予報サイトデモを作ってみた ~APIの呼び出し編~
(2)URLから画像の読込
[参考]node-canvas
(3)Googleドライブから画像データを取得
[参考]【Node.js, heroku】Googleドライブの操作(データ取得/更新)