DX攻略部がリニューアルしました!

Backlogの期限切れチケットの情報をGASを使用してChatworkに通知する方法を解説!

こんにちは、DX攻略部です。

今回は、「GASを使用してBacklogの期限切れチケットの情報をChatworkに通知する方法」について解説します。

駆け出しのエンジニアや、より効率的にタスク管理をしたい方におすすめの記事です。非エンジニアの方でも使えるように解説していきますので、一つ一つ見ていきましょう。

BacklogをChatworkと連携する方法の概要

今回はGASを使用して、Backlogの期限切れチケットをChatworkに通知する方法について解説をしていきます。

プロジェクト管理を効率化するためには、期限切れのタスクを見逃さないことが重要です。特に多くのタスクを管理している場合、手動での確認は手間がかかり、漏れが発生しやすくなります。

そこで、GASを使用して、Backlogの期限切れチケットを自動で検出し、Chatworkに通知する仕組みを構築することが有効です。

GASとは?

GASとは、Google Apps Scriptの略称で、Googleが提供するクラウドベースのスクリプト言語です。

JavaScriptベースで書かれており、Google SpreadsheetやGoogle Documentなどの各種Googleサービスと統合されています。

GASには以下のような特徴があります。

  • クラウドベース:インターネットに接続された任意の場所からアクセス可能
  • JavaScriptベース:既存のJavaScriptの知識を活用可能
  • Googleサービスとの統合:Google Sheets, Google Docs, Gmailなどとシームレスに連携

    GASは特定の操作を自動化したり、定期的に実行したりするのに非常に便利です。

    例えば、毎朝決まった時刻にスプレッドシートのデータを更新し、その結果をメールで送信する、といったことが簡単に実現できます。

    この記事ではGASを使用して、Backlogを操作したり、Chatworkにメッセージを送信します。

      Backlogとは?

      Backlogとは、Nulabが提供するプロジェクト管理ツールです。タスク管理や進捗管理を効率的に行うことができ、チームメンバー間でのコミュニケーションを円滑にします。

      Backlogは、以下のような機能を提供しています。

      • 課題管理:タスクやバグなどを「課題」として管理
      • ガントチャート:プロジェクトの進行状況を視覚的に把握
      • Wiki:プロジェクトに関するドキュメントを作成・共有
      • Git/SVNリポジトリ:バージョン管理システムと連携

        Backlogは、エンジニアだけでなく、デザイナーやマネージャーなど、様々な職種の人々に利用されています。そのため、異なる部門間のコラボレーションを円滑にし、プロジェクトの成功に貢献します。

        BacklogはAPIを公開しているので、BacklogのAPIを使用して期限切れタスクを通知する仕組みを作成します。

        Backlogの期限切れチケットをChatworkで受け取る実装手順

        ここからは具体的なスクリプトの書き方について解説します。

        STEP1:GASでプロジェクトを立ち上げる

        まずは以下のURLにアクセスしてください。

        https://www.google.com/script/start/

        「Start Scripting」ボタンをクリックし、新しいプロジェクトを作成します。

        GASのプロジェクトの始め方を示す画像
        次に、新しいプロジェクトをクリックしてください。

        GASの新しいプロジェクトの始め方
        プロジェクトを立ち上げると、スプレッドシートが開かれます。

        GASで実際にコードを入力する画面の画像
        GASのプロジェクトを開始すると、上記のようにコードが入力できる画面になります。右側の部分にコードを書いていきます。

        STEP2:GASでBacklogの期限切れチケットを取得する

        まずはBacklogでAPIを使用できるように、API KEYを取得します。画面右上のプロフィールアイコンを選択し、メニューリストから「個人設定」をクリックします。左のメニュー欄から「API」をクリックし、APIの登録をして発行したAPI KEYをコピーしておいてください。

        それから、backlogのネームスペースも保存をしておいてください。

        Backlogにログイン後、開いているURLが https://〇〇.backlog.com/projects のようになっているかと思います。その〇〇というところに当てはまるのがネームスペースになります。

        先ほどコピーしたAPI KEYとネームスペースを以下のようにGASに入れておきます。

        /* BACKLOG API KEY */
        const BACKLOG_API_KEY = "************************************";
        
        /* BACKLOG NAMESPACE */
        const BACKLOG_NAMESAPCE = "********"; //お使いのBacklogのネームスペースを入れてください
        const BACKLOG_URL = "https://" + BACKLOG_NAMESAPCE + ".backlog.com/";
        "************************************";

        次に、GASを使用してBacklogの期限切れチケットを取得します。BacklogのAPIを使用して、課題の一覧を取得します。

        function fetchBacklogIssues() {
          let baseUrl = BACKLOG_URL + `api/v2/issues?apiKey=${BACKLOG_API_KEY}`;
          let projectIds = ["472117"]; //対象のプロジェクトIDを入れて下さい
          let statusIds = [1, 2, 3];
          let sysdate = new Date();
          sysdate.setDate(sysdate.getDate() - 1);
          let endpoint = [
          baseUrl,
          dueDateUntil=${formatDate(sysdate)},
          sort=assignee,
        ];
        
          for (let i = 0; i < projectIds.length; i++) {
            endpoint.push(projectId[]=${projectIds[i]});
          }
        
          for (let j = 0; j < statusIds.length; j++) {
            endpoint.push(statusId[]=${statusIds[j]});
          }
        
          console.log(endpoint.join("&"));
        
          return UrlFetchApp.fetch(endpoint.join("&"));
        }
        
        function formatDate(date) {
          let format = "YYYY-MM-DD";
          format = format.replace(/YYYY/g, date.getFullYear());
          format = format.replace(/MM/g, ("0" + (date.getMonth() + 1)).slice(-2));
          format = format.replace(/DD/g, ("0" + date.getDate()).slice(-2));
          return format;
        }

        この関数は、Backlogの課題を取得するための基本的なコードです。以下に各部分の詳細を説明します。

        • baseUrl:これはBacklog APIの基本URLです。このURLに必要なパラメータを追加していきます。
        • projectIds:取得対象のプロジェクトIDを指定します。この例では「472117」となっていますが、実際のプロジェクトIDに置き換えてください。プロジェクトIDは、プロジェクト設定ページに移動した時のURLの末尾の数字になっています。 https://xxxxx.backlog.com/EditProject.action?project.id=〇〇
        • statusIds:取得対象の課題ステータスを指定します。この例では「1, 2, 3」が指定されています。こちらbacklogのタスクのidとなっていて、1が「未対応」・2が「処理中」・3が「処理済み」・4が「完了」となっています。今回は完了のタスクは使用しないため、4が入っていません。
        • sysdate:現在の日付を取得し、その日付を1日前に設定します。これにより、前日までの期限切れチケットを取得することができます。
        • endpoint:これはAPIリクエストのURLを構築するための配列です。baseUrlに加えて、dueDateUntilやsortなどのパラメータを追加します。dueDateUntilというパラメータがあり、
        • for:forループでは、projectIdsとstatusIdsの各要素をendpointに追加しています。最後に、endpoint.join(“&”)でURLを組み立て、UrlFetchApp.fetchを使用してAPIリクエストを送信します。

        上記までのコードでBacklogから期限切れの課題一覧の取得が完了しました。

        STEP3:GASでChatworkに通知する

        次に、取得したBacklogの期限切れチケット情報をChatworkに通知するコードを記述します。

        まず、ChatworkのAPIを使用するためにAPI TOKENを取得します。以下のURLにアクセスをしてください。

        https://www.chatwork.com/service/packages/chatwork/subpackages/api/token.php

        ChatworkのAPIの利用には申請が必要となっているので、まだの方は利用申請を上記ページから取得してください。それをGASで変数として定義をしてください。

        また、どこのChatworkのチャットに送信をするのかを決めて、そこのルームIDも取得してください。

        ルームIDの取得方法としては、グループチャット右上から歯車マークを選択して、「グループチャットの設定」という項目を選択してください。

        ChatworkのルームIDの取得画面

        もしくは、ブラウザ版のChatworkを開くとチャットごとにURLが「 https://www.chatwork.com/#!rid0000000 」のようになっています。この0000000に該当する数字の部分がROOM_IDになります。

        そのROOM_IDとAPIのTOKENを以下のようにGASに定義してください。

        const CHATWORK_API_TOKEN = "************************************"; // ここにChatworkのAPIトークンを入力する
        const CHATWORK_ROOM_ID = "*******"; // ここに投稿したい部屋のIDを入力してください

        次に、取得したチケット情報をChatworkに送信する関数を作成します。

        function postChatwork(issues) {
          if (issues.length <= 0) {
            return;
          }
          console.log(issues.length);
          let body =
            "[toall]\nBacklogのタスクが期限切れになっています!速やかにタスクを処理するか、期限日を調整してください。\n[info][title]" +
            CHATWORK_POST_SUBJECT +
            "[/title]" +
            createPostMessage(issues) +
            "[/info]";
          let payload = {
            body: body,
          };
          let headers = {
            "X-ChatWorkToken": CHATWORK_TOKEN,
          };
          let options = {
            method: "POST",
            payload: payload,
            headers: headers,
          };
          let url =
             "https://api.chatwork.com/v2/rooms/" + CHATWORK_ROOM_ID + "/messages";
          UrlFetchApp.fetch(url, options);
        }

        この関数は、指定したメッセージをChatworkに送信します。以下に各部分の詳細を説明します。

        • body:こちらで実際に送信するメッセージを作成しています。
        • url:Chatwork APIのメッセージ送信エンドポイントURLです。
        • payload:送信するメッセージの本文を指定します。
        • options:methodはHTTPメソッドを指定し、この場合はpostを使用します。headersにはAPI TOKENを設定し、payloadには送信するメッセージを設定します。
        • 最後に、UrlFetchApp.fetchを使用してAPIリクエストを送信します。

        ここまででBacklogの期限切れチケットを取得し、Chatworkに送信するプログラムが完成しました。プログラムを実行すれば、Chatworkにメッセージを送信することができます。

        これまでのコードをまとめると以下のようになります。以下のAPI_KEYの部分などを書き換えていただいたら、そのまま使用できるコードになっています。

        /* Your code... */
        // 共通変数
        const BACKLOG_NAMESAPCE = "********"; //お使いのBacklogのネームスペースを入れてください
        const BACKLOG_URL = "https://" + BACKLOG_NAMESAPCE + ".backlog.com/";
        const BACKLOG_API_KEY =
          "************************************";
        const CHATWORK_TOKEN = "***************"; // ここにトークンを入力してください
        const CHATWORK_ROOM_ID = "*******"; // ここに投稿したい部屋のIDを入力してください
        const CHATWORK_POST_SUBJECT = "Backlog期限切れタスク"; //この辺はご自由に
        
        function main() {
          let response = fetchBacklogIssues();
          // console.log(JSON.parse(response));
          postChatwork(JSON.parse(response));
        }
        
        function fetchBacklogIssues() {
          let baseUrl = BACKLOG_URL + `api/v2/issues?apiKey=${BACKLOG_API_KEY}`;
          // 取得対象のプロジェクトIDのリストを指定
          let projectIds = ["472117"]; //対象のプロジェクトIDを入れて下さい
          let statusIds = [1, 2, 3];
          let sysdate = new Date();
          sysdate.setDate(sysdate.getDate() - 1);
        
          let endpoint = [
            baseUrl,
            `dueDateUntil=${formatDate(sysdate)}`,
            `sort=assignee`,
          ];
          // sort=assignee&dueDate&order=true';//期限日順
        
          for (let i = 0; i < projectIds.length; i++) {
            endpoint.push(`projectId[]=${projectIds[i]}`);
          }
        
          for (let j = 0; j < statusIds.length; j++) {
            endpoint.push(`statusId[]=${statusIds[j]}`);
          }
          console.log(endpoint.join("&"));
        
          return UrlFetchApp.fetch(endpoint.join("&"));
        }
        
        function postChatwork(issues) {
          if (issues.length <= 0) {
            return;
          }
          console.log(issues.length);
          let body =
            "[toall]\nBacklogのタスクが期限切れになっています!速やかにタスクを処理するか、期限日を調整してください。\n[info][title]" +
            CHATWORK_POST_SUBJECT +
            "[/title]" +
            createPostMessage(issues) +
            "[/info]";
          let payload = {
            body: body,
          };
          let headers = {
            "X-ChatWorkToken": CHATWORK_TOKEN,
          };
          let options = {
            method: "POST",
            payload: payload,
            headers: headers,
          };
          let url =
            "https://api.chatwork.com/v2/rooms/" + CHATWORK_ROOM_ID + "/messages";
          UrlFetchApp.fetch(url, options);
        }
        
        function createPostMessage(issues) {
          let message = "";
          for (let i = 0; i < issues.length; i++) {
            let issue = issues[i];
            message += `${formatDate(new Date(issue.dueDate))}|${
              issue.assignee.name
            }|${issue.status.name}`;
            message += `\n${issue.summary}(${BACKLOG_URL}view/${issue.issueKey})\n[hr]\n`;
          }
          return message;
        }
        
        function formatDate(date) {
          let format = "YYYY-MM-DD";
          format = format.replace(/YYYY/g, date.getFullYear());
          format = format.replace(/MM/g, ("0" + (date.getMonth() + 1)).slice(-2));
          format = format.replace(/DD/g, ("0" + date.getDate()).slice(-2));
          return format;
        }
        
        

        STEP4:Backlogの期限切れチケットをChatworkに通知するためにトリガーを設定する

        最後に、コードが自動で動くようにトリガーを設置します。トリガーというのは、どのタイミングでこのコードを動かすのかを決めるということです。

        例えば、時間主導型であれば1時間ごとや1日ごとなど定期的に動かしたり、スプレッドシートからなら紐づけたシートが編集されたタイミングでコードが動きます。

        今回のトリガーは時間手動型を使用します。

        GAS左メニューの中から「トリガー」を選択してください。

        GASでトリガーを設定する画面

        トリガーを選択した後には、右下にトリガーの追加というのが出てきますので、そちらをクリックしてください。

        関数を「main」に設定し、イベントの種類を「時間主導型」に設定します。時間の間隔を選択に関しては、今回は1日ごとにしています。自分の通知したい頻度に合わせて、こちらを変更してください。

        GASでトリガーの詳細を設定する画面

        これで、期限切れチケットが自動でChatworkに通知されるようになります。

        GASを使用したBacklogとChatworkの便利な連携方法

        GASは他にも多くの便利な使い方があり、BacklogとChatworkを組み合わせることで、さらに多くの機能を実現できます。以下にいくつかの例を紹介します。

        例1:タスクの進捗状況を定期的に報告

        GASを使用して、Backlogのタスク進捗状況を定期的にChatworkに報告するスクリプトを作成できます。例えば、毎週月曜日の朝に進捗状況をまとめたメッセージを自動送信することができます。

        function reportProgress() {
          let projectId = "472117"; //対象のプロジェクトID
          let url = BACKLOG_URL + `api/v2/issues?projectId=${projectId}&apiKey=${BACKLOG_API_KEY}`;
          let response = UrlFetchApp.fetch(url);
          let issues = JSON.parse(response.getContentText());
        let report = "【タスク進捗状況報告】\n";
        issues.forEach(issue => {
        report += 課題: ${issue.summary}\nステータス: ${issue.status.name}\n期限日: ${issue.dueDate}\n\n;
        });
        
        postChatwork(report);
        }

        このスクリプトは、Backlogの特定プロジェクトのタスクを取得し、各課題の概要、ステータス、期限日を含むレポートを作成してChatworkに送信します。

        例2: 新しいタスクの追加をリアルタイムで通知

        新しいタスクがBacklogに追加されたときに、Chatworkにリアルタイムで通知するスクリプトを作成できます。

        function notifyNewTask() {
          let projectId = "472117"; //対象のプロジェクトID
          let url = BACKLOG_URL + `api/v2/issues?projectId=${projectId}&apiKey=${BACKLOG_API_KEY}`;
          let response = UrlFetchApp.fetch(url);
          let issues = JSON.parse(response.getContentText());
        let latestIssue = issues[0]; // 最新の課題を取得
        let message = 【新規タスク通知】\n課題: ${latestIssue.summary}\n詳細: ${latestIssue.description}\n期限日: ${latestIssue.dueDate};
        
        postChatwork(message);
        }

        このスクリプトは、Backlogの最新の課題を取得し、その情報をChatworkに通知します。トリガーを設定して新しい課題が追加された際に実行されるようにすると効果的です。

        例3: 期限切れのタスクをSpreadsheetに追加

        期限が過ぎたタスクを自動的にGoogle Spreadsheetに追加するスクリプトを作成できます。これにより、チーム全体で期限切れのタスクを共有し、対応を促すことができます。

        function addOverdueTasksToSheet() {
          let projectId = "472117"; //対象のプロジェクトID
          let url = BACKLOG_URL + `api/v2/issues?projectId=${projectId}&apiKey=${BACKLOG_API_KEY}`;
          let response = UrlFetchApp.fetch(url);
          let issues = JSON.parse(response.getContentText());
        let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("期限切れタスク");
        
        issues.forEach(issue => {
        let dueDate = new Date(issue.dueDate);
        let today = new Date();
        
        if (dueDate < today && issue.status.name !== "完了") {
          sheet.appendRow([issue.summary, issue.assignee.name, issue.dueDate, issue.status.name]);
        }
        });
        }

        このスクリプトは、期限が過ぎたが未完了の課題を検出し、その情報をGoogle Spreadsheetに追加します。これにより、チーム全体で期限切れのタスクを確認し、対応を促進できます。

        例4: タスク完了時の自動通知

        タスクが完了した際に、チーム全体に通知するスクリプトを作成できます。これにより、プロジェクトの進行状況をリアルタイムで共有できます。

        function notifyTaskCompletion() {
          let projectId = "472117"; //対象のプロジェクトID
          let url = BACKLOG_URL + `api/v2/issues?projectId=${projectId}&apiKey=${BACKLOG_API_KEY}`;
          let response = UrlFetchApp.fetch(url);
          let issues = JSON.parse(response.getContentText());
        issues.forEach(issue => {
        if (issue.status.name === "完了") {
        let message = 【タスク完了通知】\n課題: ${issue.summary}\n完了日: ${issue.updated};
        postChatwork(message);
        }
        });
        }

        このスクリプトは、Backlogの課題をチェックし、ステータスが「完了」となっているものを検出してChatworkに通知します。

        まとめ

        今回の記事では、GASを使用してBacklogの期限切れチケットをChatworkに通知する方法について解説しました。以下の手順で実装できます。

        1. GASプロジェクトの作成
        2. Backlog APIキーの取得と設定
        3. 期限切れチケットの取得コードの記述
        4. Chatworkへの通知コードの記述
        5. 自動実行トリガーの設定

          これにより、期限切れチケットを見逃すことなく、効率的にタスク管理ができます。また、GASを使用してBacklogとChatworkを組み合わせた他の便利なシナリオも紹介しました。これらの方法を活用して、日常の業務を自動化し、効率を大幅に向上させることができます。