Product Events

Product events are Freshservice events such as ticket create, ticket update, and conversation create that can trigger apps. When these events occur, the appropriate method within the server.js file of an app is called.

Note:
1. You need to have CLI v4.0.0 or higher in order to use this feature. You can find instructions on how to get the latest version here.
2. The serverless component of the app will be executed in sandbox mode and hence methods such as setTimeout, setInterval cannot be used.


Payload

When a supported product event occurs, the corresponding method in the server.js is invoked and the following payload is passed to the app to enable it to get context about the event.

Copied Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{ "account_id" : "value", "domain" : "value", "event" : "value", "region" : "value", "timestamp" : "value", "data" : { //“data” contains the list of objects related to the event. }, "iparams" : { "Param1" : "value", "Param2" : "value" } }
EXPAND ↓

Attribute Type Description
account_id number Freshservice account ID
domain string Freshservice account domain
event string Name of the event
region string Region where the app is installed, will be either "US", "EU", "EUC", or "AUS"
timestamp number App Installation timestamp in the epoch format
iparams object Installation Parameters

Registration

In order for the appropriate method to be called when an event occurs, an event listener should be added. This should be done in the format as shown in the sample below.


server.js Copied Copy
1
2
3
4
5
6
7
8
9
exports = { events: [ { event: "eventName", callback: "eventCallbackMethod" } ], eventCallbackMethod: function(payload) { //Multiple events can access the same callback console.log("Logging arguments from the event: " + JSON.stringify(payload)); } }

Note:
1. You should include the event and the callback definition within the exports block.
2. You should include only one callback method for an event.
3. You should only use valid keys - event and callback, usage of other keys will throw an error.
4. Provide a valid event name, incorrect names will lead to an error.


onTicketCreate

This event will be invoked every time a new ticket is created. The registered callback method for this event will be executed in response to this event.

Use the following format to include this event in the server.js:

Copied Copy
1
2
3
4
5
6
7
8
exports = { events: [ { event: "onTicketCreate", callback: "onTicketCreateCallback" } ], onTicketCreateCallback: function(payload) { console.log("Logging arguments from onTicketCreate event: " + JSON.stringify(payload)); } }

Sample Code Copied Copy
1
2
3
4
5
6
7
8
9
10
11
12
exports = { events: [ { event: "onTicketCreate", callback: "onTicketCreateCallback" } ], onTicketCreateCallback: function(payload) { console.log("Logging arguments from onTicketCreate event: " + JSON.stringify(payload)); if(payload.data.ticket.priority >= 3) { //your code goes here } } }
EXPAND ↓

Sample Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{ "account_id": 164988, "domain": "sample.freshservice.com", "event": "onTicketCreate", "timestamp": 1538139725.6096382, "region": "US", "data": { "ticket": { "subject": "Support Needed...", "description": "<div>Some details on the issue ..</div>", "is_description_html_truncated": false, "description_text": "Some details on the issue ...", "is_description_text_truncated": false, "due_by": "2018-10-03T09:02:05-04:00", "fr_due_by": "2018-10-01T09:02:05-04:00", "fr_escalated": false, "is_escalated": false, "fwd_emails": [], "reply_cc_emails": [], "email_config_id": null, "id": 1, "group_id": null, "group_name": "No Group", "department_id": null, "department_name": "", "responder_id": null, "requester_id": 8000236257, "responder_email": "", "responder_name": "No Agent", "status": 2, "status_name": "Open", "priority": 1, "priority_name": "Low", "type_name": "Incident", "tags": [], "spam": false, "source": 3, "source_name": "Phone", "urgency": 1, "urgency_name": "Low", "impact": 1, "impact_name": "Low", "category": null, "sub_category": null, "item_category": null, "cc_emails": [], "created_at": "2018-09-28T09:02:05-04:00", "updated_at": "2018-09-28T09:02:05-04:00", "attachments": [], "problem": null, "change": null, "assets": [], "custom_fields": [{ "name": "serverless", "label": "serverless ", "value": null }] }, "requester": { "id": 8000236257, "name": "Rachel", "email": "rachel@freshservice.com", "mobile": 7654367287, "phone": 4352789885, "language": "en", "created_at": "2018-01-18T02:13:05-05:00" } }, "iparams": null }
EXPAND ↓

The following table lists the attributes of the ticket object:

ATTRIBUTE TYPE DESCRIPTION
cc_email object of arrays Email address added in the 'cc' field of the ticket.
department_id number ID of the department to which this ticket belongs
created_at datetime Ticket creation timestamp
custom_field object Key value pairs containing the names and values of custom fields.
description_html string HTML content of the ticket
description string Content of the ticket in plain text
due_by datetime Timestamp that denotes when the ticket is due to be resolved
email_config_id number ID of email config which is used for this ticket.
frDueBy datetime Timestamp that denotes when the first response is due
fr_escalated boolean Set to true if the ticket has been escalated as the result of the first response time being breached
group_id number ID of the group to which the ticket has been assigned
id number Unique ID of the ticket
isescalated boolean Set to true if the ticket has been escalated for any reason
priority number Ticket priority value
priority_name string Ticket priority text
requester_id number User ID of the requester. For existing contacts, the requester_id can be passed instead of the requester's email.
responder_id number ID of the agent to whom the ticket has been assigned.
source number The channel through which the ticket was created. This field contains the source value.
source_name string This field contains the source text.
spam boolean Set to true if the ticket has been marked as spam
status number Ticket status value
status_name string Ticket status text
subject string Subject of the ticket
tags array of strings Tags that have been associated with the ticket
ticket_type string Helps categorize the ticket according to the different kinds of issues your support team deals with.
updated_at datetime Ticket updated timestamp

Every ticket uses certain fixed numerical values to denote its source, status, and priority. These numerical values along with their meanings are given below.

Source Value
Email 1
Portal 2
Phone 3
Chat 4
Feedback Widget 5
Yammer 6
AWS CloudWatch 7
Pagerduty 8
Walk-up 9
Slack 10
Status Value
Open 2
Pending 3
Resolved 4
Closed 5
Priority Value
Low 1
Medium 2
High 3
Urgent 4

The following table lists the attributes of the requester/contact object:

ATTRIBUTE TYPE DESCRIPTION
active boolean Set to true if the contact has been verified
address string Address of the contact
created_at datetime Contact creation timestamp
custom_field dictionary Key value pair containing the name and value of the custom fields.
deleted boolean Set to true if the contact has been deleted
description string A short description of the contact
email string Primary email address of the contact. If you want to associate additional email(s) with this contact, use the other_emails attribute
external_id number ID of the contact in an external system
helpdesk_agent boolean Is the contact an agent or not?
id number ID of the contact
job_title string Job title of the contact
language string Language of the contact
mobile number Mobile number of the contact
name string Name of the contact
phone number Telephone number of the contact
time_zone string Time zone in which the contact resides
updated_at datetime Contact updated timestamp


onTicketUpdate

This event will be invoked every time a ticket property is updated. You can provide the action to be performed in the callback method, this code will be executed in response to this event trigger.

The following ticket update events are supported:

  • Status changed
  • Priority changed
  • Group changed
  • Agent changed
  • Ticket deleted
  • Ticket is marked as spam
  • Type changed
  • Source changed
  • Ticket is escalated for any reason
  • Ticket is escalated because first response was breached

Note:
1. Ticket update only happens for updates to the ticket properties and a few other fields. Replies or note additions are not considered ticket updates, you need to use the onConversationCreate event to handle them.
2. Ticket deletion updates will be captured by the onTicketUpdate event and the changes object will note that the deleted boolean has been changed from false to true.


Restrictions

The following changes will NOT trigger a ticket update event:

  • Any updates made to custom fields.
  • Any updates to tags.

You should follow the below format to include the event in the server.js:

Copied Copy
1
2
3
4
5
6
7
8
exports = { events: [ { event: "onTicketUpdate", callback: "onTicketUpdateCallback" } ], onTicketUpdateCallback: function(payload) { console.log("Logging arguments from onTicketUpdate event: " + JSON.stringify(payload)); } }

Sample Code Copied Copy
1
2
3
4
5
6
7
8
9
10
11
exports = { events: [ { event: "onTicketUpdate", callback: "onTicketUpdateCallback" } ], onTicketUpdateCallback: function(payload) { console.log("Logging arguments from onTicketUpdate event: " + JSON.stringify(payload)); //Finding fields that are changed var changes = payload.data.ticket.changes; //Your code goes here } }
EXPAND ↓

Sample Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{ "account_id": 164988, "domain": "sample.freshservice.com", "event": "onTicketUpdate", "timestamp": 1538139545.776656, "region": "US", "data": { "ticket": { "subject": "Support Needed...", "description": "<div>Some details on the issue ..</div>", "is_description_html_truncated": false, "description_text": "Some details on the issue ...", "is_description_text_truncated": false, "due_by": "2018-10-03T08:00:06-04:00", "fr_due_by": "2018-10-01T08:00:06-04:00", "fr_escalated": false, "is_escalated": false, "fwd_emails": [], "reply_cc_emails": [], "email_config_id": null, "id": 286, "group_id": null, "group_name": "No Group", "department_id": null, "department_name": "", "responder_id": null, "requester_id": 8000766046, "responder_email": "", "responder_name": "No Agent", "status": 3, "status_name": "Pending", "priority": 1, "priority_name": "Low", "type_name": "Incident", "tags": [], "spam": false, "source": 2, "source_name": "Portal", "urgency": 1, "urgency_name": "Low", "impact": 1, "impact_name": "Low", "category": null, "sub_category": null, "item_category": null, "cc_emails": [], "created_at": "2018-09-28T07:31:18-04:00", "updated_at": "2018-09-28T08:59:05-04:00", "attachments": [], "problem": { "id": 4, "name": "one" }, "change": null, "assets": [], "custom_fields": [{ "name": "serverless", "label": "serverless ", "value": null }], "changes": { "status_name": [ "*", "Pending" ], "status": [ 2, 3 ] } }, "requester": { "id": 8000766046, "name": "Rachel", "email": "rachel@freshservice.com", "mobile": 7654367287, "phone": 4352789885, "language": "en", "created_at": "2018-05-03T09:24:23-04:00" } }, "iparams": null }
EXPAND ↓

When a ticket is deleted, a boolean field deleted will be set to true as shown in the below sample:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
{ "account_id": 164988, "domain": "sample.freshservice.com", "event": "onTicketUpdate", "timestamp": 1538139545.776656, "region": "US", "data": { "ticket": { "subject": "Support Needed...", "description": "<div>Some details on the issue ..</div>", "is_description_html_truncated": false, "description_text": "Some details on the issue ...", "is_description_text_truncated": false, "due_by": "2018-10-03T08:00:06-04:00", "fr_due_by": "2018-10-01T08:00:06-04:00", "fr_escalated": false, "is_escalated": false, "fwd_emails": [], "reply_cc_emails": [], "email_config_id": null, "id": 286, "group_id": null, "group_name": "No Group", "department_id": null, "department_name": "", "responder_id": null, "requester_id": 8000766046, "responder_email": "", "responder_name": "No Agent", "status": 3, "status_name": "Pending", "priority": 1, "priority_name": "Low", "type_name": "Incident", "tags": [], "spam": false, "source": 2, "source_name": "Portal", "urgency": 1, "urgency_name": "Low", "impact": 1, "impact_name": "Low", "category": null, "sub_category": null, "item_category": null, "cc_emails": [], "created_at": "2018-09-28T07:31:18-04:00", "updated_at": "2018-09-28T08:59:05-04:00", "attachments": [], "problem": { "id": 4, "name": "one" }, "change": null, "assets": [], "custom_fields": [{ "name": "serverless", "label": "serverless ", "value": null }], "changes": { "deleted": [false, true], } }, "requester": { "id": 8000766046, "name": "Rachel", "email": "rachel@freshservice.com", "mobile": 7654367287, "phone": 4352789885, "language": "en", "created_at": "2018-05-03T09:24:23-04:00" } }, "iparams": null }
EXPAND ↓

The changes field is passed along with the payload, this field consist of updated keys with old and new values.


The following table lists the attributes of the ticket object:

ATTRIBUTE TYPE DESCRIPTION
cc_email object of arrays Email address added in the 'cc' field of the ticket.
department_id number ID of the department to which this ticket belongs
created_at datetime Ticket creation timestamp
custom_field object Key value pairs containing the names and values of custom fields.
description_html string HTML content of the ticket
description string Content of the ticket in plain text
due_by datetime Timestamp that denotes when the ticket is due to be resolved
email_config_id number ID of email config which is used for this ticket.
frDueBy datetime Timestamp that denotes when the first response is due
fr_escalated boolean Set to true if the ticket has been escalated as the result of the first response time being breached
group_id number ID of the group to which the ticket has been assigned
id number Unique ID of the ticket
isescalated boolean Set to true if the ticket has been escalated for any reason
priority number Ticket priority value
priority_name string Ticket priority text
requester_id number User ID of the requester. For existing contacts, the requester_id can be passed instead of the requester's email.
responder_id number ID of the agent to whom the ticket has been assigned.
source number The channel through which the ticket was created. This field contains the source value.
source_name string This field contains the source text.
spam boolean Set to true if the ticket has been marked as spam
status number Ticket status value
status_name string Ticket status text
subject string Subject of the ticket
tags array of strings Tags that have been associated with the ticket
ticket_type string Helps categorize the ticket according to the different kinds of issues your support team deals with.
updated_at datetime Ticket updated timestamp

The following table lists the attributes of the requester/contact object:

ATTRIBUTE TYPE DESCRIPTION
active boolean Set to true if the contact has been verified
address string Address of the contact
created_at datetime Contact creation timestamp
custom_field dictionary Key value pair containing the name and value of the custom fields.
deleted boolean Set to true if the contact has been deleted
description string A short description of the contact
email string Primary email address of the contact. If you want to associate additional email(s) with this contact, use the other_emails attribute
external_id number ID of the contact in an external system
helpdesk_agent boolean Is the contact an agent or not?
id number ID of the contact
job_title string Job title of the contact
language string Language of the contact
mobile number Mobile number of the contact
name string Name of the contact
phone number Telephone number of the contact
time_zone string Time zone in which the contact resides
updated_at datetime Contact updated timestamp

onConversationCreate

This event will be invoked every time a reply or note is added to a ticket. You can provide the action to be performed in the callback method, this code will be executed in response to this event trigger.

Following are the supported conversation create events:

  • Reply added
  • Public note added
  • Private note added

The format to include the event in the server.js:

Copied Copy
1
2
3
4
5
6
7
8
exports = { events: [ { event: "onConversationCreate", callback: "onConversationCreateCallback" } ], onConversationCreateCallback: function(payload) { console.log("Logging arguments from onConversationCreate event: " + JSON.stringify(payload)); } }

Sample Reply Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{ "account_id": 712, "domain": "sample.freshservice.com", "event": "onConversationCreate", "timestamp": 1538139462.490419, "region": "US", "data": { "conversation": { "body": "<div>Hi tom, Still Angry</div>", "is_body_truncated": false, "body_text": "Hi tom, Still Angry", "is_body_text_truncated": false, "id": 1000008118, "from_email": null, "bcc_emails": [], "user_id": 1000014744, "ticket_id": 301, "ticket_group_id": null, "ticket_requester_id": 1000014833, "ticket_responder_id": null, "ticket_department_id": null, "ticket_display_id": "INC-301", "private": false, "incoming": false, "source": 0, "cc_emails": [], "to_emails": [], "created_at": "2018-09-28T18:27:42+05:30", "updated_at": "2018-09-28T18:27:42+05:30", "attachments": [] } }, "iparams": null }
EXPAND ↓

Sample Public Note Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{ "account_id": 712, "domain": "sample.freshservice.com", "event": "onConversationCreate", "timestamp": 1538139462.490419, "region": "US", "data": { "conversation": { "body": "<div>Hi tom, Still Angry</div>", "is_body_truncated": false, "body_text": "Hi tom, Still Angry", "is_body_text_truncated": false, "id": 1000008118, "from_email": null, "bcc_emails": [], "user_id": 1000014744, "ticket_id": 301, "ticket_group_id": null, "ticket_requester_id": 1000014833, "ticket_responder_id": null, "ticket_department_id": null, "ticket_display_id": "INC-301", "private": false, "incoming": false, "source": 2, "cc_emails": [], "to_emails": [], "created_at": "2018-09-28T18:27:42+05:30", "updated_at": "2018-09-28T18:27:42+05:30", "attachments": [] } }, "iparams": null }
EXPAND ↓

Sample Private Note Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{ "account_id": 712, "domain": "sample.freshservice.com", "event": "onConversationCreate", "timestamp": 1538139462.490419, "region": "US", "data": { "conversation": { "body": "<div>Hi tom, Still Angry</div>", "is_body_truncated": false, "body_text": "Hi tom, Still Angry", "is_body_text_truncated": false, "id": 1000008118, "from_email": null, "bcc_emails": [], "user_id": 1000014744, "ticket_id": 301, "ticket_group_id": null, "ticket_requester_id": 1000014833, "ticket_responder_id": null, "ticket_department_id": null, "ticket_display_id": "INC-301", "private": true, "incoming": false, "source": 2, "cc_emails": [], "to_emails": [], "created_at": "2018-09-28T18:27:42+05:30", "updated_at": "2018-09-28T18:27:42+05:30", "attachments": [] } }, "iparams": null }
EXPAND ↓

The following table lists the attributes of the conversation object:

ATTRIBUTE TYPE DESCRIPTION
attachments array of objects Attachments associated with the conversation
body string Content of the conversation in HTML. This content will be truncated if it exceeds 10KB.
is_body_truncated boolean Set to true if the body is truncated.
body_text string Content of the conversation in plain text. This content will be truncated if it exceeds 10KB.
is_body_text_truncated boolean Set to true if the body_text is truncated.
bcc_emails array of strings Email address added in the 'bcc' field of the outgoing ticket email
cc_emails array of strings Email addresses added in the 'cc' field of the incoming ticket email
created_at datetime Conversation creation timestamp in the UTC format, YYYY-MM-DDTHH:MM:SSZ. Example: 2016-02-13T23:27:49Z
from_email string The email address from which the reply is sent. By default, the global support email will be used.
id number Unique ID of the conversation
incoming boolean Set to true if a particular conversation should appear as being created from outside (i.e., not through a web portal)
private boolean Set to true if it is a private note
private boolean Set to true if it is a private note
source number Denotes the type of the conversation
supporting_email string Email address from which the reply is sent. For notes, this value will be null.
ticket_id number ID of the ticket to which the conversation is being added
to_emails array of strings Email addresses of agents/users who need to be notified about this conversation
updated_at datetime Ticket updated timestamp in the UTC format, YYYY-MM-DDTHH:MM:SSZ Example: 2016-02-13T23:27:49Z
user_id number ID of the agent/user who is adding the conversation

Every conversation uses certain fixed numerical values to denote its source. These numerical values along with their meanings are given below.

Source Value
Reply 0
Note 2
Created from tweets 5
Created from survey feedback 6
Created from Facebook post 7
Source Value
Created from Forwarded Email 8
Created from Phone 9
Created from Mobihelp 10
E-Commerce 11

Local Testing

You can easily test your app from your developer machine by simulating the events. For example, you can simulate a ticket being created which will trigger your app and send it a ticket create payload. You can test different scenarios by directly modifying the payload in the simulator window.

Note:
Since the testing is only simulating events, an actual event will not be recorded in the back end. If you need an actual ticket/contact to be created, then it is recommended to publish your app as a custom app and test the operation manually.


To simulate the events for local testing, follow the procedure outlined below:

  1. In your console, navigate to your project directory, and execute the following command: $ fdk run
  2. Open your browser and enter the following URL to start testing your app - http://localhost:10001/web/events.
  3. If your app does not include a serverless component, you will see an error message as shown below:
  4. Select the event that you want to simulate:
  5. Once you select an event, the corresponding event payload will be displayed. You can choose to edit the values and click Simulate. When you are editing the payload, ensure that you adhere to the JSON format.
  6. If the event was successfully simulated, you will see Success as shown below:
  7. If there was a problem, you will see Failed as shown in the below image:

Log in with your Freshservice account

Enter your helpdesk URL to proceed to login

Proceed

By clicking "Proceed", you agree to our Terms of Use.