Feedlyのフィードを自動でSlackへ投稿する(AWS Lambda , Amazon DynamoDB)
目次
やりたいこと
Feedlyで共有したいフィードに特定のタグを付けます。
特定のタグがついたフィードは自動的にSlackへ投稿されます。
実現方法
FeedlyのAPIを使ってダイレクトでSlackへ投稿すればいいのですが、単純にそれをすると投稿が重複する可能性があるので、間にAmazon DynamoDBを挟みました。
(1) 5分ごとにAmazon CloudWatchスケジュールで実行されるLambdaが過去30分にFeedlyで特定のタグがつけられたフィードを取得して、Amazon DynamoDBに格納します。
(2) Amazon DynamoDBのストリームにより実行されたLambdaがレコードを受け取って、Slackへ投稿します。
パーティションキーをFeedlyのfeed_idにすることで同じフィードがDynamoDBに格納されないようにしました。
この方法だと、RSSリーダーを変更するときや増やすときは、(1)の機能だけ変更するか追加するかでいいので変化を考えやすいと思いました。
動作
例えばスマートフォンアプリのFeedlyでフィードに特定のタグを付けると、
5分間隔ぐらいでSlackに投稿されます。
ソースコード
- Python 3.6.1
ソースコードはGitHubにあります。
2つのディレクトリにLambda_Functionをそれぞれ入れているので、ご利用される場合はそれぞれでzipを作成して、Lambda関数を設定してください。
feedly_to_dynamo
Feedlyで特定のタグがつけられたフィードを取得して、Amazon DynamoDBに格納します。
環境変数
- FEEDLY_URL : FeedlyのAPI URLです。
- FEEDLY_TOKEN : Feedlyのトークンです。
- DYNAMO_TABLE : Amazon Dynamodbのテーブル名
- INTERVAL_MINUTE : 何分前に登録されたフィードから取得するか、指定しない場合は7日前から取得します。
- FEED_COUNT : 取得するフィードの最大数を指定。指定しない場合は100。
- ERROR_SLACK_URL : エラー発生時に通知したいSlackのWebhook Incoming URL
- ERROR_SLACK_CHANNEL : エラー発生時に通知したいSlackのチャンネル
- LOG_LEVEL : ログレベル。指定しない場合はERROR。
FeedlyのAPI URLの例
https://cloud.feedly.com/v3/streams/contents?streamId=user/userid/tag/tagname
詳しくはFeedlyのAPIのドキュメントを見てください。
Feedlyのトークン
FeedlyのAPIのドキュメント Developer Access Token内のStart hereリンクから取得してください。
コード抜粋 Feed取得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
unix_time = int(time.mktime(interval_time.timetuple())) * 1000 headers = {'Authorization': feedly_token} response_stream = requests.get( '{url}&count={count}&newerThan={time}'.format( url=feedly_url, count=feed_count, time=unix_time ), headers=headers ) stream_data = json.loads(response_stream.text) stream_datas = stream_data['items'] |
コード抜粋 DynamoDB格納
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
dynamodb = boto3.resource('dynamodb') table = dynamodb.Table(table_name) for stream in stream_datas: item = { 'id': stream['id'], 'url': stream['alternate'][0]['href'], 'title': stream['title'], 'origin': stream['origin']['title'] } if 'summary' in stream: item['summary'] = stream['summary']['content'] response = table.put_item( Item=item ) |
dynamo_to_slack
Amazon DynamoDBのストリームにより実行されたLambdaがレコードを受け取って、Slackへ投稿します。
環境変数
- SLACK_URL : 投稿先のSLACKのWebhook Incoming URL
- SLACK_CHANNEL : 投稿先のSlackのチャンネル
- ERROR_SLACK_URL : エラー発生時に通知したいSlackのWebhook Incoming URL
- ERROR_SLACK_CHANNEL : エラー発生時に通知したいSlackのチャンネル
- LOG_LEVEL : ログレベル。指定しない場合はERROR。
コード抜粋
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
feed = record['dynamodb']['NewImage'] url = feed['url']['S'] title = feed['title']['S'] origin = feed['origin']['S'] if 'summary' in feed: summary = feed['summary']['S'][0:100] + '....' else: summary = '' requests.post( slack_url, json.dumps( { 'channel': slack_channel, 'attachments':[ { 'author_name': origin, 'title': title, 'title_link': url, 'text': summary } ] } ) ) |
DynamoDBの設定
- パーティションキー : id
トリガー
トリガーにLambda関数を指定します。
参考 DynamoDB ストリーム イベント
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
{ 'Records': [ { 'eventID': '43dbcc14d38293df8c0112d99f3f82ad', 'eventName': 'INSERT', 'eventVersion': '1.1', 'eventSource': 'aws:dynamodb', 'awsRegion': 'ap-northeast-1', 'dynamodb': { 'ApproximateCreationDateTime': 1506497160.0, 'Keys': { 'id': { 'S': 'ErsO8+IlENj7fuWSmTbhEXLAVFekPDwIC2AoBs6/hf0=_15e9f3c95d3:3080da7:4cab23bc' } }, 'NewImage': { 'to_slack': { 'N': '0' }, 'id': { 'S': 'ErsO8+IlENj7fuWSmTbhEXLAVFekPDwIC2AoBs6/hf0=_15e9f3c95d3:3080da7:4cab23bc' }, 'url': { 'S': 'http://dev.classmethod.jp/cloud/aws/arrange-cflogs-for-athena-by-lambda/' } }, 'SequenceNumber': '108500000000004255644569', 'SizeBytes': 234, 'StreamViewType': 'NEW_AND_OLD_IMAGES' }, 'eventSourceARN': 'arn:aws:dynamodb:ap-northeast-1:123456789012:table/table/stream/2017-09-27T07:00:53.136' }, { 'eventID': 'f9870907827c1a85c1ec00ee6129daf2', 'eventName': 'INSERT', 'eventVersion': '1.1', 'eventSource': 'aws:dynamodb', 'awsRegion': 'ap-northeast-1', 'dynamodb': { 'ApproximateCreationDateTime': 1506497160.0, 'Keys': { 'id': { 'S': '+7yK2Kk1L25t94+pJoYpyyIvh8n5WvWLazJZb65JPpE=_15eab221e48:c66f83:c84bd0de' } }, 'NewImage': { 'to_slack': { 'N': '0' }, 'id': { 'S': '+7yK2Kk1L25t94+pJoYpyyIvh8n5WvWLazJZb65JPpE=_15eab221e48:c66f83:c84bd0de' }, 'url': { 'S': 'https://aws.amazon.com/blogs/big-data/query-and-visualize-aws-cost-and-usage-data-using-amazon-athena-and-amazon-quicksight/' } }, 'SequenceNumber': '108600000000004255644570', 'SizeBytes': 284, 'StreamViewType': 'NEW_AND_OLD_IMAGES' }, 'eventSourceARN': 'arn:aws:dynamodb:ap-northeast-1:123456789012:table/table/stream/2017-09-27T07:00:53.136' } ] } |
最後までお読みいただきましてありがとうございました!
「AWS認定資格試験テキスト&問題集 AWS認定ソリューションアーキテクト - プロフェッショナル 改訂第2版」という本を書きました。

「AWS認定資格試験テキスト AWS認定クラウドプラクティショナー 改訂第3版」という本を書きました。

「ポケットスタディ AWS認定 デベロッパーアソシエイト [DVA-C02対応] 」という本を書きました。

「要点整理から攻略するAWS認定ソリューションアーキテクト-アソシエイト」という本を書きました。

「AWSではじめるLinux入門ガイド」という本を書きました。


開発ベンダー5年、ユーザ企業システム部門通算9年、ITインストラクター5年目でプロトタイプビルダーもやりだしたSoftware Engineerです。
質問はコメントかSNSなどからお気軽にどうぞ。
出来る限りなるべく答えます。
このブログの内容/発言の一切は個人の見解であり、所属する組織とは関係ありません。
このブログは経験したことなどの共有を目的としており、手順や結果などを保証するものではありません。
ご参考にされる際は、読者様自身のご判断にてご対応をお願いいたします。
また、勉強会やイベントのレポートは自分が気になったことをメモしたり、聞いて思ったことを書いていますので、登壇者の意見や発表内容ではありません。
ad
ad
関連記事
-
-
Amazon CodeCatalystのスペースとプロジェクトを作成してみました
Amazon CodeCatalystはIAMユーザーで操作するのではなく、AW …
-
-
Amazon EC2(Amazon Linux 2)にRedmine3.4をインストール
久しぶりに新しい環境でRedmineを構築したくなり、せっかくなのでAmazon …
-
-
S3リクエストメトリクスをプレフィックスを指定して有効化
検証でどのリクエストがどれぐらい発生しているのか、さっと知りたくなったので、特定 …
-
-
WordPressで画像アップロードができなくなった(AWS WAFでブロックしていた)
WordPressで画像がアップロードできなくなりました。 こんなメッセージです …
-
-
AWS Lambda(Python3.7)でPandocを実行する
昨日まで(AWS Batch) 昨日までは、Pandocを実行して、S3バケット …
-
-
AWS Service Catalogチュートリアル
AWS Service Catalog 開始方法のチュートリアルにそってみました …
-
-
AWS Cost Explorerの履歴を38ヶ月とリソース別コストを見られるように設定しました
AWS Cost Explorer がより詳細な履歴データの提供を開始 知らなか …
-
-
EC2 プレイスメントグループを試してみました
やったことないのでやってみたやつです。 プレイスメントグループの作成 まず、EC …
-
-
Amazon FSx for Lustreのユーザーガイド入門演習
ファイルシステムの作成 FSx for Lustreを選択しました。 容量やスル …
-
-
slackのbotにWikipediaを調べてもらう(Python on AWS Lambda + API Gateway)
slackのbotに少しでも役に立ってもらおうと、Wikipediaを調べてもら …