How we handle user complaints with JIRA (REST API)



Nowadays, few web services or applications do without functionality, where users can complain (notify, report) about various types of content, be it a grammatical error in the text, erroneous wording, uninteresting or uninformative content (like an exercise, lesson, article , training material or part of the functionality) . Being able to β€œreport a problem” is integral to engaging users in a product, implementing a form of feedback gathering, and being able to improve your application as a whole.



All user complaints must be stored somewhere, prioritized, easily tracked, and, moreover, must be processed on time. But it is not always possible to allocate enough resources for the development and maintenance of such a system, because there will always be a task in the backlog with a higher priority. Below I will tell you how we efficiently and quickly solved this problem in Uxcel using the JIRA REST API.



Why do we need β€œReport a problem”?



β€” ?

Uxcel β€” - UI/UX . β€œβ€ β€” 2 , , β€” . . (hint β€” ) (description) , .





β€” , - , - , , . β€œ ” , , . , , , , .





, backlog-, , JIRA + REST API.



JIRA



1 BUG JIRA Practices Reports. -. , Label ( : Course, Gym, UEye). :





, - ( ) .



.



JIRA REST API



API token JIRA, JIRA API. , , .



API :







  • -> Create




. - , .



API JIRA. , ( ) β€” HTTP basic authentication.



( TypeScript NodeJS):



private generateAuthHeader(): string {
    //   email:apiToken  Base64
    const basicAuthValue = Buffer.from(`${this.jiraEmail}:${this.jiraApiToken}`).toString('base64'); 
    return `Basic ${basicAuthValue}`;
}


: AWS Secrets Manager. . .


API



. , Issue ID JIRA. β€” GET :



GET https://{id}.atlassian.net/rest/api/3/issuetype 


, Postman:





Authorization Type: Basic Auth, email api token.



:



{
    "self": "https://{id}.atlassian.net/rest/api/3/issuetype/10004",
    "id": "10001",
    "description": "A problem or error.",
    "iconUrl": "https://${id}.atlassian.net/secure/viewavatar?size=medium&avatarId=10303&avatarType=issuetype",
    "name": "Bug",
    "untranslatedName": "Bug",
    "subtask": false,
    "avatarId": 10303
}


Issue Id BUG (β€œ10001”) Project Id, . id .



GET



GET https://{id}.atlassian.net/rest/api/3/project/search


: , (Jira Epic). id , Key ( , , UX-1).



API.



npm Got HTTP NodeJS.


await got.post({
    url: `${this.jiraApiHost}/issue`, // jiraApiHost = https://{id}.atlassian.net/rest/api/3
    headers: {
        Authorization: authorization, //  Basic Auth Header   generateAuthHeader
        'Content-Type': 'application/json'
    },
    responseType: 'json',
    json: {
        update: {},
        fields: {
            issuetype: { id: this.jiraBugTypeId }, //  id  BUG ( - β€˜10001’)
            project: { id: this.jiraPracticeReportProjectId }, // id  ( - β€˜10005’)
            parent: { key: this.jiraPracticeReportEpicKey }, //  Epic ( - UX-1)
            summary: practiceTicketName, //    -  [practiceId] practiceName (#reports)
            labels: [practice.label]
        }
    }
});


API Reference



. JIRA, : , , , .



API



API . , , .



:



//  JQL ,    BUG       id  (     )
const jql = `issuetype = Bug AND project = CNT AND parent = ${this.jiraEpicKey} AND text ~ "${practiceId}" order by created DESC`; 
const response = await got.get({
    url: `${this.jiraApiHost}/search?jql=${jql}`,
    headers: {
        Authorization: authorization
    },
    responseType: 'json'
});
const practiceJiraTicket = response.body['issues'] && response.body['issues'][0];


API Reference



, , CLOSED.



API



, Transitions. Status ID TODO / OPENED ( JIRA).



Postman:



GET https://{id}.atlassian.net/rest/api/3/project/{projectIdOrKey}/statuses


id , , id.



:



await got.post({
    url: `${this.jiraApiHost}/issue/${practiceJiraTicket.key}/transitions`, //  practiceJiraTicket -   
    headers: {
        Authorization: authorization,
        'Content-Type': 'application/json'
    },
    responseType: 'json',
    json: {
        transition: {
            id: this.jiraToDoStatusId // id    ( - β€˜10006’)
        }
    }
});


API Reference



β€” ( , ).



API



, id . . , n β€” .



API :



await got.put({
    url: `${this.jiraApiHost}/issue/${practiceJiraTicket.key}`,
    headers: {
        Authorization: authorization,
        'Content-Type': 'application/json'
    },
    responseType: 'json',
    json: {
        update: {
            summary: [{ set: newPracticeTicketName }]
        }
    }
});


API Reference



.



API



-.



:



await got.post({
    url: `${this.jiraApiHost}/issue/${practiceJiraTicket.key}/comment`,
    headers: {
        Authorization: authorization,
        'Content-Type': 'application/json'
    },
    responseType: 'json',
    json: comment //     
});


API Reference



comment Atlassian Document Format.

Builder, : β€” JSON .



! , , , JIRA.



:





JIRA ( id, #N β€” , % β€” ):





. , :





! , :)

!




All Articles