API Development

Axway Integration Builder – Syncplicity Events – Part 2

Syncplicity Events

In part 1, we discussed the Integration Builder Syncplicity Connector Event feature. We also saw that while each activity (file upload, folder delete…) can trigger an event and hence your flow, the actual trigger payload will contain data for all activities that occurred between the polling intervals set up in the connector instance.

In this blog post, we’ll analyze the trigger payload and discuss some techniques for filtering and parsing the payload to achieve the desired goal of your flow.

Analyze the Data

We’ll look at the following trigger payload for the purposes of this blog post:

{
  "eventId": "AXM_crALR7mSjmiICLLZ",
  "instanceId": 359594,
  "body": {
    "message": {
      "eventId": "AXM_crALR7mSjmiICLLZ",
      "instanceName": "Syncp GL 2 Event",
      "instanceTags": [
        "Syncp GL 2 Event"
      ],
      "raw": {
        "pollDate": 1594497342469,
        "documents": [{
            "EventDate": 1594497285373,
            "EventSource": 3,
            "Type": 20,
            "Message": "DirPurged",
            "Id": 7516828465,
            "Folder": {
              "SyncpointId": 12132474,
              "FolderId": 1112506695192001,
              "VirtualPath": "\\x\\",
              "Name": "x"
            }
          },
          {
            "EventDate": 1594497285390,
            "EventSource": 3,
            "Type": 15,
            "Message": "FileDeletedPurged",
            "Id": 7516828466,
            "File": {
              "LatestVersionId": 1112506735212001,
              "Length": 52101,
              "LastWriteTimeUtc": "2020-07-11T14:57:53.2770000Z",
              "SyncpointId": 12132474,
              "Filename": "car.jpg",
              "FileId": 1112506735211001,
              "FolderId": 1112456422209001,
              "VirtualPath": "\\",
              "DateAddedUtc": "2020-07-11T14:57:53.3000000Z",
              "CreationTimeUtc": "2020-07-11T14:57:53.2770000Z"
            }
          },
          {
            "EventDate": 1594497289700,
            "EventSource": 3,
            "Type": 2,
            "Message": "FileCreated",
            "Id": 7516828577,
            "File": {
              "LatestVersionId": 1112684891479001,
              "Length": 52101,
              "LastWriteTimeUtc": "2020-07-11T19:54:49.6770000Z",
              "SyncpointId": 12132474,
              "Filename": "car.jpg",
              "FileId": 1112684891478001,
              "FolderId": 1112456422209001,
              "VirtualPath": "\\",
              "DateAddedUtc": "2020-07-11T19:54:49.6930000Z",
              "CreationTimeUtc": "2020-07-11T19:54:49.6770000Z"
            }
          },
          {
            "EventDate": 1594497296510,
            "EventSource": 3,
            "Type": 5,
            "Message": "DirCreated",
            "Id": 7516828690,
            "Folder": {
              "SyncpointId": 12132474,
              "FolderId": 1112684961492001,
              "VirtualPath": "\\x\\",
              "ParentFolderId": 1112456422209001,
              "Name": "x"
            }
          }
        ],
        "eventHeaders": {
          "id": "359594",
          "encodedid": "MzU5NTk0",
          "Raw-Element-Key": "syncplicity"
        },
        "objectType": "documents"
      },
      "userId": 21107,
      "elementKey": "syncplicity",
      "accountId": 18281,
      "companyId": 7861,
      "instanceId": 359594,
      "instance_id": 359594,
      "events": [{
          "date": "2020-07-11T19:54:45Z",
          "elementKey": "syncplicity",
          "pollDate": "2020-07-11T19:55:42Z",
          "eventType": "DELETED",
          "hubKey": "documents",
          "objectId": "1-12132474-1112506695192001",
          "objectType": "folder"
        },
        {
          "date": "2020-07-11T19:54:45Z",
          "elementKey": "syncplicity",
          "pollDate": "2020-07-11T19:55:42Z",
          "eventType": "DELETED",
          "hubKey": "documents",
          "objectId": "1-12132474-1112506735211001",
          "objectType": "file"
        },
        {
          "date": "2020-07-11T19:54:49Z",
          "elementKey": "syncplicity",
          "pollDate": "2020-07-11T19:55:42Z",
          "eventType": "CREATED",
          "hubKey": "documents",
          "objectId": "1-12132474-1112684891478001",
          "objectType": "file"
        },
        {
          "date": "2020-07-11T19:54:56Z",
          "elementKey": "syncplicity",
          "pollDate": "2020-07-11T19:55:42Z",
          "eventType": "CREATED",
          "hubKey": "documents",
          "objectId": "1-12132474-1112684961492001",
          "objectType": "folder"
        }
      ]
    }
  },
  "type": "event",
  "event": {
    "date": "2020-07-11T19:54:49Z",
    "elementKey": "syncplicity",
    "pollDate": "2020-07-11T19:55:42Z",
    "eventType": "CREATED",
    "hubKey": "documents",
    "objectId": "1-12132474-1112684891478001",
    "objectType": "file"
  }
}

By looking at the trigger.event object (at the bottom) you can see that this trigger corresponds to the action of a file (objectType) being created (eventType):

"event": {
  "date": "2020-07-11T19:54:49Z",
  "elementKey": "syncplicity",
  "pollDate": "2020-07-11T19:55:42Z",
  "eventType": "CREATED",
  "hubKey": "documents",
  "objectId": "1-12132474-1112684891478001",
  "objectType": "file"
}

By looking at the trigger.body.message.raw.events array, we can see three other events that occurred in the polling interval:

  • folder created
  • folder deleted
  • file deleted

However, things get more interesting when you look at the trigger.body.message.raw.documents array. You can find the object that relates to the trigger event below:

{
  "EventDate": 1594497289700,
  "EventSource": 3,
  "Type": 2,
  "Message": "FileCreated",
  "Id": 7516828577,
  "File": {
    "LatestVersionId": 1112684891479001,
    "Length": 52101,
    "LastWriteTimeUtc": "2020-07-11T19:54:49.6770000Z",
    "SyncpointId": 12132474,
    "Filename": "car.jpg",
    "FileId": 1112684891478001,
    "FolderId": 1112456422209001,
    "VirtualPath": "\\",
    "DateAddedUtc": "2020-07-11T19:54:49.6930000Z",
    "CreationTimeUtc": "2020-07-11T19:54:49.6770000Z"
  }
}

This brings us to the point of this analysis. Your flow may need to parse the trigger.body.message.raw.documents array based on the trigger.event to determine details related to the event that triggered your flow.

Filter

Say you are creating a flow that is looking for files uploaded to your Syncplicity account. One of the first things your flow should do is look at the trigger.event part of the trigger and look for a file (objectType) being created (eventType). You accomplish this using a JS Filter (true/false) step with the following Javascript:

done(trigger.event.objectType === 'file' && trigger.event.eventType === 'CREATED');

If you want to copy the file to AWS S3, then you can just access the trigger.event.objectId and you now have a handle to the file and you can proceed.

However, if you need more info about the file then you may need to parse the trigger.body.message.raw.documents array.

Parse Data

Say your flow only wants to process jpg/png images. You could use the trigger.event.objectId and make a Connector API Request to retrieve the metadata for the file, but that would be a wasted API call. Instead, you could look at the trigger.body.message.raw.documents array and see that the filename is available (car.jpg). You could analyze the filename extension to make sure it is a JPG or PNG file before proceeding.

The JS Filter (true/false) step to parse the trigger.body.message.raw.documents array is shown below:

// Check to see if the new file is a photo (png/jpg extension)

let documents = trigger.body.message.raw.documents;
let fileIdLong = trigger.event.objectId;
let fileIdLongComponents = fileIdLong.split('-');
let fileIdLongComponentsLen = fileIdLongComponents.length;
let fileIdShort = fileIdLongComponents[fileIdLongComponentsLen - 1];

var isDocumentFound = false;

documents.forEach(function(document){
  if(document.hasOwnProperty('File')) {
    if(document.File.FileId == fileIdShort) {
      let filename = document.File.Filename;
      let filenameComponents = filename.split('.');
      let filenameComponentsLen = filenameComponents.length;
      if(filenameComponentsLen > 1) {
        let fileExtension = filenameComponents[filenameComponentsLen-1].toUpperCase();
        if((fileExtension === 'JPG') || (fileExtension === 'PNG')) {
          config.foundDocument = document;
          isDocumentFound = true;
        }
      }

    }
  }
});


done(isDocumentFound);

Another point worth noting is that if you look at the trigger.event.eventType or the trigger.body.message.raw.events[].eventType they are high level event types, e.g. CREATED, DELETED, …

By parsing the trigger.body.message.raw.documents array you can see Message field provides more details, such as DirPurged, FileDeletedPurged, FileCreated and DirCreated. FileCreated and DirCreated are fairly straightforward and correspond to file and folder created events. However, DirPurged and FileDeletedPurged correspond to permanent deletion as shown below:

Permanently Delete

The detailed Syncplicity events can be found in the online docs. They will give you a much finer grained understanding of the cause of the event. It provides the list of vendorType (FileCreated, FileUpdated, DirDeleted…) and the related eventType (CREATED, DELETED, UPDATED, UNKNOWN).

Summary

In this blog post, we analyzed the Syncplicity event trigger payload to better understand how to parse the payload for our flow in order to create better flows.

Read about Using the Syncplicity Events API to get real-time visibility of events.