6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GitLabのメンションをGoogleAppsScriptを使ってSlackに通知したい

Last updated at Posted at 2020-05-21

はじめに

Qiita初投稿になります。
日々の仕事の中で作ったものなどを備忘録として、またシェアできたらいいなと思っています。

きっかけ

私の会社ではGitのホスティングサービスにGitLabを使っており、またコミュニケーションツールとしてSlackを使っています。

仕事内容のやり取りはissueで管理していますが、issueのコメントで自分宛てにメンションが来た場合、メール通知はされるものの即時で見ることができず、少し不便を感じていました。

そこでお手軽にGASを使って通知できるような仕組みを作れないかググっていたところ、GitHubで同じことをしている方がいました。

[GAS] GoogleAppsScriptでGitHubの通知をSlackのDMに投稿するようにした話

こちらを参考にさせていただきGitLab版のものを作ってみることにしました。

GASの作り方やSlackのWebhookの設定

参考にさせていただいた方がすごく丁寧に解説してくださっていますので、割愛します。
[GAS] GoogleAppsScriptでGitHubの通知をSlackのDMに投稿するようにした話

GASのスクリプト

先で紹介している方のスクリプトを全面的に参考にさせていただいています。
ほとんどそのまま使用させていただきましたが、動かなかった部分やGitLab独自のPOSTデータの部分などは修正しました。
また投稿するメッセージ部も少しカスタマイズしてます。

GitlabのWebhookの内容は公式ドキュメントを参考にしました。
Webhooks | GitLab Comment on issue

参考記事で詳しく解説されていますが、基本的な流れは以下のとおりです。

  1. GitLabからjsonデータを受け取る
  2. リストにいるユーザ宛のメンションが含まれていればSlackユーザネームに変換
  3. メッセージ内容を組み立ててSlackに送信
var _ = Underscore.load();
var SLACK_WEBHOOK_URL = 'https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxx';

var USER_NAME_LIST = [
  {gitlab: '@hoge', slack: '@hoge_1'},
  {gitlab: '@fuga', slack: '@fuga_1', slackId: '@UHXXXXXX'},
];

function doPost(e) {
  var data = JSON.parse(e.postData.getDataAsString());
  notifySlack(data);
}

function notifySlack(data) {

  // コメントがない場合は通知しない
  if (!data.object_attributes.note) {
    return;
  }
  
  // ユーザネームがマッチしない場合は通知しない
  var names = data.object_attributes.note.match(/@[a-zA-Z0-9_.\-]+/g);
  if (!names) {
    return;
  }
  
  for (var i in names) {
    message = '#' + data.issue.iid + ' ' + data.issue.title + "\n";
    message += data.object_attributes.url + "\n" + data.object_attributes.note;
    callSlackWebhook(convertUserName(names[i]), message);
  }
}

function convertUserName(gitlabName) {
  var user = _.find(USER_NAME_LIST, function(user) {return user.gitlab === gitlabName});

  if (user) {
    var slackName = user.slackId || user.slack
    return slackName;
  }

  return gitlabName;
}

function callSlackWebhook(user, comment) {  
  var params = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify({
      channel: user,
      text: comment,
      link_names: 1,
    })
  };
  var response = UrlFetchApp.fetch(SLACK_WEBHOOK_URL, params);
  console.log("response:", response);
  return response;
}

GitLabの設定

GASを公開したらGitLabのWebhookを有効にします。
プロジェクトの設定 > Webhooksから今回使うWebhookを作ります。

  • URL -> GASのアプリケーションURLを入力
  • Trigger -> 今回はCommentのみチェック

Add Webhookボタンで保存します。
image.png

完成

ここまでできたらGitLabのissueにメンションをつけてコメントしてみます。
SlackBotから通知が来たら成功です!
複数人にメンションされている場合も当てはまる全員に通知されます。
コメント 2020-05-21 191855.png

さいごに

通知内容はもう少し工夫できると思うので今後も気が向いたときにカスタマイズしてみたいです。

普段GitLabを使っていて、GitHubの記事は結構あるけどGitLabの記事はあんまりないな…と思っていましたが、GitHubにできることはGitLabでも大抵のことはできるので、ちょっと工夫すれば色々できると思います。

Webhookもかなり情報が取れるので、他にも業務に役立ちそうなものを思いついたら作ってみたいです。

追記(2020/5/25)

マージリクエストのコメントも拾えたら便利かなと思いましたのでnotifyslack()のメッセージ部分をマージリクエストにも対応させてみました。
他にもコミット、コードスニペットでのコメントも拾えるようですが、ウチではissueとマージリクエストのコメントが拾えれば良いのでこのかたちにしました。

for (var i in names) {
  var message = '';
  if (data.object_attributes.noteable_type == 'Issue') {
    message += '【issue】#' + data.issue.iid + ' ' + data.issue.title + "\n";
  } else if (data.object_attributes.noteable_type == 'MergeRequest') {
    message += '【MergeRequest】!' + data.merge_request.iid + ' ' + data.merge_request.title + "\n";
  }
  message += data.object_attributes.url + "\n" + data.object_attributes.note;
  callSlackWebhook(convertUserName(names[i]), message);
}
6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?