Backlog API で課題を登録する

Backlog APIを使用して課題を登録できます。 認証方法は、 API Key方式とOAuth 2.0方式を提供しており、用途によって使い分けることができます。それぞれの認証方法でのサンプルを紹介します。課題の登録以外にもブラウザーからBacklogでできる操作の大部分をAPIから行うことができます。詳しくは Backlog API 紹介ページ を参照してください。

apiKey, projectId, summary, issueTypeId, priorityId はお客様の環境にあわせた値を設定してください。

目次

  1. API Keyでの認証
    1. Ruby
    2. Python
    3. Go
    4. Google Apps Script
    5. PHP
    6. Java (Apache HttpClient)
    7. C#
  2. OAuth 2.0での認証
    1. Go

API Keyでの認証

Ruby

#! /usr/bin/env ruby

require 'net/http'

# setup a http client
http = Net::HTTP.new('xxxxx.backlog.com', 443)
http.use_ssl = true

# post a message
path = '/api/v2/issues?apiKey= XXXXX'
params = {
           'projectId' => <projectId>,
           'summary' => 'Sample task3',
           'issueTypeId' => <issueTypeId>,
           'priorityId' => <priorityId>
}
headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
}
res = http.post(path, URI.encode_www_form(params), headers)
puts res.code
puts res.body

Python

import requests

url = 'https://xxxxx.backlog.com/api/v2/issues?apiKey=XXXXX'
data = {
        'projectId': <projectId>,
        'summary': 'Sample task',
        'issueTypeId': <issueTypeId>,
        'priorityId': <priorityId>
 }   
headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post(url, data = data, headers = headers)
print(r.status_code)
print(r.json())

Go

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

var (
	host        = "xxxxx.backlog.com"
	apiKey      = "XXXXX"
	projectId   = <projectId>
	summary     = "Sample task"
	issueTypeId = <issueTypeId>
	priorityId  = <priorityId>
)

func main() {
	values := url.Values{
		"projectId":   {strconv.Itoa(projectId)},
		"summary":     {summary},
		"issueTypeId": {strconv.Itoa(issueTypeId)},
		"priorityId":  {strconv.Itoa(priorityId)},
	}
	client := http.DefaultClient
	req, _ := http.NewRequest("POST", fmt.Sprintf("https://%s/api/v2/issues?apiKey=%s", host, apiKey), strings.NewReader(values.Encode()))
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	resp, _ := client.Do(req)
	defer resp.Body.Close()
	println(resp.StatusCode)
	body, _ := ioutil.ReadAll(resp.Body)
	println(string(body))
}

Google Apps Script

var url = "https://xxxxx.backlog.com/api/v2/issues?apiKey=XXXXX";
var data = {
	 "projectId": "<projectId>",
	 "summary": "Sample task",
	 "issueTypeId": "<issueTypeId>",
	 "priorityId": "<priorityId>"
	};
var options = {
	"method": "post",
	"contentType": "application/x-www-form-urlencoded",
	"payload": data
	};
var response = UrlFetchApp.fetch(url, options);

PHP

$host = 'xxxxx.backlog.com';
$apiKey = 'XXXXX';

$params = array(
 'projectId' => <projectId>,
 'summary' => 'Sample task',
 'issueTypeId' => <issueTypeId>,
 'priorityId' => <priorityId>
);

$headers = array('Content-Type:application/x-www-form-urlencoded');
$context = array(
 'http' => array(
 'method' => 'POST',
 'header' => $headers,
 'ignore_errors' => true
 )
);

$url = 'https://'.$host.'/api/v2/issues?apiKey='.$apiKey.'&'. http_build_query($params, '', '&');
$response = file_get_contents($url, false, stream_context_create($context)); 

Java (Apache HttpClient)

HttpClient client = HttpClientBuilder.create().build();

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("projectId", <projectId>));
params.add(new BasicNameValuePair("summary", "Sample task"));
params.add(new BasicNameValuePair("issueTypeId", <issueTypeId>));
params.add(new BasicNameValuePair("priorityId", <priorityId>));

HttpPost post = new HttpPost("https://xxxxx.backlog.com/api/v2/issues?apiKey=XXXXX");
post.setEntity(new UrlEncodedFormEntity(params));
post.addHeader("Content-type", "application/x-www-form-urlencoded");
HttpResponse response = client.execute(post);

C#

var content = new FormUrlEncodedContent(new Dictionary<string, string>() {
 { "projectId", <projectId> },
 { "summary", "Sample task" },
 { "issueTypeId", <issueTypeId> },
 { "priorityId", <priorityId> }
});

var client = new HttpClient();
client.DefaultRequestHeaders.Add("ContentType", "application/x-www-form-urlencoded");
var response = client.PostAsync("https://xxxxx.backlog.com/api/v2/issues?apiKey=XXXXX", content);

OAuth 2.0での認証

Go

package main

import (
	"log"
	"net/http"
	"os"
	"fmt"
	"net/url"
	"strings"
	"io/ioutil"
	"encoding/json"
	"html/template"
)

var (
	response_type = "code"
        // Register and get from https://backlog.com/developer/applications/
	client_id = "xxx"
        // Register and get from https://backlog.com/developer/applications/
	client_secret = "xxx"
        // Need to random state and store session
	state = "aaa"
	backlog_uri = "https://xxx.backlog.jp/OAuth2AccessRequest.action?response_type=%s&client_id=%s&redirect_uri=%s&state=%s"
	oauth_uri = "https://xxx.backlog.jp/api/v2/oauth2/token"
	redirect_uri = "https://<your app domain>/oauth"
	grant_type = "authorization_code"
        addIssueUri = "https://xxx.backlog.jp/api/v2/issues"
	input *template.Template
)

type OauthResponse struct {
	TokenType string `json:"token_type"`
	AccessToken string `json:"access_token"`
	ExpiredIn int `json:"expired_in"`
	RefreshToken string `json:"refresh_token"`
}

func init() {
	input = template.Must(template.ParseFiles("input.html"))
}

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		log.Fatal("$PORT must be set")
	}
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "redirect", http.StatusFound)
	})
	http.HandleFunc("/input", func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "input.html")
	})
	http.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, fmt.Sprintf(backlog_uri, response_type, client_id, redirect_uri, state), http.StatusFound)
	})
	http.HandleFunc("/oauth", func(w http.ResponseWriter, r *http.Request) {
		code := r.URL.Query().Get("code")
		if code == "" {
			log.Fatalln("code is empty")
		}

		values := url.Values{
			"grant_type":   {grant_type},
			"code":     {code},
			"redirect_uri": {redirect_uri},
			"client_id":  {client_id},
			"client_secret": {client_secret},
		}
		client := http.DefaultClient
		req, _ := http.NewRequest("POST", oauth_uri, strings.NewReader(values.Encode()))
		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
		resp, _ := client.Do(req)
		defer resp.Body.Close()
		body, _ := ioutil.ReadAll(resp.Body)

		data := new(OauthResponse)

		if err := json.Unmarshal(body, data); err != nil {
			fmt.Println("JSON Unmarshal error:", err)
			return
		}

		err := input.ExecuteTemplate(w, "input.html", data.AccessToken)

		if err != nil {
			log.Fatalln(err)
		}
	})
	http.HandleFunc("/done", func(w http.ResponseWriter, r *http.Request) {
		r.ParseForm()
		token := r.Form["token"]
		projectId := r.Form["projectId"]
		issueTypeId := r.Form["issueTypeId"]
		priorityId := r.Form["priorityId"]
		summary := r.Form["summary"]
		description := r.Form["description"]

		values := url.Values{
			"projectId": projectId,
			"summary": summary,
			"description": description,
			"issueTypeId": issueTypeId,
			"priorityId":  priorityId,
		}
		client := http.DefaultClient
		req, _ := http.NewRequest("POST", fmt.Sprintf(addIssueUri), strings.NewReader(values.Encode()))
		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
		req.Header.Add("Authorization", "Bearer " + strings.Join(token,"" ))
		resp, _ := client.Do(req)
		defer resp.Body.Close()
		println(resp.StatusCode)
		body, _ := ioutil.ReadAll(resp.Body)

		fmt.Fprintf(w, string(body))
	})
	log.Fatal(http.ListenAndServe(":"+port, nil))
}