Ruby2.5.0 × AWS LambdaでFeedlyの未読記事をSlackに通知する

今回はタイトルにある通りRSSリーダーであるFeedlyを使って未読記事をSlackに通知する方法を共有したいと思います！

Feedlyを使っていない人でもLambdaをRubyで使ったりと応用の効く記事にしたつもりなので良かったら読んで行ってください！

## 経緯
Feedly開いて登録してあるWebサイトに新着記事がないか確認して、なかったら閉じて...
と短期間に何回も確認するのは**めんどくさい！！** でも新着が**気になる！！**
と思った怠惰な僕は、新着記事があったらSlackで教えてくれるものがあったらなと思ったので、タイトルにある通りSlackに未読記事を通知するスクリプトを作りました。
Lambdaの言語選択ですが、普段から使っていて昨年12月からサポートされたRubyを使います。

## 必要なもの

- AWSのアカウント

- Slackのアカウント

- WebhookのURL(Slack)
[参考記事](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)

- Feedlyのaccess_tokenとuser_id
[参考記事](https://yatta47.hateblo.jp/entry/2016/10/13/221757)

以上です。揃っていない方は参考記事からお願いします！
## 実装

### Feedly API 調査
まずFeedly APIの[公式サイト](https://developer.feedly.com/)を見ると
<img width="1680" alt="スクリーンショット 2019-02-02 15.06.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/285956/76b141e6-4c0b-6a5a-ade8-edbf25cdeb0b.png">
沢山ありますね:sweat:

APIのカテゴリー(画像右)を見ていくとStreamsにありそうですね！

中を見ていくとそれらしき記載が！

<img width="717" alt="スクリーンショット 2019-02-02 15.10.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/285956/be7d1b48-712f-4a57-4736-8952ed8dee74.png">

とりあえず書いてある通り ` unread=true ` オプションを付けてあげれば取得できるのではないか！と思い

```

`curl -H 'Authorization:[取得したuser_id]' https://cloud.feedly.com/v3/streams/contents?streamId=[取得したuser_id]/unreadOnly=true 
```

と実行したところ 

```
{"errorCode":400,"errorId":"ap8int-sv2.2019020122.1070524","errorMessage":"invalid stream id"}
```
400が返ってきた:sob:

stream_idにuser_idは使えないのかなー とか考えてググった所[ドンピシャな記事](https://stackoverflow.com/questions/52029716/how-to-get-all-unread-items-using-feedly-api)を発見！

この記事の通り

```
curl -H 'Authorization:[取得したuser_id]' https://cloud.feedly.com/v3/streams/contents?streamId=user/[取得したuser_id]/category/global.all&unreadOnly 
```

とした所、取得できました！

レスポンスを加工する必要があるのでそのロジックをRubyで組んでLambdaで定期実行します！

### Gemfileに記述
今回はhttp_clientとslackのGemを使用する為Gemfileに

```ruby:Gemfile
source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'httpclient'
gem 'slack-notifier'

```
と記述し、

```
bundle install --path vendor/bundle
```
を実行し、vendor配下にパスを指定してください（lamdbaにアップロードする時に使います）

### 実行ファイル作成
そして、実行ファイルに

```ruby:fetch_unread_article.rb
require 'httpclient'
require 'json'
require 'slack-notifier'

# APIから未読記事を取得する
def get_unread_articles
  client = HTTPClient.new
  query = { unreadOnly: true }
  response = client.get("https://cloud.feedly.com/v3/streams/contents?streamId=user/#{ENV['STREAM_ID']}/category/global.all", query: query, header: [["Authorization", "#{ENV['ACCESS_TOKEN']}"]])
  response.status == 200 ? create_message(set_articles(response)) : post_slack('APIのエラーで記事を正常に取得できませんでした！')
end

# responseから未読記事のタイトルとURLを取得
def set_articles(response)
  article_title_and_url = []
  body = JSON.parse response.body
  body['items'].each do |item|
    article = []
    article.push(item['title'])
    article.push(item['originId'])
    article_title_and_url.push(article)
  end
  article_title_and_url
end


def create_message(title_and_urls)
  message = ''
  title_and_urls.each do |c|
    message << "\rタイトルは#{c[0]}\rURLは#{c[1]}です。\r"
  end
  post_slack(message)
end

def post_slack(message)
  notifier = Slack::Notifier.new("#{ENV['WEB_HOOK_URL']}")
  message.empty? ? notifier.ping('未読の記事はありません！') : notifier.ping(message)
end

def lambda_handler(event:, context:)
  get_unread_articles
end

```

と記述し、lambdaに上げる為にvendorの配下と実行対象ファイルをzip化します。

```
 zip -r fetch_unread_article.zip fetch_unread_article.rb vendor/
```

### lambdaにアップロード
そして lambdaにアップロードします！
<img width="1532" alt="スクリーンショット 2019-02-02 16.51.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/285956/40062c05-58c8-425c-5300-1a9a6b0d3b8b.png">

Handlerの箇所で ` fetch_unread_article.lambda_handler ` となっているか注意してください。
ここは ` 実行ファイル名.実行関数名 ` となっているので、自分でファイル名や実行関数を任意の値にする事もできます！

lambdaに設定したらSaveしてください。
その後テストを押してみて下さい。

<img width="1379" alt="スクリーンショット 2019-02-02 17.00.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/285956/8dbc7329-1d1d-a705-b4b0-286824b62e4e.png">

このように通知が来ていたら成功です！

その後、定期実行する為に、CloudWatch Eventを使います。
Cloudwatch Eventの説明は[こちら記事](https://qiita.com/seisyu1985/items/518b4a899cf91a43b0e4)が分かりやすいので参照してください。

以上です！