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.
The old API (<BASE-URL>/rest/api/2/issue/<KEY>/properties/com.servicerocket.jira.cloud.issue.salesforce.associations
), which used Jira entity properties for storing associations, is no longer supported due to storage limitations. You can use the API below instead to achieve the same functionality.
On this page: |
---|
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
Copy the script and install dependencies via
npm install atlassian-jwt moment
.Edit the script to use your information. For example:
For
const token
, replaceFILL_ME_IN
with the API Access Token located on the configuration page of the Salesforce Jira Connector app.For
const projectId
, replaceFILL_ME_IN
with the project ID for the issues you want to associate with.
At line 92 hardcode the Jira issue key, SF Object API Name, and the SF Object ID.
To do this in bulk, edit the script as needed.
Run the script.
You can use Visual Studio Code to run the script.
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();
Â
Â