이라 스토 야의 이미지가있는 메시지를 Slack에 게시 (Puppeteer에서 임의로 이미지 가져 오기)

개요


  • 정각이 되면, Slack의 채널에 이라스토야의 이미지가 있는 메시지를 게시한다.
  • 트리거 워드가 Slack에 게시되면 가자미와 이미지가있는 메시지로 회신합니다.

  • 덧붙여 이미지는 랜덤으로 지정되기 때문에, 무엇이 나오는지는 기대됩니다

    ※본 기사는, 이미 Slack Bot를 운용되고 있는 전제로 쓰고 있으므로, Node 환경의 준비나 Slack의 API Token의 지불 등의 정보는 할애하고 있으므로, 양해 바랍니다

    Slack에 게시물 이미지



    1의 패턴: 매시간 00분에 스케줄 지정한 경우


    2의 패턴 : "이라 스토야"라는 단어에 반응하면


    필요한 노드 모듈은 3개


    npm install -S botkit
    npm install -S puppeteer
    npm install -S node-cron
    

    주요 스크립트



    index.js
    const botkit = require('botkit');
    const puppeteer = require('puppeteer');
    const cron = require('node-cron');
    
    if (!process.env.SLACK_TOKEN) {
      console.log('Error: Specify token in environment');
      process.exit(1);
    }
    
    const controller = botkit.slackbot({
      debug: true,
    });
    
    const bot = controller.spawn({
      token: process.env.SLACK_TOKEN,
    }).startRTM();
    
    // Bot起動時のSlack疎通確認用
    controller.hears(['ping'], 'direct_message,direct_mention,mention,ambient', function (bot, message) {
      bot.reply(message, 'PONG');
    });
    
    // --------------------------------------------------
    //  いらすとや画像をSlackに投稿する
    // --------------------------------------------------
    
    function postIrasutoya(channel){
    
      (async () => {
        const browser = await puppeteer.launch({ headless: true });
        const page = await browser.newPage();
        await page.goto('https://www.irasutoya.com/2016/04/blog-post_890.html');
        await page.click('a[href="#random"]');
        await page.waitForNavigation({ waitUntil: 'domcontentloaded' });
    
        const image = await page.$('#post .entry img');
        const src = await image.getProperty('src');
        const url = await src.jsonValue();
        const title = await page.$eval('#post h2', item => {
          return item.innerText;
        });
    
        bot.say({
          channel: channel,
          text: '休憩しようぜ!<' + url + '|' + title + '>',
          as_user: false,
          username : 'いらすとや',
          icon_emoji: ':+1:',
        }, function(err, res) {
          if (err) {
            bot.botkit.log('Failed to postMessage', err);
          }
        });
        await browser.close();
      })();
    }
    
    // トリガーワードで実行する
    controller.hears(['いらすとや'], 'direct_message,direct_mention,mention,ambient', function(bot, message) {
      postIrasutoya(message.channel);
    });
    
    // cronでスケジュール実行する(月曜〜金曜の12時と15時)
    cron.schedule('0 0 12,15 * * 1-5', () => {
      postIrasutoya('#general');  // #generalチャンネルに投稿
    });
    

    해설 1: 이라스토야의 이미지를 랜덤하게 취득




  • 이스토야의 이미지 페이지를 열고 하단의 임의 버튼을 클릭합니다.
  • 클릭 후 표시된 페이지의 이미지 URL과 제목을 가져옵니다.
  • Slack에 이미지 제목과 URL을 게시합니다.

  • 설명 2: 트리거 워드에서 실행



    controller.hears의 첫 번째 인수는 트리거 단어입니다.
    복수 지정이나 정규 표현 지정도 가능합니다.

    controller.hears의 두 번째 인수는 응답할 메시지 이벤트의 유형을 지정합니다.


    이벤트 유형
    설명


    direct_message
    사용자의 직접 메시지에 응답합니다.

    direct_mention
    채널 내에서 직접 멘션 메시지에 반응합니다.

    mention
    채널 내에서 멘션된 메시지에 반응합니다.

    ambient
    채널에 멘션이 없는 메시지에 반응합니다.


    ※@멘션이 메시지의 선두에 대해 있는 것이 다이렉트 멘션입니다. (direct_mention)


    ※그 이외의 멘션 첨부 메세지(mention)


    ※멘션이 없는 메시지(ambient)


    설명 3: cron에서 일정 실행



    cron.schedule의 인수로 스케줄을 지정합니다.
    인수의 왼쪽에서 "초, 분, 시간, 일, 월, 요일"로 지정할 수 있습니다.'0 0 12,15 * * 1-5' 의 경우, 1-5는 월요일~금요일을 의미하고, 월요일~금요일 사이의 12시 0분 0초와 15시 0분 0초를 의미하고 있습니다.

    자세한 내용은 merencia/node-cron README.md Cron Syntax를 참조하십시오.

    왜 이걸 만들었는가


  • 작업에 집중하고 있으면, 휴식도 잊고 몰두하기 쉽기 때문에, 휴식을 환기(환희)하고 싶었다.
  • 처음에는 Slack의/remind에서 휴식 메시지를 내고 있었지만, 텍스트만이라면 무기질로 사무적으로 느끼게 되어 버렸다.
  • 휴식한다, 라고 하는 공기감(완화, 편안함)을 내고 싶었으므로 화상 첨부를 시도했습니다.
  • 처음에는 lgtm. 여의 이미지를 내려고했지만, 무작위로 나오는 이미지의 대부분은 LGTM을 느끼지 못하고 당초의 목적의 휴식하는 공기감을 따르지 않는다고 판단하고 , 이라스토야의 이미지를 채용했습니다.

  • ※이 기사를 쓰고 있을 때 알았습니다만, lgtm. 여 의 사이트는 닫는 것 같네요. (2018년 9월 23일에 확인한 시점)


    참고


  • 귀여운 무료 소재 모음
  • Puppeteer 입문 스크래핑 + 웹 조작 자동 처리 프로그래밍
  • GitHub
  • GoogleChrome/puppeteer

  • howdyai/botkit

  • Botkit and Slack

  • merencia/node-cron

  • U-l-me-a-n g / s-ck ※ 본 기사의 리포지토리

  • 좋은 웹페이지 즐겨찾기