Template Content
About the template
About ScriptRunner Connect
What is ScriptRunner Connect?
Can I try it out for free?
Yes. ScriptRunner Connect comes with a forever free tier.
Can I customize the integration logic?
Absolutely. The main value proposition of ScriptRunner Connect is that you'll get full access to the code that is powering the integration, which means you can make any changes to the the integration logic yourself.
Can I change the integration to communicate with additional apps?
Yes. Since ScriptRunner Connect specializes in enabling complex integrations, you can easily change the integration logic to connect to as many additional apps as you need, no limitations.
What if I don't feel comfortable making changes to the code?
First you can try out our AI assistant which can help you understand what the code does, and also help you make changes to the code. Alternatively you can hire our professionals to make the changes you need or build new integrations from scratch.
Do I have to host it myself?
No. ScriptRunner Connect is a fully managed SaaS (Software-as-a-Service) product.
What about security?
ScriptRunner Connect is ISO 27001 and SOC 2 certified. Learn more about our security.
This template demonstrates how to create an issue in Jira Cloud when a ticket is created in Zendesk. Summary (subject in Zendesk), reporter (requester in Zendesk), assignee, priority and description (includes a reference to Zendesk ticket) field values are copied over.
Parameters
, and set the PROJECT_KEY
parameter to match the key of the project in Jira Cloud where you want the new issue to be created. Optionally, you can also change which issue type to use in Jira Cloud or how priority
and status
map from Zendesk to Jira Cloud.When you create a ticket in Zendesk, a new issue will be created in Jira Cloud containing the url of the corresponding Zendesk ticket in the description.
import JiraCloud from './api/jira/cloud';
import Zendesk from './api/zendesk';
// This function creates a new issue in Jira Cloud when a ticket is created in Zendesk
export default async function (event: ZendeskTicketCreatedEvent, context: Context): Promise<void> {
if (context.triggerType === 'MANUAL') {
console.error('This script is designed to be triggered externally or manually from the Event Listener. Please consider using event listener test event payload if you need to trigger this script manually.');
return;
}
// Get the parameters specified for this template
const { ISSUE_TYPE, PROJECT_KEY, ZENDESK_TO_JIRA_CLOUD_STATUS_MAPPING, ZENDESK_TO_JIRA_CLOUD_PRIORITY_MAPPING } = getParameters(context);
try {
// Get more data about the Zendesk ticket that triggered the event
const ticket = await Zendesk.Ticket.getTicket({ ticket_id: event.ticketId });
// If the ticket has a priority, try to find the corresponding one in Jira Cloud
const jiraPriority = ticket.ticket.priority ? ZENDESK_TO_JIRA_CLOUD_PRIORITY_MAPPING[ticket.ticket.priority] : undefined;
// Get the requester and assignee of the ticket if specified
const requester = ticket.ticket.requester_id ? await Zendesk.User.getUser({ user_id: ticket.ticket.requester_id }) : undefined;
const assignee = ticket.ticket.assignee_id ? await Zendesk.User.getUser({ user_id: ticket.ticket.assignee_id }) : undefined;
// Try to find a reporter and assignee in Jira Cloud with matching emails to those in Zendesk
const jiraReporter = requester && (await JiraCloud.User.Search.findUsers({ query: requester?.user.email }))?.[0];
const jiraAssignee = assignee && (await JiraCloud.User.Search.findUsers({ query: assignee?.user.email }))?.[0];
// Extract the Zendesk instance url from the ticket's metadata path
const zendeskUrl = ticket.ticket.url.split('/api/')[0];
// Construct a url for viewing the Zendesk ticket
const ticketUrl = `${zendeskUrl}/agent/tickets/${event.ticketId}`;
// Create an issue in Jira Cloud using parameter values and Zendesk ticket data
const issue = await JiraCloud.Issue.createIssue({
body: {
fields: {
project: {
key: PROJECT_KEY,
},
issuetype: {
name: ISSUE_TYPE,
},
summary: `Zendesk ticket: ${ticket.ticket.subject}`,
description: {
type: "doc",
version: 1,
content: [
{
type: "paragraph",
content: [
{
type: "text",
text: ticket.ticket.description
},
{
type: 'hardBreak'
},
{
type: "text",
text: "Zendesk ticket url",
marks: [
{
type: "link",
attrs: {
href: ticketUrl,
}
}
] as any
}
]
}
]
},
priority: jiraPriority && {
name: jiraPriority
},
reporter: jiraReporter && {
accountId: jiraReporter.accountId
},
assignee: jiraAssignee && {
accountId: jiraAssignee.accountId
},
}
}
});
// Try to find a corresponding status in Jira Cloud for the Zendesk ticket
const jiraStatus = ZENDESK_TO_JIRA_CLOUD_STATUS_MAPPING[ticket.ticket.status];
if (jiraStatus) {
// If a corresponding status is found, fetch all transitions in Jira Cloud
const transitions = await JiraCloud.Issue.Transition.getTransitions({ issueIdOrKey: issue.id });
// Find the required transition
const transition = transitions.transitions.find(t => t.name === jiraStatus);
// Transition the Jira Cloud issue to the status that matches the one in Zendesk, if it already doesn't
await JiraCloud.Issue.Transition.performTransition(
{
issueIdOrKey: issue.id,
body: {
transition:
{
id: transition.id
}
}
}
);
}
// If the operation was successful, log out the key for the created Jira Cloud issue
console.log(`Created a Jira Cloud issue with key: "${issue.key}".`);
} catch (error) {
// In case of an error, log it out
console.error('Error creating an issue in Jira Cloud', error)
}
}
interface ZendeskTicketCreatedEvent {
ticketId: number;
}
interface Parameters {
PROJECT_KEY: string;
ISSUE_TYPE: string;
ZENDESK_TO_JIRA_CLOUD_STATUS_MAPPING: Record<string, string>;
ZENDESK_TO_JIRA_CLOUD_PRIORITY_MAPPING: Record<string, string>;
}
export function getParameters(context: Context) {
return context.environment.vars as Parameters;
}