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
関連記事
-
AWSアカウントの解約
アカウント作成メニュー確認のために作成したAWSアカウントを解約しました。 使っ …
-
AWS Cost Explorerの設定で「EC2リソースの推奨事項を受け取る」を有効にしました
「EC2リソースの推奨事項を受け取る」という機能がAWS Cost Explor …
-
EC2ユーザーデータからメタデータを取得してRocket.Chatで80ポートを使用する
Rocket.Chatのデフォルトポート番号は3000です。 80を使うようにす …
-
Amazon EMR 「Hadoop を使用してビッグデータを分析」チュートリアルをやってみました
AWS認定データアナリティクス受験準備の一環で、Amazon EMRのチュートリ …
-
GoogleForm,GASからAPI Gateway, Lambdaで入力情報をDynamoDBに格納する
vol.26 AWS認定試験テキスト認定クラウドプラクティショナーのデモ(Dyn …
-
AWSエンコードされたエラーメッセージをデコードするコマンドのメモ
Stdout: couldn’t create ENI: Unaut …
-
RDSリザーブドDBインスタンスを購入しました
リザーブドインスタンス推奨事項を確認したで確認した結果、購入したほうがよさそうで …
-
「streamlit勉強会」に参加しました
streamlitってなんだろう? と思いながら参加しまししました。 fin-p …
-
IAM Access Analyzerの検出をEventBridgeルールで検知して通知する
やりたかったことは使用可能としているリージョンのIAM Access Analy …
-
新しいVPCウィザード(2022年)がすんごく便利になってました
VPCウィザードがすんごく便利になってました。 ウィザードの左ペインで設定を選択 …