株価チャートって見てて面白いですよね!(株やってないですが)
googleで 企業名 株価
って検索すると
その企業の株価チャートを表示してくれるのに気づいたので、
puppeteerを使ってその部分のスクリーンショットを取得して
Slackに投稿してくれるBotを作ってみました
つくったもの
Github: https://github.com/tamanugi/slack_bot_stock_chart
キャプチャのようにbotにメンションつけてメッセージ送ると
{メッセージ} 株価
でGoogle検索を実行して
出てきた株価の部分のスクリーンショットをslackにアップロードしてくれます。
また Google の株価チャートは期間指定ができるのですが、そちらも選択できるようにしています
つかったもの
- botkit
- puppeteer
中身とか
const StockCapture = require('./lib/stock_capture.js')
if (!process.env.token) {
console.log('Error: Specify token in environment');
process.exit(1);
}
var Botkit = require('botkit');
let fs = require('fs')
var controller = Botkit.slackbot({
debug: false
});
var bot = controller.spawn({
token: process.env.token
}).startRTM();
controller.hears(['(.*)'],['direct_message', 'direct_mention', 'mention'], function(bot, message) {
let arg = message.match[1]
let company, period;
let match = arg.match(/(.*)(1日|5日|1か月|3か月|1年|5年|最長)$/)
if(match) {
company = match[1]
period = match[2]
}else{
company = arg
}
StockCapture.capture(company, period, () => {
bot.api.files.upload({
file: fs.createReadStream('stock-chart.png'),
filename: 'stock-chart.png',
channels: message.channel
},(err,res) => {
if (err) console.log(err)
})
})
});
botkitを使ってファイルをアップロードする方法については
以前書いた自分の記事を参考にしました
参考: Botkitで画像ファイルをslackにアップロードする
const puppeteer = require('puppeteer');
const periods = {
'1日': '1d',
'5日': '5d',
'1か月': '1M',
'3か月': '3M',
'1年': '1Y',
'5年': '5Y',
'最長': '40Y',
}
const capture = async (company, period ,cb) => {
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
const targetElementSelector = '#fac-ut'
await page.goto('https://google.co.jp')
await page.type('#lst-ib', `${company} 株価`)
await page.click('#tsf > div.tsf-p > div.jsb > center > input[type="submit"]:nth-child(1)')
await page.waitFor(targetElementSelector)
if(period){
const dataPeriod = periods[period]
await page.click(`#fac-sbtns > ol > li[data-period='${dataPeriod}']`)
await page.waitFor(1000)
}
const clip = await page.evaluate(s => {
const el = document.querySelector(s)
// エレメントの高さと位置を取得
let { width, height, top: y, left: x } = el.getBoundingClientRect()
// padding分調整
width += 32
height += 36
x -= 16
y += 4
return { width, height, x , y}
}, targetElementSelector)
// スクリーンショットに位置と大きさを指定してclipする
await page.screenshot({ clip, path: 'stock-chart.png' })
cb()
browser.close();
};
module.exports.capture = capture
株価を表示している部分は div#fac-ut
になりますので
位置と大きさを取得してスクリーンショット取る際に引数に指定しています。
取得できる位置と大きさと実際に欲しい部分がずれていたのでそこは調整しています。(padding分だけずれた?)
puppeteerを使ってあるエレメントのスクリーンショットを取得する方法は
過去にまとめたので、そちらもご参考いただけると幸いです
Puppeteerを使って指定したDOMのみのスクリーンショットを取得する
まとめとか
puppeteerもbotkitもほんとにお手軽に使えるので
ちょっとしたChat Bot作る際に役立ちますね~~
もっと色々と作ってみようと思います
よーしこれで仕事中に株価ウォッチできるぞー