Edited at

仕事中でも株価を見るために株価チャートを投稿するSlack botを作ってみた

More than 1 year has passed since last update.

株価チャートって見てて面白いですよね!(株やってないですが)

googleで 企業名 株価って検索すると

その企業の株価チャートを表示してくれるのに気づいたので、

puppeteerを使ってその部分のスクリーンショットを取得して

Slackに投稿してくれるBotを作ってみました


つくったもの

Github: https://github.com/tamanugi/slack_bot_stock_chart

スクリーンショット 2017-10-18 12.39.04.png
スクリーンショット 2017-10-18 12.39.16.png

キャプチャのようにbotにメンションつけてメッセージ送ると

{メッセージ} 株価 でGoogle検索を実行して

出てきた株価の部分のスクリーンショットをslackにアップロードしてくれます。

また Google の株価チャートは期間指定ができるのですが、そちらも選択できるようにしています


つかったもの


  • botkit

  • puppeteer


中身とか


bot.js

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にアップロードする


lib/stock_capture.js

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作る際に役立ちますね~~

もっと色々と作ってみようと思います

よーしこれで仕事中に株価ウォッチできるぞー