Receive Events

You can use events to obtain changes that occur in Oracle Field Service Cloud (OFSC) application, such as field changes, status changes, and so on. An event is generated when a change occurs in the application. There are various events defined within the application such as 'activityCreated', 'activityCompleted', 'inventoryInstalled', and so on. You need to first subscribe to the required events defined in the application before you try retrieving the related changes.

Let's look at an example to understand the use of events.

Vision Corporation is a company whose back office system is integrated with OFSC. The back office system is the master system for all customer and inventory records and should always be synced with OFSC in near real-time. It is the source where any work/activity is generated before being sent to OFSC and to which all OFSC updates are synched back into. Vision Corporation uses the information maintained in the back office system for:

  • Work status tracking: Used to keep track of the customer's work status which is then used to bill them for the work that was completed such as an installation activity, trouble call that had a charge, and so on.
  • History tracking: Used to maintain historical information for work previously done, such as, details of the technician that completed the work, notes specific to the work, the technician's findings or resolution for the customer request, and so on.
  • Business analytics: Used for internal analysis to determine trends in the business, such as, how often an activity occurs, what was done to complete the work, and so on.

Let's suppose you need to update the back office system with all finished activities that you receive from OFSC. These include activities whose status has been updated to 'completed', 'notdone', or 'suspended'.

To receive the activities, you will first need to subscribe to the events that correspond to the activity status updates. Events are generated when there is a change in the application. In this case, whenever an activity status is updated to 'completed', 'notdone', or 'suspended', a different event is generated. You need to subscribe to these events, which are 'activityCompleted', 'activityNotDone', and 'activitySuspended respectively. After subscribing to these events, you can retrieve the events and the related activity details. You can also delete a subscription that you don't need anymore.

You can subscribe to many types of events. For more information, see Supported Events.

Create a Subscription

Suppose you want to subscribe to multiple events, in this case, to events that occur when the activity status is updated to 'completed', 'notdone', or 'suspended'. And you also want to specify some additional configurations for these events such as filter conditions on the events, specific fields to include in the events, and so on. You can create the subscription as follows:

  1. Construct the request URL for the 'Create subscription' operation.
  2. Identify the events you need to subscribe to: activityCompleted, activityNotDone, and activitySuspended.
  3. Construct the request body with the subscriptionConfig parameter to specify the events and the additional configurations. In this scenario, you apply:
    • One set of configurations for event activityCompleted
    • Another set of configurations for events activityNotDone and activitySuspended
  4. Run the request using the POST HTTP method to create the subscription. If the request is successful, you get a subscriptionId indicating that the subscription was created.

Note:

The events that support fields, filterExpression, and monitorChanges parameters under the subscriptionConfig parameter are:

Although you can specify monitorChanges for any of these events. It only makes sense to include it for events that change fields. For example, the userDeleted event doesn't change any field, so monitorChanges makes no sense and is ignored.

Example URL

Here's the complete URL with the POST HTTP method.

POST  
https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/subscriptions

cURL Command

curl -X POST 'https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/subscriptions' -u '<CLIENT_ID>@<INSTANCE_NAME>:<CLIENT_SECRET>' -d '{"subscriptionConfig":[{"events" : ["activityCompleted"],"filterExpression" : "(activityDetails.activityType in ['\''IN'\'','\''TC'\'','\''BR'\'']) AND (user != '\''my_integ'\'') AND (activityDetails.customerName != '\'''\'')","fields" : ["timeSlot","apptNumber","resourceId","resourceInternalId","date","status","customerName","streetAddress","language","masterActivityId"]},{"events" : ["activityNotDone","activitySuspended"],"filterExpression" : "(activityDetails.activityType in ['\''IN'\'','\''TC'\'','\''BR'\'']) AND (user != '\''my_integ'\'') AND (activityDetails.customerName != '\'''\'')","fields" : ["apptNumber","resourceId","date","status","customerName","streetAddress"]}]}'

Example Request Body

Here's an example of the request body in JSON format.

{
    "subscriptionConfig":[
        {
            "events" : ["activityCompleted"],
            "filterExpression" : "(activityDetails.activityType in ['IN','TC','BR']) AND (user != 'my_integ') AND (activityDetails.customerName != '')",
                "fields" : [
                "timeSlot",
                "apptNumber",
                "resourceId",
                "resourceInternalId",
                "date",
                "status",
                "customerName",
                "streetAddress",
                "language",
                "masterActivityId"
            ]
        },
        {
            "events" : [
                "activityNotDone",
                "activitySuspended"
            ],
            "filterExpression" : "(activityDetails.activityType in ['IN','TC','BR']) AND (user != 'my_integ') AND (activityDetails.customerName != '')",
            "fields" : [
                "apptNumber",
                "resourceId",
                "date",
                "status",
                "customerName",
                "streetAddress"
            ]
        }
     ]
 }

Example Response

Here's an example of the response body in JSON format.

HTTP/1.1 200 OK
  {
    "subscriptionId": "2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2",
    "nextPage": "190404-305,0",
    "links": [
        {
            "rel": "describedby",
            "href": "https://<instance_name>.etadirect.com/rest/ofscCore/v1/metadata-catalog/events"
        },
        {
            "rel": "canonical",
            "href": "https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/subscriptions/2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2"
        },
        {
            "rel": "data",
            "href": "https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2&page=190404-305,0"
        }
     ]
 }

Retrieve Events after Creating a Subscription

After you have created the subscription successfully, you are ready to retrieve the events and the related activities using the subscriptionId and nextPage values that you received in the response of the create subscription operation. Suppose you created a subscription and in the response, you received the subscriptionId as 2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2 and the nextPage as 190404-305,0. You can retrieve the events for the given subscription as follows:

  1. Construct the request URL for the 'Get events' operation.
  2. Specify the path parameters, subscriptionId as 2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2 and page as 190404-305,0 in the operation URL.
  3. Run the request using the GET HTTP method to retrieve the events.

Note:

  • If there are no events in the response, wait for some time for new events to be generated and then try retrieving again, starting from Step 1.
  • To retrieve the next set of events, take a note of the nextPage value in the response and specify it as the page value in the subsequent request or directly use the link provided for "rel":"next" as the request URL for the subsequent request.

You can try retrieving at any interval, but you must keep in my mind the following constraints:

  • Time limit: Subscriptions that the you don't attempt to retrieve for more than 36 hours after creation are marked as unused subscriptions. Unused subscriptions expire automatically in 36 hours or 1.5 days. It's recommended that you retrieve the subscriptions at least once during this interval.
  • Subscription count limit: The number of subscriptions that you can create at a time must not exceed 100. If the number exceeds 100, the subscription creation fails. You must wait for 36 hours for the oldest subscription to expire.
  • Subscription event type limit: You can create only one subscription with the specified event types for each API user. Any attempt to create a second subscription using the same event types returns the existing subscription.

Example URL

Here's the complete URL with the GET HTTP method.

GET 
https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2&page=190404-305,0

cURL Command

curl -X GET 'https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2&page=190404-305,0' -u '<CLIENT_ID>@<INSTANCE_NAME>:<CLIENT_SECRET>'

Example Response

Here's an example of the response body in JSON format.

{
    "found": true,
    "nextPage": "190405-414,0",
    "items": [
        {
            "eventType": "activityCompleted",
            "time": "2019-04-05 08:56:24",
            "user": "brc.root",
            "applicationId": "ed46d96e4163c9b642582c4aee4a2f2967906876",
            "activityDetails": {
                "activityId": 8764272,
                "masterActivityId": 0,
                "resourceId": "tech_activityCompleted_event986",
                "resourceInternalId": 21620,
                "date": "2019-04-05",
                "apptNumber": "ApptNumber",
                "status": "completed",
                "timeSlot": "01",
                "customerName": "John Doe",
                "streetAddress": "8 Palm Pl",
                "language": "en",
                "languageISO": "en-US"
            },
            "activityChanges": {
                "status": "completed",
                "duration": 180,
                "endTime": "2019-04-05 19:00:00"
            }
        },
        {
            "eventType": "activityNotDone",
            "time": "2019-04-05 09:53:03",
            "user": "brc.root",
            "applicationId": "ed46d96e4163c9b642582c4aee4a2f2967906876",
            "activityDetails": {
                "activityId": 8764273,
                "resourceId": "tech_activityCompleted_event181",
                "resourceInternalId": 21621,
                "date": "2019-04-05",
                "apptNumber": "ApptNumber",
                "status": "notdone",
                "customerName": "John Doe",
                "streetAddress": "8 Palm Pl"
            },
            "activityChanges": {
                "status": "notdone",
                "duration": 7560,
                "endTime": "2019-04-10 22:00:00"
            }
        },
        {
            "eventType": "activityNotDone",
            "time": "2019-04-05 10:07:22",
            "user": "brc.root",
            "applicationId": "ed46d96e4163c9b642582c4aee4a2f2967906876",
            "activityDetails": {
                "activityId": 8764277,
                "resourceId": "tech_activityNotDone_event226",
                "resourceInternalId": 21626,
                "date": "2019-04-05",
                "apptNumber": "ApptNumber",
                "status": "notdone",
                "customerName": "John Doe",
                "streetAddress": "8 Palm Pl"
            },
            "activityChanges": {
                "status": "notdone",
                "duration": 240,
                "endTime": "2019-04-05 20:00:00"
            }
        },
        {
            "eventType": "activitySuspended",
            "time": "2019-04-05 10:18:45",
            "user": "brc.root",
            "applicationId": "ed46d96e4163c9b642582c4aee4a2f2967906876",
            "activityDetails": {
                "activityId": 8764274,
                "resourceId": "tech_activityCompleted_event363",
                "resourceInternalId": 21622,
                "date": "2019-04-05",
                "apptNumber": "ApptNumber",
                "status": "pending",
                "customerName": "John Doe",
                "streetAddress": "8 Palm Pl"
            },
            "activityChanges": {
                "status": "pending",
                "startTime": "",
                "positionInRoute": 0
            }
        }
    ],
    "links": [
        {
            "rel": "describedby",
            "href": "https://<instance_name>.etadirect.com/rest/ofscCore/v1/metadata-catalog/events"
        },
        {
            "rel": "canonical",
            "href": "https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2&page=190404-305,0"
        },
        {
            "rel": "next",
            "href": "https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2&page=190405-414,0"
        }
    ]
}

Frequently Asked Questions

  • What happens if OFSC generates many events at the same time?

    The maximum number of events that a single 'Get events' call can return is 1000. But you can specify any limit in the range of 1 to 1000 when making the call. You can then continually make calls for events in batches of 1000 or less, until there are no new events left.

  • How do I ensure that I don't receive the same set of events in the subsequent 'Get events' calls?

    In every 'Get events' call, you must specify the page and the limit query parameters in the request.

    When you make a 'Get events' call, the response always contains the nextPage field irrespective of the number of events returned. When you specify the nextPage field as the page parameter in the subsequent call, you get the next set of events following the previous call.

    The sequence of the 'Get events' calls is as follows:

    1. Make the first 'Get events' call.

      cURL Command:

      curl -X GET 'https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=1a876085c7a4df6018c04aa2a7066a63341bdc03&limit=2&page=160902-440,0' -u '<CLIENT_ID>@<INSTANCE_NAME>:<CLIENT_SECRET>'

      Example Response:

      {
          "nextPage": "160902-478,0",
          "items": [
              {
                  ...event 1...
              },
              {
                  ...event 2...
              }
          ]
      }
      
    2. Make the next 'Get events' call without any delay since in the previous call the nextPage value (160902-478,0) is different from the page parameter value (160902-440,0).

      cURL Command:

      curl -X GET 'https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=1a876085c7a4df6018c04aa2a7066a63341bdc03&limit=2&page=160902-478,0' -u '<CLIENT_ID>@<INSTANCE_NAME>:<CLIENT_SECRET>'

      Example Response:

      {
          "nextPage": "160902-478,1",
          "items": [
              {
                  ...event 3...
              }
          ]
      }
      
    3. Make the next 'Get events' call without any delay since in the previous call the nextPage value (160902-478,1) is different from the page parameter value (160902-478,0).

      cURL Command:

      curl -X GET 'https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=1a876085c7a4df6018c04aa2a7066a63341bdc03&limit=2&page=160902-478,1' -u '<CLIENT_ID>@<INSTANCE_NAME>:<CLIENT_SECRET>'

      Example Response:

      {
          "found": true,
          "nextPage": "160902-478,1",
          "items": [
          ],
      }
      
    4. You should wait for a while before making the next 'Get events' call since in the previous call the nextPage value (160902-478,1) is same as the page parameter value (160902-478,1).
  • What is the recommended time interval between subsequent 'Get events' calls?

    The time interval between the calls depend on your requirement.

    • If real-time updates are required, the time interval should be 1 minute.
    • If real-time updates are not required, the time interval can be an hour or more.
    • The time interval must not exceed 1.5 days. In case no 'Get events' requests are received for your subscription in 1.5 days, then the subscription is marked as unused, and is deleted.

Recover Lost Page Parameter for Retrieving Events

Suppose due to some application failure, such as abnormal termination of the process, you lose the page parameter value that you had obtained from the previous successful call to the 'Get events' operation. You can recover it by using the special page identifier lastRequested. The following is a sample flow depicting the loss and recovery of the page parameter value:

  1. You call the 'Get events' operation by passing the subscriptionId parameter value and successfully retrieve the events related to the subscription.
  2. You make a subsequent call to the 'Get events' operation by passing the subscriptionId and the page parameter values obtained from the previous successful 'Get events' call.
  3. You get an application error and lose the page value.
  4. You recover the page value by calling the 'Get events' operation and passing the subscriptionId parameter value and the special page parameter value lastRequested.
  5. OFSC uses the value of the page parameter received in the previous 'Get events' call and you receive the events starting from the last page before the failure.

Example URL

Here's the complete URL with the GET HTTP method.

GET 
https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2&page=lastRequested

cURL Command

curl -X GET 'https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2&page=lastRequested' -u '<CLIENT_ID>@<INSTANCE_NAME>:<CLIENT_SECRET>'

Example Response

Here's an example of the response body in JSON format.

{
    "found": true,
    "nextPage": "190405-417,0",
    "items": [
        {
            "eventType": "activityCompleted",
            "time": "2019-04-05 08:56:24",
            "user": "brc.root",
            "applicationId": "ed46d96e4163c9b642582c4aee4a2f2967906876",
            "activityDetails": {
                "activityId": 8764272,
                "masterActivityId": 0,
                "resourceId": "tech_activityCompleted_event986",
                "resourceInternalId": 21620,
                "date": "2019-04-05",
                "apptNumber": "ApptNumber",
                "status": "completed",
                "timeSlot": "01",
                "customerName": "John Doe",
                "streetAddress": "8 Palm Pl",
                "language": "en",
                "languageISO": "en-US"
            },
            "activityChanges": {
                "status": "completed",
                "duration": 180,
                "endTime": "2019-04-05 19:00:00"
            }
        },
        {
            "eventType": "activityNotDone",
            "time": "2019-04-05 09:53:03",
            "user": "brc.root",
            "applicationId": "ed46d96e4163c9b642582c4aee4a2f2967906876",
            "activityDetails": {
                "activityId": 8764273,
                "resourceId": "tech_activityCompleted_event181",
                "resourceInternalId": 21621,
                "date": "2019-04-05",
                "apptNumber": "ApptNumber",
                "status": "notdone",
                "customerName": "John Doe",
                "streetAddress": "8 Palm Pl"
            },
            "activityChanges": {
                "status": "notdone",
                "duration": 7560,
                "endTime": "2019-04-10 22:00:00"
            }
        },
        {
            "eventType": "activityNotDone",
            "time": "2019-04-05 10:07:22",
            "user": "brc.root",
            "applicationId": "ed46d96e4163c9b642582c4aee4a2f2967906876",
            "activityDetails": {
                "activityId": 8764277,
                "resourceId": "tech_activityNotDone_event226",
                "resourceInternalId": 21626,
                "date": "2019-04-05",
                "apptNumber": "ApptNumber",
                "status": "notdone",
                "customerName": "John Doe",
                "streetAddress": "8 Palm Pl"
            },
            "activityChanges": {
                "status": "notdone",
                "duration": 240,
                "endTime": "2019-04-05 20:00:00"
            }
        },
        {
            "eventType": "activitySuspended",
            "time": "2019-04-05 10:18:45",
            "user": "brc.root",
            "applicationId": "ed46d96e4163c9b642582c4aee4a2f2967906876",
            "activityDetails": {
                "activityId": 8764274,
                "resourceId": "tech_activityCompleted_event363",
                "resourceInternalId": 21622,
                "date": "2019-04-05",
                "apptNumber": "ApptNumber",
                "status": "pending",
                "customerName": "John Doe",
                "streetAddress": "8 Palm Pl"
            },
            "activityChanges": {
                "status": "pending",
                "startTime": "",
                "positionInRoute": 0
            }
        }
    ],
    "links": [
        {
            "rel": "describedby",
            "href": "https://<instance_name>.etadirect.com/rest/ofscCore/v1/metadata-catalog/events"
        },
        {
            "rel": "canonical",
            "href": "https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2&page=190404-305,0"
        },
        {
            "rel": "next",
            "href": "https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/?subscriptionId=2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2&page=190405-417,0"
        }
    ]
}

Delete a Subscription

Suppose you want to delete an existing subscription that you don't need, say the subscription having subscriptionId as 2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2. You can delete the subscription as follows:

  1. Construct the request URL for the 'Delete subscription' operation.
  2. Specify the subscriptionId value as a path parameter in the operation URL.
  3. Run the request using the DELETE HTTP method to delete the subscription.

Note:

You can delete subscriptions only by using the application that created them.

Example URL

Here's the complete URL with the DELETE HTTP method.

DELETE 
https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/subscriptions/2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2

cURL Command

curl -X DELETE 'https://<instance_name>.etadirect.com/rest/ofscCore/v1/events/subscriptions/2fbcfe8c71f38a129b0e3ee63401bc208cbb45f2' -u '<CLIENT_ID>@<INSTANCE_NAME>:<CLIENT_SECRET>'

Example Response

Here's an example of the response.

HTTP/1.1 204 OK
No content