Qiitaの人気記事をSlackに通知するBotを作った話

プログラミング

いつも鉄道の記事ばかり書いているので、今回はエンジニアに関しての記事を書こうと思います!

エンジニアたるもの、日々の情報収集は最新の技術についていくという意味でも大切ですよね。

私も様々な媒体から日々情報収集をしていますが、

Qiitaの人気記事を毎日通知してくれるBotがあるといいなと感じました。

しかし良さそうなツールがなかったので自分で作りました!

今回はそのコードを全て公開したいと思います!

スポンサーリンク

ツールの概要と使用技術

以下の定義をしてツールを作成しました。

  • 最近3日間で作成された記事の中で、いいね数が多かった記事を抽出したい
  • いいねをもらった順でソートして3位までをSlackに通知したい
  • 毎日Slackに通知したい

ツールはGAS(Google Apps Script)を使用しました。

GASを使用するとプログラムをGoogle Spreadsheetの裏側に仕込むことができ、無料でサーバーとしてプログラムを動かすことができます。

無料って魅力的ですよね☺️

全てのコード

以下が全てのコードになります。のちに詳細を解説していきます。

/** スプレッドシート */
var ss = SpreadsheetApp.openById(getPropertyFromPropertyService('spreadsheetId'));
/** 投稿一覧シート */
var postSS = ss.getSheetByName('投稿一覧');
var START_ROW = 2;
var START_COLUMN = 1;
var NUMBER_OF_COLUMN = 4;

function executeQiitaPostman() {
  var posts = getPosts();
  
  if(posts === "error") {
    return;  
  }
  
  pasteToSS(posts);
  sortByLike();
  postSlack(createSlackMessage());
}

/**
* qiita記事を取得する
* @return APIリクエストのデータ
*/
function getPosts() {
  var REQUEST_URL = 'https://qiita.com/api/v2/items?page=1&per_page=100&query=stocks%3A%3E6+created%3A%3E';
  // 3日前を指定する
  var term = Moment.moment().add(-3,'d').format('YYYY-MM-DD');
  
  try {
    var response = UrlFetchApp.fetch(REQUEST_URL + term);
    return JSON.parse(response.getContentText());
  } catch(e) {
    postSlack("エラーが発生しました。確認してください。" + e.message);
    return "error"
  }
}

/**
* スプレッドシートに記事を貼り付ける
* @param [] posts 貼り付ける投稿
*/
function pasteToSS(posts) {
  //書き込むにシート情報を消す
  postSS.getRange("A2:D" + ss.getLastRow()).clear();
  
  var insertPosts = [];
  for(var i = 1; i < posts.length; i++) {
    insertPosts.push([posts[i]["id"], posts[i]["title"], posts[i]["url"], posts[i]["likes_count"]]);
  }
  postSS.getRange(START_ROW, START_COLUMN, insertPosts.length, NUMBER_OF_COLUMN).setValues(insertPosts);
}

/**
* いいね数で降順でソートする
*/
function sortByLike() {
  /** いいね数カラム */
  var COLUMN_NUMBER_OF_GOOD = 4;
  
  postSS.sort(COLUMN_NUMBER_OF_GOOD, false);
}

/**
* slackに送信するメッセージを作成する
* @return [String] message slackに送信するメッセージ
*/
function createSlackMessage() {
  var postData = postSS.getRange(START_ROW, START_COLUMN, 3, NUMBER_OF_COLUMN).getValues();
  var message = "最近3日間で最もいいねが集まった記事";
  
  for(var i = 0; i < postData.length; i++) {
    message = message + "\n\n\n◯タイトル: " + postData[i][1] + "\nURL: " + postData[i][2] + "\nいいね数: " + postData[i][3] + "";
  }
  return message;
}

/**
* slackにpostする
* @param [String] message メッセージ
*/
function postSlack(message) {
  var slackapp = SlackApp.create(getPropertyFromPropertyService('slackToken'));
  slackapp.postMessage(<チャンネルID>, message, {"icon_emoji": ":qiita_icon:"});
}

/**
* keyとして与えられた値をスクリプトプロパティから取り出して返す
* @param [String] key キー
* @return [String] キーにひもづく値
*/
function getPropertyFromPropertyService(key) {
  var prop = PropertiesService.getScriptProperties();
  return prop.getProperty(key);
}

上記のコードを実行するとSlackにこの画像の様な投稿が届きます。

 Qiita記事を取得する

以下の箇所はAPIリクエストを投げてqiita記事を取得しています。

日付の操作はMoment.jsを使用しています。

Moment.jsはリソース > ライブラリから以下のスクリプトIDを追加することで使用することができます。

スクリプトID: MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48

バージョンは最新にして保存しました。

スプレッドシートに取得した記事を貼り付ける

以下でAPIから取得したレスポンスをGoogle Spreadsheetに貼り付けています。

まず書き込むシートに前回の投稿が張り付いているのでそれを削除します。

実際に貼り付けるのは.setValuesの部分です。

/**
* スプレッドシートに記事を貼り付ける
* @param [] posts 貼り付ける投稿
*/
function pasteToSS(posts) {
  //書き込むにシート情報を消す
  postSS.getRange("A2:D" + ss.getLastRow()).clear();
  
  var insertPosts = [];
  for(var i = 1; i < posts.length; i++) {
    insertPosts.push([posts[i]["id"], posts[i]["title"], posts[i]["url"], posts[i]["likes_count"]]);
  }
  postSS.getRange(START_ROW, START_COLUMN, insertPosts.length, NUMBER_OF_COLUMN).setValues(insertPosts);
}

いいね数で降順でソートする

以下の関数ではいいねの多い順に取得した記事を並べ替えています。

/**
* いいね数で降順でソートする
*/
function sortByLike() {
  /** いいね数カラム */
  var COLUMN_NUMBER_OF_GOOD = 4;
  
  postSS.sort(COLUMN_NUMBER_OF_GOOD, false);
}

Slack通知

以下はSlack通知の該当箇所です。ソートした投稿の上から3つをSlackに投稿しています。

Slackへの投稿は、SlackAppというライブラリを使用しています。

/**
* slackに送信するメッセージを作成する
* @return [String] message slackに送信するメッセージ
*/
function createSlackMessage() {
  var postData = postSS.getRange(START_ROW, START_COLUMN, 3, NUMBER_OF_COLUMN).getValues();
  var message = "最近3日間で最もいいねが集まった記事";
  
  for(var i = 0; i < postData.length; i++) {
    message = message + "\n\n\n◯タイトル: " + postData[i][1] + "\nURL: " + postData[i][2] + "\nいいね数: " + postData[i][3] + "";
  }
  return message;
}

/**
* slackにpostする
* @param [String] message メッセージ
*/
function postSlack(message) {
  var slackapp = SlackApp.create(getPropertyFromPropertyService('slackToken'));
  slackapp.postMessage(<チャンネルID>, message, {"icon_emoji": ":qiita_icon:"});
}

終わりに

いかがだったでしょうか?意外に簡単にSlack通知Botができたと思います。

ぜひ皆さんも日々の情報収集やプログラミングの練習のためにSlack通知Botを作ってみてはいかがでしょうか?

APIリクエストの部分を変更すれば他のランキングを簡単に作成できると思います!

コメント

タイトルとURLをコピーしました