_RJ 技術メモ

人生を豊かにする技術を提供する、筋肉

QiitaのContribution数が増えるたびにSlackに通知する

Qiita Slack slackbot GoogleAppsScript JavaScript

概要

環境はGoogle Apps Scriptを使用。

スクリーンショット 2017-03-26 17.44.59.png

事前準備

SlackのAPIキーを取得する

https://api.slack.com/custom-integrations/legacy-tokens Appを登録するとxoxp-xxxxxxxxxxxxxxxxxxxxのようなコードが発行されるので、ソースコード内のslackTokenに設定する

Slackにチャンネルを追加する

Slackにて、qiita-contributionのチャンネルを新規で追加する

ライブラリにSlackAppを追加する

Slackを使用するためにsoundTrickerさんの以下のライブラリを導入する http://qiita.com/soundTricker/items/43267609a870fc9c7453 Library Keyをコピーして、リソース-ライブラリ-ライブラリを追加に入力する 今回はバージョン22を使用

取得したいユーザーのアカウント名を設定する

ソースコード内のuserNameにContributionを取得したいユーザーアカウント名を設定する

トリガーの設定

プロジェクトのトリガーを時間主導型で1分に設定する

ソースコード解説

今回はQiitaAPIを使わずに、簡易的な正規表現でのスクレイピングでContributeを取得 1. Qiitaのユーザーページをフェッチ 2. ユーザーページHTMLのContributeに該当する箇所のみ正規表現で抜き出し 2. Slackの以前の最後のメッセージと、今回の送信するメッセージを比較 3. 以前のメッセージと違ければ(Contributionが増えて入れば)新しいContribution数を通知する

function myFunction() {
  //各種設定
  var userName = '_RJ';
  var slackToken = 'xoxp-xxxxxxxxxxxxxxxxxxxx';
  var slackChannel = 'qiita-contribution';
  var slackUserName = 'contributin-bot';
  var additionalStartMessage = 'QiitaのContribution数が'
  var additionalEndMessage = 'に増えました!'
  
  //Contributionの取得
  var html = UrlFetchApp.fetch('http://qiita.com/' + userName).getContentText();
  var contribution = /contributions\"><span class=\"userActivityChart_statCount\">([\s\S]*?)<\/span>/i.exec(html)[1].replace(/(^\s+)|(\s+$)/g, "")
 
  //Logger.log(contribution);
  
  //以前のメッセージと比較してContributionが更新されていれば投稿する
  var message = additionalStartMessage + contribution + additionalEndMessage;
  var lastMessage = getSlackMessage(slackToken, slackChannel)[0].text;
  if(lastMessage != message){
    postSlackMessage(slackToken, slackChannel, slackUserName, message);
  }else{
    //Logger.log('Duplicated');
  }
}


function postSlackMessage(accessToken, channelName, userName, message){
  //Get channels
  var slackApp = SlackApp.create(accessToken);
  var channels = slackApp.channelsList().channels;
  
  //Find channel by channel name
  var channel = null;
  channels.forEach(function(v, i){
    if(v.name == channelName){
     channel = v; 
    }
  });

  //Post Message to slack
  slackApp.postMessage(channel.id, message, {
    username : userName
  }); 
}


function getSlackMessage(accessToken, channelName){
  //Get channels
  var slackApp = SlackApp.create(accessToken);
  var channels = slackApp.channelsList().channels;
  
  //Find channel by channel name
  var channel = null;
  channels.forEach(function(v, i){
    if(v.name == channelName){
     channel = v; 
    }
  });

  //Get Message at slack
  return slackApp.channelsHistory(channel.id).messages;
}