LANG SELRCT

コードを書く場所についてはこちら

2019年3月1日金曜日

JIRAのAPIでemailからaccountIdを取得したい


JIRA APIのusernameが廃止になるため、代わりにaccountIdを使う方法を調べました。


知りたかったのはEmailからaccountIdを取得するこれ


https://SITENAME.atlassian.net/rest/api/3/user/assignable/search?project=PROJECT_KEY&query=EMAIL


※SITENAME、PROJECT_KEY、EMAILを指定すると結果が配列で返ってきます。


これは以下の公式ガイドのFind userのUpdated requestにありました。
https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/#updated-request-1
Updated request
You will need to update your code to use a method that supports the query request parameter, where the value can be an email address, display name, or any other user attribute.
GET https://your-domain.atlassian.net/rest/api/3/user/assignable/search?project=ABC&query=your-user-attribute
Email以外にdisplay nameなどでも取得できるようです。

指定したEmailの結果が「配列で返ってくる」という点が一癖ある感じでした。

実際にやってみた手順を以下に書き残しておきます。


試してみる


foo@gmail.com を渡して結果を取得してみる

JIRAにログインしている状態で、ブラウザのアドレスバーに以下を入力します。
https://SITENAME.atlassian.net/rest/api/3/user/assignable/search?project=PROJECT_KEY&query=foo@gmail.com

  • SITENAMEは利用している名前
  • PROJECT_KEYは対象のプロジェクト
  • foo@gmail.comは自分のEmail

該当のユーザが1人の場合は以下のように返ってきます。
IDが今回取得したいaccountIdです。
[{
    "self": "https://SITENAME.atlassian.net/rest/api/3/user?accountId=ID",
    "key": "admin",
    "accountId": "ID",
    "name": "admin",
    "emailAddress": "foo@gmail.com",
    "avatarUrls": {
        "16x16": "URL",
        "24x24": "URL",
        "32x32": "URL",
        "48x48": "URL"
    },
    "displayName": "NAME",
    "active": true,
    "timeZone": "Asia/Tokyo",
    "locale": "en_US"
}]


もし foo@gmail.comとは別に、bar.foo@gmail.com のようなユーザがいる場合は、「foo@gmail.com」という文字列が一致して以下のように2つのアカウント情報が返ってきます。
(渡したEmailに完全一致するものだけが返ってくると思ったらそうではない)
[{
    "self": "https://SITENAME.atlassian.net/rest/api/3/user?accountId=ID",
    "key": "admin",
    "accountId": "ID",
    "name": "admin",
    "emailAddress": "foo@gmail.com",
    "avatarUrls": {
      "16x16": "URL",
      "24x24": "URL",
      "32x32": "URL",
      "48x48": "URL"
    },
    "displayName": "NAME",
    "active": true,
    "timeZone": "Asia/Tokyo",
    "locale": "en_US"
  },
  {
    "self": "https://SITENAME.atlassian.net/rest/api/3/user?accountId=ID",
    "key": "admin",
    "accountId": "ID",
    "name": "admin",
    "emailAddress": "bar.foo@gmail.com",
    "avatarUrls": {
      "16x16": "URL",
      "24x24": "URL",
      "32x32": "URL",
      "48x48": "URL"
    },
    "displayName": "NAME",
    "active": true,
    "timeZone": "Asia/Tokyo",
    "locale": "en_US"
  }
]

上記の結果からaccountIdを取得しますが、配列で返ってくるため、emailAddressが一致するアカウントを特定してaccountIdを取得します。


以下2つのパターンのコードを書きました。
  • emailからaccountIdを取得するコード
  • accountIdをreporterに入れて課題を作成するコード


emailからaccountIdを取得するコード


コード.gs
function getToken() {
  var id = "EMAIL";
  var pw = "PASSWORD";
  var token = Utilities.base64Encode(id + ":" + pw);
  return token;
}

function getAccountId() {
  var project = 'KEY';//プロジェクトを指定する
  var email = Session.getActiveUser().getEmail();
  var url = 'https://SITENAME.atlassian.net/rest/api/3/user/assignable/search?project=' + project + '&query=' + email;
    var options = {
    method: "get",
    contentType: "application/json",
    headers: {"Authorization": " Basic " + getToken()}
  }
  var response = UrlFetchApp.fetch(url, options);
  var jobj = JSON.parse(response);
  var accountInfo = getAccountInfo(jobj, email);
  var accountId = accountInfo['accountId'];
  Logger.log(accountId);
}

function getAccountInfo(jobj, email) {
  var accountInfo;
  for(var i = 0; i < jobj.length; i++) {
    var emailAddress = jobj[i]['emailAddress'];
    if(emailAddress === email) {
      accountInfo = jobj[i];
    }
  }
  return accountInfo;
} 

意訳
この機能がやること
ログインEmail
ログインパスワード
base64でエンコードして
返す


この機能がやること
プロジェクトを指定する
アクティブユーザのEmailを取得する
APIにアクセスしてパラメータを渡す
optionsを作る
methodを設定
contentTypeを設定
headersを設定
  }
APIにアクセスして結果を取得する
結果をオブジェクトに変換する
getAccountInfo()にjobjとemailを渡して結果を得る
その中からaccountIdを取得して
ログに出す


この機能がやること
accountInfoの入れ物を作る
渡されたjobjの要素の数だけ繰り返す
ひとつずつemailAddressを取得して
渡されたemailと一致したら
accountInfoにそのアカウント情報を入れる


accountInfoを返す




ログに出したresponseの中身を見てみる
[
    [{
        "self": "https://SITENAME.atlassian.net/rest/api/3/user?accountId=ここにIDが書かれている",
        "key": "admin",
        "accountId": "ここにもIDが書かれている",
        "name": "admin",
        "emailAddress": "自分のEMAIL",
        "avatarUrls": {
            "16x16": "URL",
            "24x24": "URL",
            "32x32": "URL",
            "48x48": "URL"
        },
        "displayName": "YOUR NAME",
        "active": true,
        "timeZone": "Asia/Tokyo",
        "locale": "en_US"
    }], ここにaccountIdを抜き出す
]


accountIdをreporterに入れて課題を作成するコード


コード2.gs
var BASE_URL = 'https://SITENAME.atlassian.net';
var ISSUE_URL = BASE_URL + '/rest/api/3/issue/';

function getToken() {
  var id = "EMAIL";
  var pw = "PASSWORD";
  var token = Utilities.base64Encode(id + ":" + pw);
  return token;
}

function doPost() {
  var token = getToken();
  var payload = getPayload();
  var options = getOptions(token, payload);
  var response = UrlFetchApp.fetch(ISSUE_URL, options);
  Logger.log(response);
  var key = getKey(response);
  Logger.log(key);
}

function getPayload(values) {
  var email = Session.getActiveUser().getEmail();
  var data = {
    project: {key: "KEY"},
    issuetype: {name: "Bug"},
    summary: "たいとる",
    description: ["タスクの説明です\n説明の2行め"],
    reporter: {id: getAccountId()}
  };
  var fields = {fields: data};
  var payload = JSON.stringify(fields);
  return payload;
}

function getOptions(token, payload) {
  var options = {
    method: "post",
    payload: payload,
    contentType: "application/json",
    headers: {"Authorization": " Basic " + token}
  }
  return options;
}

function getKey(response){
  var jobj = JSON.parse(response);
  var key = jobj["key"];
  return key;
}

function getAccountId() {
  var project = 'KEY';//プロジェクトを指定する
  var email = Session.getActiveUser().getEmail();
  var url = BASE_URL + '/rest/api/3/user/assignable/search?project=' + project + '&query=' + email;
    var options = {
    method: "get",
    contentType: "application/json",
    headers: {"Authorization": " Basic " + getToken()}
  }
  var response = UrlFetchApp.fetch(url, options);
  var jobj = JSON.parse(response);
  var accountInfo = getAccountInfo(jobj, email);
  var accountId = accountInfo['accountId'];
  Logger.log(accountId);
  return accountId;
}

function getAccountInfo(jobj, email) {
  var accountInfo;
  for(var i = 0; i < jobj.length; i++) {
    var emailAddress = jobj[i]['emailAddress'];
    if(emailAddress === email) {
      accountInfo = jobj[i];
    }
  }
  return accountInfo;
} 


補足:

APIを利用して課題を作成する際に、reporterの値がusernameだと今回の廃止の影響を受けるため、コード2.gsのようにaccountIdへ変更します。

今回やったこと
  1. emailからaccountIdを取得する方法を見つける
  2. reporterにaccountIdを入れて課題を作成する