【Google Apps Script】DiscordのWebhookを使って毎朝天気を通知する(Discord Bot改良:第1回)

1544 語
8 分
【Google Apps Script】DiscordのWebhookを使って毎朝天気を通知する(Discord Bot改良:第1回)

はじまり#

リサちゃん avatar
リサちゃん
あ〜! 濡れた濡れた・・・
135ml avatar
135ml
お、お帰りさん、ズブ濡れだねえ
リサちゃん avatar
リサちゃん
今日、夕方から雨が降るなんて聞いてないよお・・・
135ml avatar
135ml
じゃあ、今回はその日に雨が降るかどうかをDiscordで通知してくれるツールを作ってみよう
リサちゃん avatar
リサちゃん
おおっ。

ツールの概要#

今回は、DiscordのWebhookを使って、OpenWeatherMapというサイトから気象情報を取得します。

ツールを作る言語は、Google Apps Scriptを使用します。 APIをタダで作れるため、個人利用の範囲内であれば、とてもコスパが良いです。 ツールの概要はこんな感じ。

機能#

Discordに通知するまでの機能の紹介です。 実際に時間トリガーでWebhookが作動するとこのように通知されます。

気温と雨の時間帯を通知するために、以下の情報を取得する必要がありますね。

  • その日の天気(その日の8つの時間帯における天気を集計して最多の天気を取得する)
  • 最高気温
  • 最低気温
  • 任意の時間における天気

気象情報を取得する#

まずは、Google Apps Scriptから、OpenWeatherMapのWeather APIにGETでリクエストを送ります。 大体3、4日分くらいを3時間おきでブツ切りされた気象情報がレスポンスで返ってきます。

[ { dt: 1676224800,
main:
{ temp: 282.88,
feels_like: 281.08,
temp_min: 282.88,
temp_max: 283.2,
pressure: 1014,
sea_level: 1014,
grnd_level: 1009,
humidity: 68,
temp_kf: -0.32 },
weather: [ [Object] ],
clouds: { all: 75 },
wind: { speed: 3.47, deg: 2, gust: 5.47 },
visibility: 10000,
pop: 0.42,
rain: { '3h': 0.43 },
sys: { pod: 'n' },
dt_txt: '2023-02-12 18:00:00' },
{ dt: 1676235600,
main:
{ temp: 282.84,
feels_like: 281.32,
temp_min: 282.75,
temp_max: 282.84,
pressure: 1014,
sea_level: 1014,
grnd_level: 1008,
humidity: 66,
temp_kf: 0.09 },
weather: [ [Object] ],
clouds: { all: 83 },
wind: { speed: 2.95, deg: 7, gust: 4.8 },
visibility: 10000,
pop: 0.3,
sys: { pod: 'n' },
dt_txt: '2023-02-12 21:00:00' },
.
.
.
]

まずは、その日の天気を決めます。 天気の決め方は、その日の8つの時間帯(0:00、3:00、6:00、9:00、12:00、15:00、18:00、21:00)における天気を集計して、その中で最も多かった天気をその日の天気とします。 天気の種類は、以下のリファレンスに載っています。天気のステータスコードが5xxだと雨になります。 5xxや8xxなどの状態をグループごとに集計して天気を決めました。

おそらく、main属性のオブジェクトにあるtemp_mintemp_maxで、その時間帯の気温を取ってこれます。その気温を1日ごとに集計して、その日の最高気温と最低気温を割り出しました。

最後に、雨の状態になっている時間帯をオブジェクトにメモっておきました。 これで、僕が欲しかった情報は手に入りました。

WebhookでDiscordに通知する#

天気の情報を整理してオブジェクト形式に出来たら、それをJSON形式でDiscordのWebhookに送ります。 以下のように送ることで、Discordでメッセージを送信できるかと思います。 muteHttpExceptionsはどちらでも良いような気がします。 ログの見え方が変わるらしいですが、ぶっちゃけ、trueでもfalseでもログの見え方は大して変わると思っていません。

function getReqHeaders(type="json"){
let contentType = "";
switch(type){
case "json":
contentType = "application/json"
}
const requestHeaders = {
"Content-Type": contentType
}
return requestHeaders;
}
const webhookUrl = "WEBHOOKのURL";
let options = {
method: "POST"
, payload: JSON.stringify(payload)
, headers: getReqHeaders("json")
, muteHttpExceptions : true
}
let res = UrlFetchApp.fetch(webhookUrl, options);

通知内容を凝りたい#

通知するところまでは出来たので、通知するときのデザインを確認します。 先程貼った通知の内容にするためには、こんな感じのコードになります。単なる一部抜粋になります。 infoに整理したオブジェクトがあって、それをmapでどーのこーのしています。 最高気温Maxと最低気温Minを並べて表示したかったので、"embeds"属性の"fields"属性を使って並べました。

let embedsArray = keys.map(location => {
let items = info[location];
if(items[keyRO]["weather"].length === 0){
content = "今日は雨が降らないみたいだよ!";
}else{
content = "今日は雨が降るみたいだよ!";
for(let i = 0; i < items[keyRO]["weather"].length; i++){
console.log(items[keyRO]["time"][i]);
r = `${items[keyRO]["time"][i]["hour"]}:${items[keyRO]["time"][i]["minute"]}:${items[keyRO]["time"][i]["second"]} - ${items[keyRO]["weather"][i]}`;
content = `${content}\r${r}`;
}
}
let embeds = [];
for(let i = 0; i < items[keyTF].length; i++){
imageFileUrl = getImageFileUrl(items[keyWF][i]["weather"], imageFolderUrl);
author = getDateDesignation(i);
iconUrl = "https://openweathermap.org/themes/openweathermap/assets/vendor/owm/img/icons/favicon.ico";
embeds.push({
"title": items[keyTF][i]["date"]
, "color": "15494471"
, "author": {
"name": author
, "url": "https://openweathermap.org/city/?q=Tokyo"
, "icon_url": iconUrl
}
, "footer": {
"text": "OpenWeatherMap"
, "icon_url": iconUrl
}
, "fields": [
{
"name" : "Max"
, "value" : `${items[keyTF][i]["temp_max"]}`
, "inline": true
}
, {
"name" : "Min"
, "value" : `${items[keyTF][i]["temp_min"]}`
, "inline": true
}
]
, "thumbnail": {
"url" : imageFileUrl
}
})
}
return embeds;
})

画像にリンクを埋め込むやつを本文中で使えるかどうかを試してみましたが、それは出来ないようです。

let urlSite = "https://openweathermap.org/city/?q=Tokyo";
let urlImage = "https://openweathermap.org/themes/openweathermap/assets/img/logo_white_cropped.png";
ontent = `${content}\r[![OpenWeatherMap](${urlImage})](${urlSite})`;
const payload = {
"username": "お天気あゆ"
, "content": content
, "embeds": returnEmbeds
// , "tts": true
}

少し詰まったところ#

以下、少し詰まったところです。

ICO形式のファイルは表示できない#

また、Discord上では.ico拡張子のファイルは表示できないみたいでした。 2つ上に貼ったコード内のiconUrlが該当箇所です。 後ほど、自分で.png形式に変えて別の場所から公開したものをリンクに付けると、ちゃんとファビコンがDiscord上で表示されました。

Number型のままでは、リクエスト時にエラーになる#

これは、Discord Webhookとか関係ないかと思いますが、最高気温と最低気温をNumber型のまま、オブジェクトをJSONにしたら、Discordへのリクエストを正常にできませんでした。 そのため、NumberをStringにして、JSON.stringifyしています。

ちなみに、しゃべらせることができる#

ちなみに、1つ上に貼ったコード内の”tts”: trueですが、これをリクエストにちゃんと載せると、Discordで表示されたテキストのとおりに喋り始めます。 画像の場合だと、「今日は雨が降るみたいだよ。ぜろじぜろぜろふんぜろぜろびょう・・・」といった具合になります。 使いどころですね・・・

おしまい#

リサちゃん avatar
リサちゃん
うわ、通知されてきた!
135ml avatar
135ml
DiscordのWebhookを使ったツールは、通知するだけなら比較的簡単に作れます。ぜひ試してみて下さい。
リサちゃん avatar
リサちゃん
他にも何か作れないかなあ

以上になります!

記事を共有

この記事が役に立ったなら、ぜひ他の人と共有してください!

【Google Apps Script】DiscordのWebhookを使って毎朝天気を通知する(Discord Bot改良:第1回)
https://endorphinbath.com/posts/gas-discord-webhook-weather/
著者
kinkinbeer135ml
公開日
2023-02-12
ライセンス
CC BY-NC-SA 4.0
関連記事 スマート
1
【Google Apps Script】DiscordのWebhookを使って行動を習慣化する
Code DiscordのWebhookをGoogle Apps Scriptで叩いて、行動を習慣化するためのツールを作りました。指定した時間帯は通知をオフにします。
2
【Python】Pycordでボットの機能を増やした(Discord Bot改良:第2回)
Code 以前にRenderでビルドしていたDiscordのボットを刷新していきます。pycordを使って、スラッシュコマンドの実装、オートコンプリートの適用などを行いました。
3
【GAS】Google Apps Scriptで作った自作関数に対してテストコードを書けるライブラリ「TestGAS」を作りました!
Code Google Apps Scriptで作った関数に対して、テストコードを使って動作を検証するためのツール「TestGAS」を作成および公開しました。初めて作ったテストツールですが、個人的にかなり便利なものになったので、ぜひ使ってみて下さい。
4
【Notion API】Google Apps Scriptでリッチテキストの編集を自動化する
Code NotionのAPIを使って、ページ内のブロックのリッチテキストを自動的に編集する方法を紹介します。日々の日記用のページを自動作成したり、自動更新することが出来るようになります。
5
【Notion API】Google Apps Scriptでデータベースからページの中身を取得する
Code NotionのDatabase API、Page API、Block APIでページの内容を取得する方法を紹介します。ベースはJavaScriptなのでNode.js、Deno、Bunでも流用できるかと。
ランダム記事 ランダム
Profile Image of the Author
kinkinbeer135ml
SIerをやめて、プログラミングを勉強しています。※Amazonアソシエイトに参加しています。
お知らせ
私のブログへようこそ!これはサンプルのお知らせです。
音楽
カバー

音楽

再生中なし

0:00 0:00
歌詞なし
カテゴリ
タグ
サイト統計
記事
287
カテゴリー
8
タグ
93
総文字数
486,174
運用日数
0
最終活動
0 日前

目次