JIRA api上传附件

Posted on 2021-03-21 16:18:02
Author: 可乐小可爱メ
1. 背景

需要一个支持系统, 面向非JIRA 直接用户, 调用JIRA 方便用户操作。

(此篇以  Issue attachments, add attachement 为例)

2. 设计实现



3. 代码

    3.1 后端部分

        3.1.1  API TOKEN

const { JIRA_TOKEN, JIRA_ACCOUNT } = require("../.secret");
const headers = {
Authorization: `Basic ${Buffer.from(JIRA_ACCOUNT + ":" + JIRA_TOKEN).toString(
"base64"
)}`,
Accept: "application/json",
"Content-Type": "application/json",
};


生成链接 : https://id.atlassian.com/manage-profile/security/api-tokens


        3.1.2 调 JIRA api

// ... 上下文
router.post(`/issue/attachment/:key`, (req, res) => {
const { key } = req.params;
const contentType = req.headers["content-type"];
const form = new Formidable.IncomingForm();
form.parse(req, async (err, fields, files) => {
if (err) {
return res.end({ code: 10001, err });
}
const rs = fs.createReadStream(files.file.path);
let value = [];
rs.on("data", (chunk) => {
value.push(chunk);
});
rs.on("error", (err) => {
res.json({ code: 10001, err });
});
rs.on("end", () => {
request(
{
url: `${JIRA_HOST}/rest/api/3/issue/${key}/attachments`,
method: "POST",
headers: {
Authorization,
Accept: "application/json",
"content-type": contentType,
"X-Atlassian-Token": "no-check",
},
formData: {
file: {
value: Buffer.from(value),
options: {
filename: files.file.name,
contentType: null,
},
},
},
},
(error, response, body) => {
if (error) {
log("jira api err: /issue/comment");
return res.json({ code: 10001, msg: "jira api err" });
}
res.status(response.statusCode);
res.send(body);
}
);
});
});
});

    3.2 前端部分

function uploadFile(e: any) {
const file = new window.File([e.file], e.file.name, { type: e.file.type });
const SIRATOKEN = window.localStorage.getItem("SIRA-TOKEN");
const formData = new FormData();
formData.append("file", file);
axios({
headers: {
Accept: "application/json",
"Content-Type": "multipart/form-data",
SIRATOKEN,
},
url: `/sira/jira/issue/attachment/${selectIssue}`,
method: "POST",
data: formData,
})
.then((res) => {
console.log("res: ", res);
})
.catch((e) => {
console.log("e: ", e);
});
}


4. 注意点

    4.1 这里 node服务,steam流 尝试转成pipe 避免大文件内存不够问题(暂时还没写出来), 需要加上 size 判断拦截.

    4.2 查看文件时,JIRA 文件地址做了 鉴权 302重定向,


并不能简单通过, 

res.set("Authorization", Authorization);
res.redirect(fileUrl);

这样处理来获取,因为真实资源路径是 JIRA 自己再次302而来。

这里的处理是 先 request 获取资源, 其中有当前资源的真实Uri,

router.get(`/file`, (req, res) => {
const {
query: { fileUrl },
} = req;
request(
{
method: "GET",
url: encodeURI(fileUrl),
headers: {
Authorization,
},
},
(error, response, body) => {
if (error) throw new Error(error);
if (response.statusCode === 200) {
res.redirect(response.request.uri.href);
} else {
res.status(response.statusCode);
res.json(response.body);
}
}
);
});


5. 资源链接

https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/


当前评论 (0) 登录后评论

暂无评论