見出し画像

Google Apps Scriptでスプレッドシートからチケットを発注する話 | 第5回

はじめに

本記事は、GASとRedmine APIを用い、Googleスプレッドシートの情報からRedmineのチケットを自動で作成するスクリプトを紹介していくシリーズの最終回にあたるものです。

第1回では、スプレッドシートとスクリプト全体の処理を概観し、続く第2回で、それに必要な事前準備について説明しました。
そのうえで第3回では、GASとRedmine、ならびにスプレッドシートを紐付け、そのスプレッドシートから情報を抜き出すところまでを解説しました。
そして第4回では、スプレッドシートの情報からのチケットの生成について、その処理の大枠を先におさらいできたので、本回でその中身について、詳細を確認していきたいと思います。

スプレッドシートの情報をもとにした複数のチケットの登録(2/2)

さっそく、前回に省略した大枠の中身の箇所について再度確認したいと思います。

画像1

// チケット情報の設定
var subject = ISSUES[i][*]; // チケットのタイトルが記載された列を記入
dueDate = Utilities.formatDate(ISSUES[i][*], "JST", "yyyy-MM-dd"); // チケットの期日が記載された列を記入
var description = // シートから取得した要素をもとに説明の文章を構築
 '新規イベントのバナーを発注します。\r\n' +
 '\r\n' +
 '### イベント概要\r\n' +
 '記載テキスト:\r\n' +
 ISSUES[i][*] + '\r\n' +
 'ターゲット:\r\n' +
 ISSUES[i][*] + '\r\n' +
 'インセンティブ:\r\n' +
 ISSUES[i][*] + '\r\n' +
 'イベント期間:\r\n' +
 Utilities.formatDate(new Date(ISSUES[i][*]), "JST", "MM/dd") + ' ▶︎ ' + Utilities.formatDate(new Date(ISSUES[i][*]), "JST", "MM/dd") + '\r\n' +
 'コメント:\r\n' +
 ISSUES[i][*];

var issue = {
 'tracker_id': *, // チケットを登録するトラッカーのIDを記入
 'subject': subject,
 'description': description,
 'due_date': dueDate,
 'assigned_to_id': *, // チケットの初期担当者のIDを記入
}

// チケットの登録
var payload = {
 'issue': issue,
 'project_id': PROJECT_ID,
};

payload = JSON.stringify(payload);

var options = {
 'method': 'POST',
 'headers': HEADERS,
 'payload': payload,
 'contentType': 'application/json',
 'muteHttpExceptions': true
}

UrlFetchApp.fetch(REDMINE_URL + '/issues.json?key=' + API_KEY, options);

// 登録したチケットのURLをスプレッドシートに記載
var options = {
 'headers': HEADERS,
 'muteHttpExceptions': true
};
var jsonLatestIssue = UrlFetchApp.fetch(REDMINE_URL + '/issues.json?key=' + API_KEY + '&limit=1', options).getContentText();
var latestIssue = JSON.parse(jsonLatestIssue);
var latestIssueId = latestIssue.issues[0].id;
SHEET.getRange(START_ROW + i, *).setValue(REDMINE_URL + '/issues/' + latestIssueId); // チケットのURLが記載された列を記入  

前回にも触れたとおり、その内容は大きく3つに分かれますが、その1つ目はチケットの内容の設定です。

// チケット情報の設定
var subject = ISSUES[i][*]; // チケットのタイトルが記載された列を記入
dueDate = Utilities.formatDate(ISSUES[i][*], "JST", "yyyy-MM-dd"); // チケットの期日が記載された列を記入
var description = // シートから取得した要素をもとに説明の文章を構築
 '新規イベントのバナーを発注します。\r\n' +
 '\r\n' +
 '### イベント概要\r\n' +
 '記載テキスト:\r\n' +
 ISSUES[i][*] + '\r\n' +
 'ターゲット:\r\n' +
 ISSUES[i][*] + '\r\n' +
 'インセンティブ:\r\n' +
 ISSUES[i][*] + '\r\n' +
 'イベント期間:\r\n' +
 Utilities.formatDate(new Date(ISSUES[i][*]), "JST", "MM/dd") + ' ▶︎ ' + Utilities.formatDate(new Date(ISSUES[i][*]), "JST", "MM/dd") + '\r\n' +
 'コメント:\r\n' +
 ISSUES[i][*];

var issue = {
 'tracker_id': *, // チケットを登録するトラッカーのIDを記入
 'subject': subject,
 'description': description,
 'due_date': dueDate,
 'assigned_to_id': *, // チケットの初期担当者のIDを記入
}

ここではタイトルと期日、説明の項目を設定しています。もちろん、ステータスや予定工数といった他のパラメータも設定可能です。

まず、タイトルについては単純で、シートの内容をそのまま抽出します。例によって、第2回で挙げた例を代入すれば、次のとおりになります。

var subject = ISSUES[i][1]; // チケットのタイトルが記載された列を記入

期日については先に取り出していますが、Redmineの書式にあわせて整形し、再設定します。

`dueDate = Utilities.formatDate(ISSUES[i][3], "JST", "yyyy-MM-dd"); // チケットの期日が記載された列を記入

説明の項目については、どのような内容にすべきか、チームごとに千差万別になることと思われます。そのため、必要な書式に整形をいただかなければなりません。このとき、この変数はひとつのStringであること、Stringは「’」で囲い、「+」で接続ができること、ならびにRedmineではMarkdownが採用されており、かつ改行は「\r\n」で表されることを参考にしてください。一例として弊チームでは、シートのE列からJ列の情報をもとに、以下のような内容に整形しています。

var description = // シートから取得した要素をもとに説明の文章を構築
    '新規イベントのバナーを発注します。\r\n' +
    '\r\n' +
    '### イベント概要\r\n' +
    '記載テキスト:\r\n' +
    ISSUES[i][6] + '\r\n' +
    'ターゲット:\r\n' +
    ISSUES[i][7] + '\r\n' +
    'インセンティブ:\r\n' +
    ISSUES[i][8] + '\r\n' +
    'イベント期間:\r\n' +
    Utilities.formatDate(new Date(ISSUES[i][4]), "JST", "MM/dd") + ' ▶︎ ' + Utilities.formatDate(new Date(ISSUES[i][5]), "JST", "MM/dd") + '\r\n' +
    'コメント:\r\n' +
    ISSUES[i][9];
新規イベントのバナーを発注します。
イベント概要
記載テキスト:
Vtuberになれる!
ターゲット:
Vtuber志望
インセンティブ:
新規Vtuberの声優就任
イベント期間:
2/21 ▶︎ 2/27
コメント:
Vtuberの画像を使用

そしてこれらの情報と、トラッカーID、ならびにチケット担当者のIDをまとめて、issueというひとつの連想配列に格納すれば、チケット情報の設定は完了です。

var issue = {
    'tracker_id': 9, // チケットを登録するトラッカーのIDを記入
    'subject': subject,
    'description': description,
    'due_date': dueDate,
    'assigned_to_id': 20, // チケットの初期担当者のIDを記入
}


次に、いよいよこのチケット情報を、Redmineのチケットとして登録します。

// チケットの登録
var payload = {
    'issue': issue,
    'project_id': PROJECT_ID,
};
payload = JSON.stringify(payload);
var options = {
    'method': 'POST',
    'headers': HEADERS,
    'payload': payload,
    'contentType': 'application/json',
    'muteHttpExceptions': true
}
UrlFetchApp.fetch(REDMINE_URL + '/issues.json?key=' + API_KEY, options);

すでに必要な情報はすべて設定しているので、ここで編集する箇所はありません。なにがなされているのかだけ、簡単に確認していきます。

まず、さきのissueの情報とその登録先のプロジェクトIDとをpayloadにまとめ、それをJSON形式に変換します。

var payload = {
    'issue': issue,
    'project_id': PROJECT_ID,
};
payload = JSON.stringify(payload);

そのうえで、さらにそのpayloadとチケット登録に必要なパラメータをoptionsにまとめます。

var options = {
    'method': 'POST',
    'headers': HEADERS,
    'payload': payload,
    'contentType': 'application/json',
    'muteHttpExceptions': true
}

そして、Redmine APIのURLを生成し、このoptionsとともに読み込ませれば、チケットの登録は完了です。

UrlFetchApp.fetch(REDMINE_URL + '/issues.json?key=' + API_KEY, options);


以上で、ようやくスプレッドシートからのチケットの登録ができました。最後に、管理しやすくするために、いましがた登録したチケットのURLをシートに記載しておきます。

// 登録したチケットのURLをスプレッドシートに記載
var options = {
    'headers': HEADERS,
    'muteHttpExceptions': true
};
var jsonLatestIssue = UrlFetchApp.fetch(REDMINE_URL + '/issues.json?key=' + API_KEY + '&limit=1', options).getContentText();
var latestIssue = JSON.parse(jsonLatestIssue);
var latestIssueId = latestIssue.issues[0].id;
SHEET.getRange(START_ROW + i, *).setValue(REDMINE_URL + '/issues/' + latestIssueId); // チケットのURLが記載された列を記入  

しかしRedmineでは、チケット登録時にそのチケットのURLを知る方法がありません。助けてください。そこで稚拙ではありますが、代替案を考えます。

そのために、ここでRedmineのチケットのURLの規則を確認してみます。お手元のRedmineで適当なチケットを開いていただければ分かる通り、RedmineのチケットはチケットIDをもとに生成されています。

https://redmine.mixch.tv/issues/****

したがって、チケット登録から間髪をいれず最新のチケットの情報を取得すれば、そのID、ひいてはURLを確認することができるはずです。

それにしたがい、チケット登録時と同様に、取得に必要な情報をoptionsにまとめます。

var options = {
    'headers': HEADERS,
    'muteHttpExceptions': true
};

そしてこれも先ほどと同様に、RedmineのURLを生成してoptionsとともに読み込み、最新1件のチケット情報を取得します。ただしこのとき、中身の情報を取得する処理を追加しています。

var jsonLatestIssue = UrlFetchApp.fetch(REDMINE_URL + '/issues.json?key=' + API_KEY + '&limit=1', options).getContentText();

ここで登録の時とは逆に、取得した情報をJSON形式から配列に変換し、そこからチケットIDの情報を抜き出します。

var latestIssue = JSON.parse(jsonLatestIssue);
var latestIssueId = latestIssue.issues[0].id;

そして最後に、そのIDからチケットURLを生成し、シート上の指定の列に書き込めば、すべての処理は完了です。

SHEET.getRange(START_ROW + i, *).setValue(REDMINE_URL + '/issues/' + latestIssueId); // チケットのURLが記載された列を記入

以上で、全5回に渡るGASによるスプレッドシートのチケット化についての解説は終了です。拙いところもあったかと思いますが、少なくともこれで、スプレッドシートから100回以上コピペを繰り返す苦役からは解放されるはずです。

とはいえ、弊チームではなにもバナーばかりを制作しているわけではありません。アプリのUIは言わずもがな、イベントの優勝者に贈呈するトロフィーや、それを宣伝するビジョンの動画広告、はてはポテトチップスの包装や海の家の外装にいたるまで、日々退屈することのない案件が飛び交っているうえに、こちらから積極的にこれがやりたいと手を挙げれば、実行できる環境があります。

そんな弊社Donutsでは、現在採用に力を注いでいます。最先端のライブ配信事業を先導する「MixChannel」をはじめ、話題のSaaS事業で業界No.1を誇る「ジョブカン」シリーズや、医療業界にITのメスをいれる電子カルテの「CLIUS」、さらに「Tokyo 7th Sisters」、「Black Star」、「D4DJ」といったゲームにいたるまで、幅広い事業を展開するからこそ、多様な人材が求められています。デザイナーにかぎらず、新しいことに挑戦してみたい方、是非ご応募をお待ちしています。

採用

具体的にどのような業務を行なっているかご興味のある方は、ぜひ弊チームの他の記事をご参照ください。

最後になりますが、ここまでお読みいただき、ありがとうございました。

この記事が気に入ったら、サポートをしてみませんか?
気軽にクリエイターの支援と、記事のオススメができます!
1
株式会社Donuts(https://www.donuts.ne.jp/)でUIデザイナーとして働いています。 業務のことや、そのなかで得た知見について紹介させていただきます。

こちらでもピックアップされています

Corporate IT
Corporate IT
  • 687本
コメントを投稿するには、 ログイン または 会員登録 をする必要があります。