직장에서도 주가를 보기 위해 주가 차트를 게시하는 슬랙 봇을 만들어 보았습니다.

주가 차트를 보면 재미 있습니다! (주하지 않지만)

google에서 企業名 株価그 기업의 주가 차트를 표시하는 것을 알았으므로,
puppeteer를 사용하여 해당 부분의 스크린 샷을 얻습니다.
Slack에 게시 할 Bot을 만들어 보았습니다.

만든 것



Github : htps : // 기주 b. 코 m / 타마 누기 / s CK_BOT_S 및 CK_CHART







캡처처럼 봇에 멘션을 붙이고 메시지를 보내면{メッセージ} 株価 에서 Google 검색 실행
나온 주가 부분의 스크린 샷을 슬랙에 업로드합니다.

또한 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에서 이미지 파일을 슬랙에 업로드

    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위치와 크기를 취득해 스크린샷 찍을 때에 인수로 지정하고 있습니다.

    취득할 수 있는 위치와 크기와 실제로 원하는 부분이 어긋나 있었기 때문에 거기는 조정하고 있습니다. (패딩만큼 어긋났어?)

    puppeteer를 사용하여 요소의 스크린 샷을 얻는 방법은
    과거에 정리했기 때문에 그쪽도 참고해 주시면 감사하겠습니다.

    Puppeteer를 사용하여 지정한 DOM 전용 스크린 샷 얻기

    결론



    puppeteer도 botkit도 정말 쉽게 사용할 수 있기 때문에
    약간의 Chat Bot 만들 때 도움이 되네요 ~~
    더 여러가지 만들려고 생각합니다.

    좋아, 이제 일하는 동안 주가를 볼 수 있습니다.

    좋은 웹페이지 즐겨찾기