13
21

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 5 years have passed since last update.

RedmineAdvent Calendar 2017

Day 12

RedmineのJavaScriptから各種データを取得する方法

Last updated at Posted at 2017-12-09

RedmineのJavaScriptからRedmineの内部データを取得する方法の中で、authenticity_tokenを使う方法と、REST APIを使う方法を紹介する。

authenticity_tokenを使ったデータの取得

Redmine自身のフロントエンドが呼び出している機能を利用する。
各ページに埋め込まれているauthenticity_tokenが必要。

authenticity_tokenの取得

authenticity_tokenはRedmineの全てのページには埋め込まれているわけではない。
何かしらのデータ作成や更新の機能があるページに埋め込まれている模様。

$(':input[name="authenticity_token"]:first').val()

下記ページには埋め込まれているのを確認した。他にもあると思う。

  • グローバルメニュー
    • 「マイページ」
    • 「プロジェクト」 > 新しいプロジェクト
    • 「個人設定」
  • プロジェクトメニュー
    • 「概要」 > 新しいサブプロジェクト
    • 「ロードマップ」
    • 「リリース」 > 新しいリリース
    • 「チケット」
    • 「新しいチケット」
    • 「Wiki」
    • 「文書」
    • 「ニュース」
    • 「ファイル」 > 新しいファイル
    • 「設定」
    • 既存のチケット詳細
    • 作業時間の記録

チケットに入力可能な値の一覧の取得

Redmine自身がチケット入力フォームを部分更新する際に使用しているupdate_form.jsを利用して、チケット入力フォームのHTMLと、HTMLをパースすることでチケットに入力可能なステータスなどの値を取得する。

ここで取得したhtmlIssueFormをjQueryセレクターの第2引数に渡すことで、<input><select>に入力されているパラメータを抽出することもこのHTMLをそのまま利用して自前のチケット情報入力フォームのパーツに流用することもできる

var project_identifier = "redmine-test";
var issue_id = '7'; // if create new issue, set blank.
$.post(
    '/projects/' + project_identifier + '/issues/update_form.js' + (issue_id ? 'id=' + issue_id : ''),
    {utf8:"", authenticity_token:$(':input[name="authenticity_token"]:first').val()}
).done(function(data){
    eval(data.split("\n")[0].replace(/^replaceIssueFormWith\(/, 'var htmlIssueForm=').replace(/\);$/, ';'));
    // デバッグ表示:HTMLフォーム
    console.log(htmlIssueForm);
    // デバッグ表示:入力項目の抽出
    console.log($(":input", $(htmlIssueForm)));
});

解説すると少しトリッキーなことをしている。(Redmineのバージョンアップで死ぬ可能性がままある)

このレスポンス(data)にはチケット編集のHTMLフォームを置き換えるJavaScriptコードが含まれる。
このJavaScriptの本来の使われ方は、例えばトラッカーが変化するとトラッカーごとに入力フォームの入力項目が変わったり、ユーザーのロールによって選択可能なステータスが変わるなどのリアルタイムなHTMLフォームの変化に用いられている。

上記の処理はそのHTMLフォームの置き換えコードを正規表現で無理矢理に変数htmlIssueFormへの代入に変更してeval()実行している。
これにより置き換えに使われるはずだったHTMLがアクセス可能な変数htmlIssueFormに代入される。

REST APIを使ったデータの取得

Rest api - Redmine

JavaScriptからREST APIでよく取得したくなるデータを抜粋した。

ここでは取得方法のみを軽く書いたが、APIによっては新規作成も更新もできる。
詳細はリンクしているREST APIドキュメントを参照して欲しい。

またJavaScriptからREST APIを呼び出す記事は別途作成した。

RedmineのJavaScriptからREST APIを使用する

ログインユーザーのapikeyの取得

apikeyを取得するような関数は存在しないためログインユーザーの「個人設定」をスクレイピングして取得する。
(下記コードは、当然ながらRedmineのバージョンアップなどで動かなくなる可能性はある)

// Redmineの全バージョンに対応。
// REST APIがONになっていなければapikeyには空文字が入る。
let apikey = "";
$.get('/my/account').done(function(data){
     apikey = $("#api-access-key", $(data)).first().text();
});

// Redmine 3.1以上の低負荷版。専用ページなので読み込み負荷は若干低くなるはず。
// REST APIのON/OFFに関わらずapikeyにはAPIキーの文字列が入る。
let apikey = "";
$.get('/my/api_key').done(function(data){
    apikey = $('#content > div.box > pre', $(data)).first().text();
});

プロジェクトデータの取得

プロジェクト

Projects - Redmine

var apikey = '****************************************';

// プロジェクト一覧
$.ajax({
    type: 'get',
    url: '/projects.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

// プロジェクト詳細
var project_identifier = "redmine-test";

$.ajax({
    type: 'get',
    url: '/projects/' + project_identifier + '.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

カテゴリー

Issue Categories - Redmine

var apikey = '****************************************';
var project_identifier = "redmine-test";

$.ajax({
    type: 'get',
    url: '/projects/' + project_identifier + '/issue_categories.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

バージョン

Versions - Redmine

var apikey = '****************************************';
var project_identifier = "redmine-test";

$.ajax({
    type: 'get',
    url: '/projects/' + project_identifier + '/versions.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

Wiki

Wiki Pages - Redmine

var apikey = '****************************************';
var project_identifier = "redmine-test";

// ページ一覧
$.ajax({
    type: 'get',
    url: '/projects/' + project_identifier + '/wiki/index.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

// ページ詳細
var page_name = 'Wiki';

$.ajax({
    type: 'get',
    url: '/projects/' + project_identifier + '/wiki/' + page_name + '.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

チケットデータの取得

チケット

Issues - Redmine

var apikey = '****************************************';

// チケット
$.ajax({
    type: 'get',
    url: '/issues.json',
    headers: {'X-Redmine-API-Key': apikey},
    data: {project_id:1, limit:100, include:'relations'},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

// ページ詳細
var issue_id = '15781';

$.ajax({
    type: 'get',
    url: '/issues/' + issue_id + '.json',
    headers: {'X-Redmine-API-Key': apikey},
    data: {include:'children,attachments,relations,changesets,journals,watchers'},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

関連するチケット

Issue Relations - Redmine

var apikey = '****************************************';
var issue_id = '16894';

$.ajax({
    type: 'get',
    url: '/issues/' + issue_id + '/relations.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

システム定義データの取得

トラッカー

Trackers - Redmine

var apikey = '****************************************';

$.ajax({
    type: 'get',
    url: '/trackers.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

チケットステータス

Issue Statuses - Redmine

var apikey = '****************************************';

$.ajax({
    type: 'get',
    url: '/issue_statuses.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

列挙項目

Enumerations - Redmine

var apikey = '****************************************';

$.ajax({
    type: 'get',
    url: '/enumerations/issue_priorities.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));

カスタムフィールド

Custom Fields - Redmine
※システム管理者のapikeyが必要

var apikey = '****************************************';

$.ajax({
    type: 'get',
    url: '/custom_fields.json',
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'json',
    contentType: 'application/json',
}).done((json) => console.log(json));
13
21
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
13
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?