🙌

bundleからメンバー情報を引っ張り出す

2022/12/11に公開

https://qiita.com/advent-calendar/2022/lancers

昨日は@Isanaさんの「開発生産性は企業にとって競争力そのものであるという話」でした。

はじめに

はじめまして!
ランサーズでコーポレートITを担当している長峰です。色々なツールをつくるのが好きでコーポレートエンジニアになり、今日で誕生日を迎えました!

https://www.wantedly.com/companies/lancers/post_articles/426866

今回はbundleというSaaSからデータを引っ張り出し、slackに通知するツールをつくりたいと思います。

bundleとは

  • 情シス向けの作業自動化ツール
  • 各SaaSアカウントの作成、削除を効率化できる

というサービスです。

https://bundle.jp/

API機能もあり、非常に重宝させていただいています。

やりたいこと

bundleはGraphQLをAPIに採用されています。
https://graphql.org/

ツールの流れとして

  1. bundleからメンバー情報をAPIですべて出す
  2. メンバー情報の中から部署がないものをフィルター
  3. slackに通知

をつくっていきます。

code

大元の処理です。こういったファイルをつくっておくと、エラー調査などがやりやすいですね。

main.js
function main(){
 // bundleからメンバー情報を取ってくる
  const memberList = getMemberList();
  
  const alertList = memberList.reduce((alertList, member) => {
    if(member.isNoDivision()) alertList.push(member.getName());

    return alertList;
  }, []);

  if(alertList.length === 0) return;

  const slackMessage = `部署がないメンバー\n${alertList.join('\n')}`;

  const SLACK_WEBHOOK = 'XXXXXX';
  slackChannel(SLACK_WEBHOOK, slackMessage);

}

bundleとの接続部分(API)の処理です。

https://qiita.com/massa-potato/items/2209ff367d65c5dd6181

bundle.js
const TOKEN = 'XXXXXX';
const URL_API = 'https://XXXXX.bundle.jp/api/v1';

function getMemberList(){

  let memberList = [];
  let cursor = '';

  do{
    // SQLなどのソースコードへの記載は毎回迷う。もっと綺麗な書き方がある気がする。
    const query = `
{
  team {
    members(first:100, after:"${cursor}") {
      pageInfo {
        endCursor
        hasNextPage
      }
      nodes {
        databaseId
        fullName
        url
        memberDepartments{
          department{
            fullName
          }
        }
      }
    }
  }
}
    `;
  
    const options = {
      'method': 'POST',
      'payload': JSON.stringify({query: query}),
      'headers': {
        'content-type': 'application/json',
        'Accept': 'application/json',
        'Authorization': `Bearer ${TOKEN}`,
      },
    };
    
    // ここでbundleと通信を行っている。
    const res = UrlFetchApp.fetch(URL_API, options);
    const json = JSON.parse(res).data.team;

    memberList = memberList.concat(json.members.nodes.map(json => new Member(json)));
    cursor = json.members.pageInfo.endCursor;
    Utilities.sleep(1 * 1000);
  
  // 次のメンバー情報があるまで続ける。
  }while(json.members.pageInfo.hasNextPage);
  
  return memberList;
}

メンバークラスです。メンバーに関する処理はここに入れてます。

class/Member.js
class Member{
  constructor(response){

    this.id = response.databaseId;
    this.name = response.fullName;
    this.url = response.url;
    this.departments = response.memberDepartments[0]?.department?.fullName;
  }

  isNoDepartments(){
    return !this.division;
  }

  getName(){
    return this.name;
  }
}

slack送信処理です。slackワークフローから生成したwebhookに向けてメッセージを送信するのが最近のおすすめで、ボタン追加やチャンネル変更がslack上で可能となります。

slack.js
function slackChannel(webhook, message) {
  const jsonData = {
    'text' : message
  };

  const options = {
    'method' : 'post',
    'contentType' : 'application/json',
    'payload' : JSON.stringify(jsonData)
  };

  const res = UrlFetchApp.fetch(webhook, options);
  Logger.log(res);
}

後は1日1回トリガーに、mainを実行すればslackに通知されます。
https://blog.synnex.co.jp/google/gas-trigger/

最後に

bundleはSaaSのアカウントを管理するSaaSですし、slackはコミュニケーションするためのSaaSです。それぞれはそれぞれに機能を特化していきますが、専門性を深めるSaaSを組み合わせた時に、なにかとんでもなくクールな使い方ができるんじゃないかなと時々思います。
この一年は、それを見つける一年にしたいですね!

明日は@narinarinariさんの『「アドラー心理学」を用いたチームマネジメント』という記事です。お楽しみに!
https://qiita.com/narinarinari/items/c298d3a68f7db61a281d

Discussion