Associate and push actions via Jira REST API

This page provides information for configuring and running an API call that associates a Jira issue to a Salesforce object and pushes the data to Salesforce.

Use case

Scenario

A customer has migrated their Salesforce instances, recreated their data on a new instance, and now requires an automated solution to associate and push the newly created Salesforce objects.

Solution

Use the script below to automate the association and push mechanism of Salesforce objects in the new instance.

Instructions

  1. Copy the script and install dependencies via npm install atlassian-jwt moment.

  2. Edit the script to use your information. For example:

    • For const token, replace FILL_ME_IN with the API Access Token located on the configuration page of the Salesforce Jira Connector app.

    • For const projectId, replace FILL_ME_IN with the project ID for the issues you want to associate with.

  3. At line 92 hardcode the Jira issue key, SF Object API Name, and the SF Object ID.

    1. To do this in bulk, edit the script as needed.

  4. Run the script.

    1. You can use Visual Studio Code to run the script.

  5. Verify that the association was created and pushed. Ensure the object you are linking to has a different summary so that a simple association only creates a link, while the push actually replaces the summary.

Example script

const jwt = require('atlassian-jwt'); const moment = require('moment'); const token = "FILL_ME_IN"; const APP_BASE_URL = "https://sfjc.integration.appfire.app/" const projectId = "FILL_ME_IN"; if (token === "FILL_ME_IN") { console.error('Please fill in the token found in the configuration page of the Salesforce Jira Connector app.'); process.exit(1); } if (projectId === "FILL_ME_IN") { console.error('Please fill in the project id for the issues you want to associate with.'); process.exit(1); } function getTokenDataForToken(token) { const buf = Buffer.from(token, 'base64'); const s= buf.toString('utf-8'); return JSON.parse(s); } console.log('Extracting token data...') const r = getTokenDataForToken(token); const now = moment().utc(); function createClaims(connectionData) { return { iss : 'sfjc/host/' + connectionData.acKey + '/connection/' + connectionData.connectionId, aud : 'sfjc/host/' + connectionData.acKey + '/connection/' + connectionData.connectionId, "iat": now.unix(), // The time the token is generated "exp": now.add(3, 'minutes').unix(), // Token expiry time (recommend 3 minutes after issuing) } } const shortLivedJwtToken = jwt.encodeSymmetric(createClaims(r), r['sharedSecret']); console.log('Created short lived token.') async function associateSingleCase(issueIdString, salesforceObjectName, salesforceObjectId) { const payload = { "jiraIssueId": issueIdString, "son": salesforceObjectName, "soid": salesforceObjectId, "viewOnly": false, "autoPush": false, "autoPull": false } const url = `${APP_BASE_URL}/external/api/association`; console.log('Associating single object...'); const r = await fetch(url,{ method: 'POST', body: JSON.stringify(payload), headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'JWT ' + shortLivedJwtToken, } }) if ((r.status !== 200) && (r.status !== 201)) { console.error(r.status); let data = await r.text(); console.error(data); throw new Error(data); } else { const result = await r.json() console.log('associateSingleIssue complete: ', result); return result; } } async function pushSingleIssue(projectIdString, issueIdString, salesforceObjectName, salesforceObjectId) { const payload = { "jiraIssueId": issueIdString, "son": salesforceObjectName, "soid": salesforceObjectId, "viewOnly": false, "autoPush": false, "autoPull": false } const url = `${APP_BASE_URL}/external/api/push/project/${projectIdString}/issue/${issueIdString}/to/${salesforceObjectName}/${salesforceObjectId}`; console.log('Pushing issue to object...'); const r = await fetch(url,{ method: 'POST', body: JSON.stringify(payload), headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'JWT ' + shortLivedJwtToken, } }) const result = await r.json(); console.log('pushSingleIssue complete: ', result); return result; } function associateThenPush(projectIdString, issueIdString, salesforceObjectName, salesforceObjectId) { return associateSingleCase(issueIdString, salesforceObjectName, salesforceObjectId) .then(() => pushSingleIssue(projectIdString, issueIdString, salesforceObjectName, salesforceObjectId)); } async function main() { await associateThenPush(projectId, "11816", "Case", "500J80000019IF9IAM") console.log('Done!'); } main();

Â