Opens a Jira ticket for each message your people report, and adds later reports of the same sender to the ticket already open.

UsesGmailJira

Turn reported suspicious mail into Jira tickets

GmailGmailWhen an email arrives.When an email arrives.
ValuesSet reportSearch to blank.Set reportSearch to blank.
ValuesSet jiraProjectKey to blank.Set jiraProjectKey to blank.
ValuesSet ourDomains to blank.Set ourDomains to blank.
ValuesSet impersonatedNames to blank.Set impersonatedNames to blank.
ValuesSet triagedLabel to Reported mail triaged.Set triagedLabel to Reported mail triaged.
ValuesSet issueType to Task.Set issueType to Task.
ValuesSet maxReportsPerRun to 10.Set maxReportsPerRun to 10.
TextJoin a list of [reportSearch, -label:, @triagedLabel, ] with nothing and save it as reportQuery.Join a list of [reportSearch, -label:, @triagedLabel, ] with nothing and save it as reportQuery.
MathSet reportLimit to maxReportsPerRun multiplied by 1.Set reportLimit to maxReportsPerRun multiplied by 1.
TextJoin a list of [,, ourDomains with "Join a list of [,, ourDomains with replaced by , with replaced by in lowercase, ,] with nothing and save it as ourDomainList.
TextSplit impersonatedNames with "Split impersonatedNames with replaced by , by , and save it as nameList.
GmailGmailList emails matching reportQuery. Save it as reported.List emails matching reportQuery. Save it as reported.
ValuesSet handledCount to 0.Set handledCount to 0.
ValuesSet ticketCount to 0.Set ticketCount to 0.
ValuesSet commentCount to 0.Set commentCount to 0.
Decisions & LoopsFor each message in reported.emails:For each message in reported.emails:
Decisions & LoopsIf handledCount is greater than or equal to reportLimitIf handledCount is greater than or equal to reportLimit
Yes
Decisions & LoopsStop repeating.Stop repeating.
No
No steps
Decisions & LoopsIf a step below fails, save the error as reportErrorIf a step below fails, save the error as reportError
Try
TextTrim message.id and save it as messageId.Trim message.id and save it as messageId.
Decisions & LoopsIf messageId is emptyIf messageId is empty
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
TextTrim message.from and save it as fromHeader.Trim message.from and save it as fromHeader.
Decisions & LoopsIf fromHeader is emptyIf fromHeader is empty
Yes
ValuesShow in the output: A reported message arrived with no sender address; skipped..Show in the output: A reported message arrived with no sender address; skipped..
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ValuesSet addressPart to fromHeader.Set addressPart to fromHeader.
ValuesSet displayName to blank.Set displayName to blank.
Decisions & LoopsIf fromHeader contains <If fromHeader contains <
Yes
ListsGet the first item of the last item of fromHeader split by < split by > and save it as addressPart.Get the first item of the last item of fromHeader split by < split by > and save it as addressPart.
TextTrim the first item of fromHeader split by < with replaced by " and save it as displayName.Trim the first item of fromHeader split by < with replaced by " and save it as displayName.
No
No steps
TextMake addressPart with replaced by with \ replaced by with replaced by " lowercase and save it as senderKey.Make addressPart with replaced by with \ replaced by with replaced by " lowercase and save it as senderKey.
Decisions & LoopsIf senderKey doesn't contain @If senderKey doesn't contain @
Yes
ValuesShow in the output: a list of [The From line of message , messageId, holds no address, so there is nothing to group it by; skipped.] joined by nothing.Show in the output: a list of [The From line of message , messageId, holds no address, so there is nothing to group it by; skipped.] joined by nothing.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsIf senderKey contains :// or senderKey contains /If senderKey contains :// or senderKey contains /
Yes
ValuesShow in the output: a list of [The From line of message , messageId, is not shaped like an address; skipped.] joined by nothing.Show in the output: a list of [The From line of message , messageId, is not shaped like an address; skipped.] joined by nothing.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsIf the length of senderKey is greater than 120If the length of senderKey is greater than 120
Yes
ValuesShow in the output: a list of [The sender address on message , messageId, is too long to use as a ticket title; skipped.] joined by nothing.Show in the output: a list of [The sender address on message , messageId, is too long to use as a ticket title; skipped.] joined by nothing.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ListsGet the last item of senderKey split by @ and save it as senderDomain.Get the last item of senderKey split by @ and save it as senderDomain.
TextCheck whether ourDomainList contains a list of [,, senderDomain, ,] joined by nothing and save it as ownDomain.Check whether ourDomainList contains a list of [,, senderDomain, ,] joined by nothing and save it as ownDomain.
ValuesSet subject to (no subject).Set subject to (no subject).
Decisions & LoopsIf a step below fails, save the error as subjectMissingIf a step below fails, save the error as subjectMissing
Try
TextTrim message.subject and save it as subjectText.Trim message.subject and save it as subjectText.
Decisions & LoopsIf subjectText isn't empty and subjectText is not nullIf subjectText isn't empty and subjectText is not null
Yes
ValuesChange subject to subjectText.Change subject to subjectText.
No
No steps
On error
ValuesShow in the output: A reported message arrived with no subject..Show in the output: A reported message arrived with no subject..
Decisions & LoopsFor each subjectLink in all web addresses in subject:For each subjectLink in all web addresses in subject:
Text Replace subjectLink with [link removed] in subject and save it as subject. Replace subjectLink with [link removed] in subject and save it as subject.
Decisions & LoopsIf subject contains ://If subject contains ://
Yes
ValuesChange subject to (subject withheld: it carried a web address).Change subject to (subject withheld: it carried a web address).
No
No steps
ValuesSet bodyText to blank.Set bodyText to blank.
Decisions & LoopsIf a step below fails, save the error as bodyMissingIf a step below fails, save the error as bodyMissing
Try
TextTrim message.body and save it as bodyValue.Trim message.body and save it as bodyValue.
Decisions & LoopsIf bodyValue is not nullIf bodyValue is not null
Yes
ValuesChange bodyText to bodyValue.Change bodyText to bodyValue.
No
No steps
On error
ValuesShow in the output: A reported message arrived with no readable text..Show in the output: A reported message arrived with no readable text..
ListsStart an empty list and save it as namesUsed.Start an empty list and save it as namesUsed.
Decisions & LoopsFor each candidate in nameList:For each candidate in nameList:
Text Trim candidate and save it as nameText. Trim candidate and save it as nameText.
Decisions & Loops If nameText is empty or nameText is null If nameText is empty or nameText is null
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Text Check whether displayName contains nameText (ignoring case) and save it as inName. Check whether displayName contains nameText (ignoring case) and save it as inName.
Text Check whether subject contains nameText (ignoring case) and save it as inSubject. Check whether subject contains nameText (ignoring case) and save it as inSubject.
Decisions & Loops If inName is yes or inSubject is yes and ownDomain is no If inName is yes or inSubject is yes and ownDomain is no
Yes
ListsAdd nameText to the end of namesUsed and save it as namesUsed.Add nameText to the end of namesUsed and save it as namesUsed.
No
No steps
ValuesSet nameLine to None of the names in 'impersonatedNames' appear in the sender name or the subject..Set nameLine to None of the names in 'impersonatedNames' appear in the sender name or the subject..
Decisions & LoopsIf namesUsed isn't emptyIf namesUsed isn't empty
Yes
TextJoin a list of [Names from 'impersonatedNames' that appear in the sender name or the subject: , namesUsed joined by , , . The address itself is not on one of your own domains.] with nothing and save it as nameLine.Join a list of [Names from 'impersonatedNames' that appear in the sender name or the subject: , namesUsed joined by , , . The address itself is not on one of your own domains.] with nothing and save it as nameLine.
No
No steps
ListsStart an empty list and save it as linkHosts.Start an empty list and save it as linkHosts.
ValuesSet linkCount to 0.Set linkCount to 0.
Decisions & LoopsFor each linkUrl in all web addresses in bodyText:For each linkUrl in all web addresses in bodyText:
Decisions & Loops If linkCount is greater than or equal to 8 If linkCount is greater than or equal to 8
Yes
Decisions & LoopsStop repeating.Stop repeating.
No
No steps
Text Join the items from index 1 onward of linkUrl split by :// with :// and save it as afterScheme. Join the items from index 1 onward of linkUrl split by :// with :// and save it as afterScheme.
Lists Get the first item of afterScheme split by / and save it as hostPart. Get the first item of afterScheme split by / and save it as hostPart.
Lists Get the first item of hostPart split by ? and save it as hostPart. Get the first item of hostPart split by ? and save it as hostPart.
Lists Get the first item of hostPart split by # and save it as hostPart. Get the first item of hostPart split by # and save it as hostPart.
Lists Get the last item of hostPart split by @ and save it as hostPart. Get the last item of hostPart split by @ and save it as hostPart.
Lists Get the first item of hostPart split by : and save it as hostPart. Get the first item of hostPart split by : and save it as hostPart.
Text Make hostPart lowercase and save it as linkHost. Make hostPart lowercase and save it as linkHost.
Decisions & Loops If linkHost is empty or linkHost doesn't contain . or linkHost contains : or… If linkHost is empty or linkHost doesn't contain . or linkHost contains : or…
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & Loops If linkHosts contains linkHost If linkHosts contains linkHost
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Lists Add linkHost to the end of linkHosts and save it as linkHosts. Add linkHost to the end of linkHosts and save it as linkHosts.
Values Add 1 to linkCount. Add 1 to linkCount.
ValuesSet hostLine to No web addresses were found in the text of the message..Set hostLine to No web addresses were found in the text of the message..
Decisions & LoopsIf linkHosts isn't emptyIf linkHosts isn't empty
Yes
TextJoin a list of [Hosts the message text links to: , linkHosts joined by , , . Only the host part of each link is recorded here; the rest of each address is left out of the ticket on purpose, because it can carry a code that identifies the person who was written to.] with nothing and save it as hostLine.Join a list of [Hosts the message text links to: , linkHosts joined by , , . Only the host part of each link is recorded here; the rest of each address is left out of the ticket on purpose, because it can carry a code that identifies the person who was written to.] with nothing and save it as hostLine.
No
No steps
TextJoin a list of [[sender: , senderKey, ]] with nothing and save it as marker.Join a list of [[sender: , senderKey, ]] with nothing and save it as marker.
TextJoin a list of [project = , @jiraProjectKey, AND summary ~ , @senderKey, ORDER BY created DESC] with nothing and save it as jql.Join a list of [project = , @jiraProjectKey, AND summary ~ , @senderKey, ORDER BY created DESC] with nothing and save it as jql.
JiraJiraFind issues matching jql. Save it as candidates.Find issues matching jql. Save it as candidates.
ValuesSet openTicket to blank.Set openTicket to blank.
Decisions & LoopsFor each issue in candidates.issues:For each issue in candidates.issues:
Text Trim issue.summary and save it as issueSummary. Trim issue.summary and save it as issueSummary.
Decisions & Loops If issueSummary contains marker If issueSummary contains marker
Yes
TextTrim issue.key and save it as issueKey.Trim issue.key and save it as issueKey.
Decisions & LoopsIf issueKey isn't empty and issueKey is not nullIf issueKey isn't empty and issueKey is not null
Yes
ValuesChange openTicket to issueKey.Change openTicket to issueKey.
Decisions & LoopsStop repeating.Stop repeating.
No
No steps
No
No steps
TextShorten subject to 100 characters and save it as subjectShort.Shorten subject to 100 characters and save it as subjectShort.
ValuesSet ownDomainLine to The address is not on one of the domains listed in 'ourDomains'..Set ownDomainLine to The address is not on one of the domains listed in 'ourDomains'..
Decisions & LoopsIf ownDomain is yesIf ownDomain is yes
Yes
ValuesChange ownDomainLine to The address is on one of the domains listed in 'ourDomains'..Change ownDomainLine to The address is on one of the domains listed in 'ourDomains'..
No
No steps
ValuesSet nameShown to displayName.Set nameShown to displayName.
Decisions & LoopsIf displayName is emptyIf displayName is empty
Yes
ValuesChange nameShown to (none).Change nameShown to (none).
No
No steps
TextJoin a list of [Sender address: , senderKey, "Join a list of [Sender address: , senderKey, Name shown on the message: , nameShown, Sender domain: , senderDomain, , ownDomainLine] with nothing and save it as sectionSender.
ValuesSet sectionSubject to Subject as received: subjectShort.Set sectionSubject to Subject as received: subjectShort.
ValuesSet sectionNames to nameLine.Set sectionNames to nameLine.
ValuesSet sectionHosts to hostLine.Set sectionHosts to hostLine.
TextJoin a list of [Gmail message id: , messageId, "Join a list of [Gmail message id: , messageId, Picked up on: , today's date] with nothing and save it as sectionIds.
ValuesSet sectionNote to Every line above is copied from the message itself. Nothing here reads the body into the ticket, and no step decides what the message is - that is the reader's job..Set sectionNote to Every line above is copied from the message itself. Nothing here reads the body into the ticket, and no step decides what the message is - that is the reader's job..
TextJoin a list of [sectionSender, sectionSubject, sectionNames, sectionHosts, sectionIds, sectionNote] with a blank line and save it as ticketBody.Join a list of [sectionSender, sectionSubject, sectionNames, sectionHosts, sectionIds, sectionNote] with a blank line and save it as ticketBody.
Decisions & LoopsFor each bodyLink in all web addresses in ticketBody:For each bodyLink in all web addresses in ticketBody:
Text Replace bodyLink with [link removed] in ticketBody and save it as ticketBody. Replace bodyLink with [link removed] in ticketBody and save it as ticketBody.
Decisions & LoopsIf ticketBody contains ://If ticketBody contains ://
Yes
ValuesChange ticketBody to The details of this report carried a web address and were left out. Open the message in the mailbox instead..Change ticketBody to The details of this report carried a web address and were left out. Open the message in the mailbox instead..
No
No steps
Decisions & LoopsIf openTicket isn't emptyIf openTicket isn't empty
Yes
JiraJiraComment on openTicket: 'Another message from this sender was reported.Comment on openTicket: 'Another message from this sender was reported. ticketBody'.
ValuesAdd 1 to commentCount.Add 1 to commentCount.
No
JiraJiraCreate the issue 'a list of [Reported mail , marker, , subjectShort] joined by nothing' in jiraProjectKey.Create the issue 'a list of [Reported mail , marker, , subjectShort] joined by nothing' in jiraProjectKey.ticketBody
ValuesAdd 1 to ticketCount.Add 1 to ticketCount.
GmailGmailAdd label triagedLabel to email messageId.Add label triagedLabel to email messageId.
ValuesAdd 1 to handledCount.Add 1 to handledCount.
On error
ValuesShow in the output: Could not raise a ticket for one reported message: reportError as text.Show in the output: Could not raise a ticket for one reported message: reportError as text.
ValuesShow in the output: a list of [Reports handled: , handledCount as text, (new tickets: , ticketCount as text, , added to a ticket already open: , commentCount as text, )] joined by nothing.Show in the output: a list of [Reports handled: , handledCount as text, (new tickets: , ticketCount as text, , added to a ticket already open: , commentCount as text, )] joined by nothing.