MicrosoftTeamsにGoogleNewsBotを入れてみた
ゴールイメージ
動機
- 会社の公認コミュニケーションツールがSlackじゃなくてTeamsになりそう
- Teamsのwebhookを使ってみたい
- お友達の作ったGoogleNewsBot for SlackをTeamsに改造してみよう
実行環境とフロー
- AWS
- CloudWatch ルールでLambda(Node.js)を定周期起動
- GoogleNewsRSSを利用して、指定したキーワドのNewsを取得して、Teamsに投げ込む
Teams側の設定
- Newsを表示したいチャンネルにIncoming Webhookコネクタを作成する必要がある。
- 詳しい解説記事が既にQiitaにあるのでこちら参照して作成してください(
チャネルの画面に戻ると 3 で付けた名前とアイコンの何者かが参加しています
まで実行すれば大丈夫)
ローカルで試してみよう
npmインストール
- request-promise
- request
- rss-parser
- さくっとやりたいので
serverless
は使わない
$ mkdir newsbot-teams
$ cd newsbot-teams
$ npm install request-promise request rss-parser
ソース
- 下記構成でそれぞれ作成してください
tree
.
├── index.js
├── google-news-service.js
├── main.js
└── package.json
index.js
index.js
'use strict';
const rp = require('request-promise');
const lodash = require('lodash');
const GoogleNewsService = require('./google-news-service.js');
function dateTimeFilter(articles, fromDate) {
return articles.filter((article) => {
const pubDate = new Date(article.pubDate);
return (pubDate.getTime() - fromDate.getTime()) > 1;
});
}
function post2Slack(teams_webhook,message) {
return rp.post(teams_webhook, {
headers: { "Content-type": "application/json" },
json: { text: message } ,
uri : teams_webhook
});
}
async function main(fromDate,teams_webhook,keywords) {
try {
const googleNews = await (new GoogleNewsService()).exec(keywords);
const news = lodash.uniqBy(dateTimeFilter(lodash.concat([], googleNews), fromDate), 'link');
const titleList = news.map((article) => {
return `・[${ article.title }](${ article.link })<br>`;
}).join('');
const message = 'ニュースとってきた。<br>' + titleList;
await post2Slack(teams_webhook,message);
} catch(error) {
console.error(error);
}
}
exports.handler = (event, context, callback) => {
const fromDate = new Date();
const teams_webhook = event['teams_webhook'];
const keywords = event['keywords'];
fromDate.setHours(fromDate.getHours() - event['fromHour']);
main(fromDate,teams_webhook,keywords);
};
google-news-service.js
google-news-service.js
const Parser = require('rss-parser');
module.exports = class GoogleNewsService {
constructor(){
}
createGoogleNewsUrl(keyword) {
return 'https://news.google.com/_/rss/search?q='
+ encodeURIComponent(keyword)
+ '&hl=ja&gl=JP&ceid=JP:ja';
}
async exec(keywords) {
const splitkeywords = keywords.split(',');
const parser = new Parser();
const feeds = await Promise.all(splitkeywords.map((keyword) => {
return parser.parseURL(this.createGoogleNewsUrl(keyword));
}));
const articles = [];
feeds.forEach((feed) => {
feed.items.forEach((item) => {
articles.push(item);
});
});
return articles;
}
}
main.js
- ローカルでlambdaっぽく呼ぶやつ
main.js
var event = {
version: '0',
id: 'XXXXXXXX-XXXXX-XXXX-XXXXX-XXXXXXXX',
'detail-type': 'Scheduled Event',
source: 'aws.events',
account: 'XXXXXXXXXX',
time: '2019-01-30T06:27:04Z',
region: 'ap-northeast-1',
resources:
[ 'arn:aws:events:ap-northeast-1:XXXXXXXXXX:rule/box-auditlog-exec' ],
detail: {},
fromHour : '10',
teams_webhook : 'https://outlook.office.com/webhook/XXXXXXXXXXXXXXXXXXXX/IncomingWebhook/XXXXXXXXXXX/XXXXXXXXXXXXXX',
keywords : 'AWS,GCP,Azure,CentOS,IDaaS,okta,onelogin,ゼロトラスト,zero trust,Nginx,Microsoft,Windows Server,脆弱性,ゼロデイ'
};
var context = {
invokeid: 'invokeid',
done: function(err,message){
return;
}
};
var lambda = require("./index.js");
lambda.handler(event,context);
適宜変更してください
- fromHour : 過去何時間分のニュースを取得するか設定
- teams_webhook : Teams webhooksのurl.
- keywords : 取得したいNewsキーワード
ローカルで実行
$ node main.js
AWSにアップして動かしてみよう
事前準備
AWSへデプロイ
- 今回はS3を経由しているが、S3を経由する必要は特に無い
$ zip -r newsbot-teams.zip index.js node_modules
$ aws s3 cp ./newsbot-teams.zip s3://[mybucket]/newsbot-teams.zip --profile [myprofile]
$ aws lambda update-function-code --function-name newsbot-teams --s3-bucket [mybucket] --s3-key newsbot-teams.zip --publish --profile [myprofile]
実行
- CloudWatch ルールに、lambdaを指定して引数を設定して起動する。
- 周期はお好きなように
GMTだから気をつけて
- 引数サンプル:
入力の設定
-定数(JSONテキスト)
- 周期はお好きなように
{"fromHour": "15", "teams_webhook": "https://outlook.office.com/webhook/xxxxxxx/IncomingWebhook/xxxxxxxxxxx/xxxxxxxx", "keywords": "AWS,GCP,Azure,CentOS,IDaaS,okta,onelogin,ゼロトラスト,zero trust,Nginx,Microsoft,Windows Server,脆弱性,ゼロデイ"}
部単位のチャンネルトとかに、部で共有したいNewsキーワードを設定して毎日1回とか数回ポストすると良いと思う。日常業務に忙殺されて、情報をキャッチアップできてない人多いし。
ソース置き場
こちらにソース置いておきます。(ソース汚かったらPullReqください)