猫の画像が次々届くサーバーレスなシステム

# はじめに

コロナ禍ですっかり疲れ切っている方も多いと思いますが、そんな時こそ一服の清涼剤が必要...ということで、**Slackのチャンネルに猫の画像が定期的に届くサーバーレスなシステム**を作ってみました。

なお、今回は[The Cat API](https://thecatapi.com/)から猫の画像を拝借しています。

# 1. Cat APIのAPIキーの取得

* [The Cat API](https://thecatapi.com/)のページを開いて、`SIGNUP FOR FREE`と書かれたボタンを押します。

![cat_api_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/ada25a20-6ef3-63bc-0a93-5cfb0150f874.png)

* 遷移先のページで、メールアドレスを記入して`SIGNUP`を押してしばらく待つと、`Welcome to The Cat API!Welcome to The Cat API!`というタイトルのメールが届きます。
 * `App Discription`については任意項目らしいので、拙い英語で書いても大丈夫でした(笑)
* このメールの中にAPIキーが記載されているので、それをメモしておきます。

![cat_api_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/85c8e28e-5e79-48fc-fda6-ffe4d917894b.png)

# 2. 猫画像配信用のチャンネルの作成

* 猫の画像がSlackのチャンネルにどんどん投稿されるため、猫画像配信用のチャンネルを作成しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/5012c2a3-5ca4-e0b7-4904-76e80f41bebe.png)

# 3. SlackのWebhook URLの取得

* 前の工程で作成したSlackのチャンネルに入り、`アプリを追加する`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/c30df0c1-dbbc-9a86-9b50-5822fb6e7c41.png)

* 遷移先の画面で検索欄に`webhook`と入力して、`Incoming Webhook`をインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/8bcb1180-2324-e740-32b0-b04a98eb3cd2.png)

* ブラウザに以下の画面が表示されたら、`Slackに追加`を押してIncoming Webhookをインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/3dc74546-5b5a-5d89-a472-c752b59172a3.png)

* 遷移先の画面で、前の工程で作成したSlackのチャンネルを選択して、`Incoming Webhookインテグレーションの追加`を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/141697ee-ff50-b41c-ceee-5f3dc29d3c25.png)

* 次の画面で、**「Incoming Webhook　○○○さんによって ○○○○年○○月○○日に追加されました」**と表示されれば、アプリのインストールは完了です。
* このページに`Webhook URL`と書かれている欄があるので、そこに書かれているURLをメモしておきます。
* また、このページの下部に`インテグレーションの設定`という設定画面があるため、今回はこの設定画面で以下の設定を変更しました。
  * 名前をカスタマイズ：「The Cat API」に変更。
  * アイコンをカスタマイズする：[こちらの記事](https://qiita.com/nkojima/items/1fb901c13f9707808bc0)で作成した猫の画像をアップロード。

# 4. Lambdaのコードの作成

## 4-1. Lambda関数の基本情報

* 以下の内容を関数の`基本的な情報`に設定しました。
 * 関数名：GetCatImage
 * ランタイム：Ruby2.7
 * アクセス権限（実行ロール）：基本的なLambdaアクセス権限で新しいロールを作成

## 4-2. lambda_function.rbの作成

* 幾つかのサイトを参考にして以下のコードを書いてみましたが、`slack-notifier`が存在しないためエラーになってしまいました。
* そこで、以下のサイトを参考にして「Gemfileを作成」→「bundle install」→「bundle install --deployment」→「ZIPとしてアップロード」という手順で試してみたところ、ようやく正常に動作しました。
  * [【ハンズオン】Ruby support for AWS Lambdaを使ってみる](https://qiita.com/harhogefoo/items/ecac4b0fa9475a8bd393)
  * [AWS Lambda の Ruby ランタイムを試す](http://blog.akanumahiroaki.com/entry/2018/12/01/170000)
  * [AWS Lambda上でgemがつかえない](https://teratail.com/questions/206614)

```rb:lambda_function.rb
require 'json'
require 'net/http'
require "bundler/setup"
require 'slack-notifier'

def lambda_handler(event:, context:)
    # Get image url from TheCatAPI.
    res = Net::HTTP.get(URI.parse('https://api.thecatapi.com/v1/images/search?api_key=xxxxxxxxxx'))
    json = JSON.parse(res)
    url = json[0]["url"]

    # Notification to Slack channel using Incoming Webhook.
    notifier = Slack::Notifier.new('https://hooks.slack.com/services/xxxxxxxxxx')
    notifier.ping(url, unfurl_links: true)
end
```

* なお、作成したGemfileは以下の通りです。

```text:Gemfile
source 'https://rubygems.org'
gem 'slack-notifier'
```

* また、Linux環境で`bundle install`を実行すると、以下のフォルダ構成となります。

```text:>bundle-installの実行結果@Windows環境
.
│  Gemfile
│  Gemfile.lock
│  lambda_function.rb
└─vendor
    └─bundle
```

## 4-3. ZIPファイルのアップロード

* `bundle install --deployment`を実行したフォルダを、丸ごとZIPで圧縮します。
* 次にLambdaの関数（GetCatImage）の画面に入り、関数コードの［コードエントリ］を`.zipファイルをアップロード`として、ZIPファイルをアップロードします。
  * アップロードファイルを選んだあと、画面右上の［保存］を押すとAWS側にアップロードされるようです。
* ここまで出来上がったら、［テスト］を実行して、Slackに通知が飛ぶかを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/e889ab17-c636-2581-d841-cd4fb4c3ea23.png)

# 5. CloudWatchのイベントの作成

* Lambdaの関数のページの上部で［設定］タブを選び、［Designer］の領域で`トリガーを追加`を押します。
* `トリガーを追加`画面で、以下の内容を記入して［追加］を押します。
  * トリガーの種類：CloudWatch Events/EventBridge
  * ルールタイプ：スケジュール式
  * スケジュール式：rate(1 hour)
  * トリガーの有効化：チェックあり
* 上記のように、今回は「毎時1回猫の画像（のURL）を取得して、Slackに通知する」という形になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/ecdb238a-490b-9476-d544-6abfcd5d0d4b.png)

# 6. 完成形

* 以下のように、指定されたチャンネルに毎時猫の画像が投稿されます。
* 疲れた時は、このチャンネルを見てちょっとだけリフレッシュしましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/d2e59d32-0a69-b847-06a3-da3ad8cd1f2d.png)


# 参考URL

## AWS CLI

* [aws cli install mac](https://qiita.com/maimai-swap/items/999eb69b7a4420d6ab64)

## Lambda

* [【ハンズオン】Ruby support for AWS Lambdaを使ってみる](https://qiita.com/harhogefoo/items/ecac4b0fa9475a8bd393)
* [AWS Lambda の Ruby ランタイムを試す](http://blog.akanumahiroaki.com/entry/2018/12/01/170000)
* [AWS Lambda上でgemがつかえない](https://teratail.com/questions/206614)
* [【AWS】lambdaファンクションを定期的に実行する](https://qiita.com/Toshinori_Hayashi/items/5b0a72dc64ced91717c0)

## SlackのWebhook

* [RubyでQiitaの投稿をSlackに通知する](https://qiita.com/sugawara_k/items/dd60fdfd3359da6f0284)
* [SlackのWebhook URL取得手順](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)
* [slack-notifierでrailsアプリからslackへ通知](https://qiita.com/michiharujp/items/9302b8075c39780c1418)
* [[AWS] API Gateway + Lambda for Ruby + S3 + Slack通知をSAMで構築](https://qiita.com/withelmo/items/9b8575cedc69f6af57e7)