読者です 読者をやめる 読者になる 読者になる

定期的に GitHub API を叩いて Slack にポストしたい (3)

最終回

メッセージを Slack に投げる

function sendToSlack(message, attachments) {
  var url = "https://slack.com/api/chat.postMessage";
  var token = "token" // Slack のアクセストークン
  var channel = "#channel"; // 投稿する先のチャンネル
  var text = message; // 本文
  var username = "GitHub"; // Slack に投稿する BOT の名前
  var parse = "full"; // URL エスケープする
  var icon_emoji = ":emoji:"; // emoji 名
  
  var payload = {
    "token" : token,
    "channel" : channel,
    "text" : text,
    "username" : username,
    "parse" : parse,
    "icon_emoji" : icon_emoji,
    "attachments" : JSON.stringify(attachments)
  };
  
  var method = "post";
  var params = {
    "method" : method,
    "payload" : payload
  };
  
  var response = UrlFetchApp.fetch(url, params);
}

各 PR の情報を全部 message として組み立ててもいいのだけど attachment を使うとよりカッコよく一覧化できる。 ここ で試せる!

// 各 PR を attachment として配列で返す。
function createAttachments(pulls) {      
  var attachments = [];
  for (var i = 0; i < pulls.length; i++) {
    var pull = pulls[i];
    
    // GAS はいまのところ yyyy/mm/dd hh:mm:ss.mmm じゃないとパースできないのでミリ秒をくっつける。
    var createdAtDate = new Date(pull["createdAt"].replace("Z", ".000Z"));
    var createdAtString = 
      (createdAtDate.getMonth() + 1) + "/" + 
      createdAtDate.getDate() + " " +
      ("0" + createdAtDate.getHours()).slice(-2) + ":" +
      ("0" + createdAtDate.getMinutes()).slice(-2);
    
    var attachment = {
      "color": "#000000",
      "author_name": pull["user"],
      "author_icon": pull["avatar_url"],
      "title": pull["title"],
      "title_link": pull["url"],
      "footer": pull["commentCount"] + " comments ( +" + pull["newCommentCount"]  +" ), created at " + createdAtString,
    };
    
    attachments.push(attachment);
  }
  
  return attachments;
}

で、 PR 取得したらメッセージ付けて Slack に流す。

function notify() {
  var pulls = getPulls();
  if (pulls.length == 0) {
    return;
  }
  
  var message = pulls.length + " 個の PR が更新されました。"
  var attachments = createAttachments(pulls);
  
  sendToSlack(message, attachments);
}

cron 的な設定

解説や注意点など

  • チャンネルじゃなくて DM に送りたいときは # じゃなくて @ にするらしい。
  • Google Apps Script の Date は生 js と微妙に仕様が違うようで、コメントにも書いている以外にも色々ありそう。
  • attachment で日時を表示したいとき、自前で文字列にくっつけなくても ts に UNIX timestamp を指定すると出してくれるのだけど「Dec 29th at 7:44 PM」とかで表示されて我々にとって直感的じゃないのでやめた。
  • Slack の API はドキュメントが充実してるのでとっつきやすいですね。