Product Events

Product events are Freshservice events, such as ticket create, ticket update, and conversation create, which can trigger apps. When product events occur, the appropriate method in the server.js file is invoked.

Note:
1. You need to have CLI v5.0.0 to use this feature. For more information on how to get the latest version, click here.
2. The serverless component of the app is executed in sandbox mode where some methods, such as setTimeout and 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", "IND", "EUC", or "AUS".
timestamp number App Installation timestamp in the epoch format.
iparams object Installation Parameters.
Registration

When a product event occurs, an event listener is required for the appropriate method to be invoked. This is done in the following format.

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. Include the event and callback definition in the exports block.
2. Include only one callback method for an event.

OnTicketCreate

When a new ticket is created, the onTicketCreate event is invoked and the registered callback method is executed.

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

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 idicating when the ticket is due to be resolved.
email_config_id number ID of email config is used for this ticket.
frDueBy datetime Timestamp indicating 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 Priority of the ticket.
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 Status of the ticket.
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 a ticket according to the different kinds of issues your support team deals with.
updated_at datetime Ticket updated timestamp.

Tickets use certain numbers to denote source, status, and priority. These numbers and their values are as folows.

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 pairs containing the names and values 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 Set to 'true' if the contact is an agent.
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

When a ticket property is updated, the onTicketUpdate event is invoked and the registered callback method is executed.

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. Replies or note additions are not considered ticket updates, you need to use the onConversationCreate event to handle them.
2. Ticket deletion is captured by the onTicketUpdate event and the deleted field is changed to true in the changes object.


Restrictions

The following changes will NOT trigger the onTicketUpdate event.

  • Updates to custom fields.
  • Updates to tags.

Use the following format to include the event in the server.js file.

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, the deleted is set to true as shown in the sample code.
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, and consists of the updated keys with the 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 indicating 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 indicating 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 ID of the ticket.
isescalated boolean Set to 'true' if the ticket has been escalated for any reason.
priority number Priority of the ticket.
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 Status of the ticket.
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 a 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 pairs containing the names and values 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 Set to 'true' if the contact is an agent.
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

When a reply or note is added to a ticket, the onConversationCreate event is invoked and the registered callback method is executed.

The supported conversation create events are:

  • Reply added
  • Public note added
  • Private note added

Use the following format to include the event in the server.js file.

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 is truncated if it exceeds 10 KB.
is_body_truncated boolean Set to 'true' if the body is truncated.
body_text string Content of the conversation in plain text. This content is truncated if it exceeds 10 KB.
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 is used.
id number 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.
source number Denotes the type of 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 numbers to denote its source. These numbers and their values are listed.

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
Testing

Note: For testing, we recommend that you use the latest version of Chrome browser.

You can easily test your app in your machine by simulating events. Also, you can test different scenarios by directly modifying the payload.

Note:
As the testing is only a simulation of 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 events for testing, follow the given procedure.

  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, the following error message is displayed.
  4. Select the event that you want to simulate.
  5. Once you select an event, the corresponding event payload is displayed. Edit the values and then click Simulate. When you edit the payload, ensure that you adhere to the JSON format.
  6. If the event is successfully simulated, Success is displayed.
  7. If there was a problem, Failed is displayed. Check if the payload is valid and then resume testing.