たった20行で電力ひっ迫状況をslackへ通知する

お盆過ぎて少しずつ秋の気配を感じるようになりましたが、まだまだ日中は暑い日が続きますね。
2022年は観測史上最速の梅雨明けだったこともあり電力需給ひっ迫のリスクが高いと連日報道されていました。

1人1人のこまめな省エネ・節電がとても大切な時期だと思い、日々のでんき予報をslackへ通知するようにしてみました。

## 完成形のイメージ
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14082/a9be8495-9233-720c-5d71-20617e41fd35.png)|
|---|

今回はお手軽に定時実行を行いたかったため GoogleAppsScript を利用しています。
実装は以下の流れで行いました。
- slack アプリの作成と認証トークンの生成
  - 詳しく解説されている記事があったのでこの記事では省略します。
    - [Slack API 推奨Tokenについて \- Qiita](https://qiita.com/ykhirao/items/3b19ee6a1458cfb4ba21)
- 画面キャプチャの実装
- slackへの画面キャプチャのアップロードの実装
- 定期実行の設定


## 画面キャプチャの実装
今回は[ApiFlash](https://apiflash.com/)という無料で月100枚まで画面のスクリーンショットを撮ってくれるAPIを利用します。
アカウント登録を行うとAPIキーが発行されるのでAPIキーとスクリーンショットを取りたいURLをAPIへ投げてやるだけです。

今回は東京電力パワーグリッド株式会社より提供されている[でんき予報](https://www.tepco.co.jp/forecast/)を対象にします。

```js
https://api.apiflash.com/v1/urltoimage?access_key=【APIキー】&url=【取得したいURL】
```


|![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14082/a2328804-8171-6d43-c35a-a37aaeba7d6d.png)|
|---|

初期状態ではこのように指定したURLのスクリーンショットが返ってきます。
このとき何も指定しないと1920ｘ1080pxというサイズになります。

APIパラメータを指定することで様々な指定することができます。


|  パラメータ名 | 初期値 | 説明　|
|:---:|:---:|:---|
|  format | jpeg | キャプチャする画像の種類を指定します。jpeg・png・webpが指定できます。 |
|  element |  | 指定したCSSセレクタにマッチした最初の要素のスクリーンショットをキャプチャします。 |
|  wait_until | network_idle| 指定された条件が満たされるまで待ち、ページの読み込みが終了したとみなします。<br />指定可能な基準は以下の3通り。<br />dom_loaded は、スタイルシートや画像の読み込みが終了するのを待たずに、HTML ドキュメントが完全に読み込まれるまで待ちます。<br />page_loaded は、スタイルシートや画像などの依存リソースを含む、ページ全体が読み込まれるまで待ちます。<br />network_idle は、ページ全体が読み込まれ、ネットワークがアイドル状態になるまで待ちます（ネットワーク接続がアクティブでなくなる）。 |
|  css |  | キャプチャする際に、ウェブページに挿入されるCSS文字列です。<br />このCSS文字列はURLエンコードされている必要があります。|

この他にも様々なパラメータの指定が可能です。
興味のある方は[ApiFlashのAPIドキュメント](https://apiflash.com/documentation)をご参照ください。

## slackへの画面キャプチャのアップロードの実装
先述のパラメータをゴニョゴニョと組み合わせ完成イメージのキャプチャが撮れるようになったので、次にslackへ投稿する部分の実装をおこないます。 

取得した画像ファイルからblobオブジェクト取得しを`https://slack.com/api/files.upload`へ`POST`で投げてやるだけです。 


```js

const response = UrlFetchApp.fetch("【画像のURL】");
const blob = response.getBlob();

const PAYLOAD = {
  'token'     : "【slaskの認証トークン】",
  'file'      : blob,
  'channels'  : "【投稿したいチャンネルのID】",
  'title'     : "【アップする画像のタイトル】",
};

const OPTIONS = { 'method' : 'post', 'payload': PAYLOAD };
const result = UrlFetchApp.fetch('https://slack.com/api/files.upload', OPTIONS);
```


## 定期実行の設定

最後にGoogleAppsScriptのトリガーを設定し定期実行されるようにします。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14082/29c6cee5-08a8-ceae-0a00-03c4e6442249.png)|
|---|


## 完成
以上で完成です！
たった20行で電力ひっ迫状況をslackへ通知できるようになりました。

```js:main.gs
function getElectricityForecast() {
  const API_KEY = "【APIキー】";
  const TARGET_URL = "https://www.tepco.co.jp/forecast/";
  const API_URL = "https://api.apiflash.com/v1/urltoimage";
  const CSS_SELECTOR = "div.inner";
  const CSS_STYLES = "div.day_area.aven%7Bdisplay%3Anone%3B%7D%23content-forecast+.tab_box+.next_day%7Bdisplay%3Anone+%21important%3B%7D%23content-forecast+.tab_box+.inner%7Bpadding%3A15px+%21important%3B%7D";
  const CAPTURING_URL = `${API_URL}?access_key=${API_KEY}&wait_until=page_loaded&url=${TARGET_URL}&element=${CSS_SELECTOR}&css=${CSS_STYLES}`;

  const response = UrlFetchApp.fetch(CAPTURING_URL);
  const blob = response.getBlob();

  const PAYLOAD = {
    'token'     : "【slaskの認証トークン】",
    'file'      : blob,
    'channels'  : "【投稿したいチャンネルのID】",
    'title'     : "本日の電力使用状況",
  };

  const OPTIONS = { 'method' : 'post', 'payload': PAYLOAD };
  const result = UrlFetchApp.fetch('https://slack.com/api/files.upload', OPTIONS);
}
```

## 参考
- [Website screenshot API \| ApiFlash](https://apiflash.com/)
- [でんき予報｜東京電力パワーグリッド株式会社｜東京電力ホールディングス株式会社](https://www.tepco.co.jp/forecast/)
- [files\.upload method \| Slack](https://api.slack.com/methods/files.upload)
- [Slackにファイルをアップロードする \- Qiita](https://qiita.com/yaju/items/2e1ab8a25b6e207bfbe6)
- [Slack API 推奨Tokenについて \- Qiita](https://qiita.com/ykhirao/items/3b19ee6a1458cfb4ba21)