Subscribe to this blog to receive periodic product release announcements for developers and tips and tricks for using API.

Creating Physical Attachments

The Constituent API supports the ability to create attachments that link to external resources and has done so for a while now. However, link attachments aren’t always the best option. Sometimes you want to upload physical files such as images, PDFs, or Word files and add them as physical attachments. And since you don’t want to go to the trouble of uploading these files to a publicly accessible file hosting platform so that you can add them as link attachments, physical attachments have been a highly requested API feature.

 

That functionality is now available, and we have worked hard to get the process right from the start. Due to the nature of uploading local files and the existing Raiser’s Edge NXT architecture that the API is built upon, the process to create physical attachments is slightly more complicated than our normal create endpoints. Since physical attachments are such a highly requested feature, we thought a blog post would be a good opportunity to explain the intricacies.

 

For the most part, creating a physical attachment to associate with an action or constituent isn’t much different than creating a link attachment. However, because we use a third-party storage solution to host files, creating physical attachments requires a few additional steps. The basic workflow is as follows:
 

  1. Call our Document (Create) endpoint with the name of the file to upload to provision your document. This endpoint returns the  file_id, url, method, and  headers properties.
  2. Make a request to the url with the appropriate http method and headers specified in the file_upload_request and thumbnail_upload_request with the binary data for your file(s). This uploads the file to our third-party storage vendor.
  3. Call the create attachment endpoint and provide the file_name and file_id from our document provisioning endpoint along with any other desired properties to create a link between a parent and the attachment.

That’s it! With these three steps, you can upload a physical document and attach it to a parent through the API.

 

Now that you have a high-level overview of how to add physical attachments, let's go through a real world example to provide more context and explain any questions that might pop up.

 

Let’s say your application currently uses the Constituent API to provide quick contact information on constituents. The application has a list of constituents along with some basic information, and you want to upload images of business cards as a quick reference. To do this, we need a few things. First, we need the ability to create physical attachments, which we now have! We also need a way to identify attachments so that we can retrieve them through our Constituent attachment list (Single constituent) endpoint. A great option is the attachments tag functionality. You can create an attachment with a tag of “OurAppBusinessCard” where “OurApp” is the name of your app. Then in the app, you can filter on the list of attachments for a constituent where the tag is equal to “OurAppBusinessCard.”

 

Now that we have our design plan, let’s see what the actual calls would look like to make this happen. If a user uploads an image through your app’s front end and you have the image ready to attach, the first step is to make a POST request to our Document (Create) endpoint with the file_name in the body.

 

When you upload images, we strongly recommend that you also upload image thumbnails of 100px by 100px to enhance user experience when loading a list of preview images for attachments, as seen in the RE NXT Attachments tile. This requires a small bit of processing in your application to resize the image before uploading it. We’ve put together a few code samples to illustrate how to create the thumbnails. Here is the NodeJs code snippet that uses Jimp, a lightweight NodeJs image processing library:

 

var jimp = require('jimp');

 

jimp.read('https://github.com/recurser/exif-orientation-examples/blob/master/Landscape_2.jpg?raw=true')

   .then(function (image) {

       // resize and crop image to 100px by 100px keeping the image centered

       image.cover(100, 100)

           // apply any exif orientation transforms

           .exifRotate()

           .getBuffer(jimp.MIME_JPEG, function(err, buffer) {

               // make request using thumbnail_upload_request with buffer

           })

}).catch(function (err) {

   console.error(err);

});

 

The basics for thumbnail resizing are to scale and crop images down to 100px by 100px while keeping the focus on the center. In some cases, you may want to leave images at their original aspect ratio. In those cases, we recommend setting the max width and height to 100px and not cropping the final images. It’s also important to keep in mind any Exif orientation transformations that need to be applied.

 

To upload an image and provide a thumbnail, you need to provide the following request to Document (Create).

 

{

 "file_name": "businesscard.jpg",

 "upload_thumbnail": true

}

 

The endpoint returns a response similar to this:

{
    "file_id": "db0977bd-dc74-4560-bece-6e014593365d",
    "file_upload_request": {
        "headers": [
            {
                "name": "x-ms-blob-type",
                "value": "BlockBlob"
            },
            {
                "name": "x-ms-version",
                "value": "2015-12-11"
            }
        ],
        "method": "PUT",
        "url": "https://prodsarnxdocmn002blkbrdo.blob.core.windows.net/blackbauddocumentsvc/tenants/d69aa0de-73f5-4a81-a4b1-ff353509faec/documents/db0977bd-dc74-4560-bece-6e014593365d/demo.png?sv=2015-12-11&sr=b&sig=ZM72atvVZHhi8CI7uccr3isbOJ4Gq5Be4xUcKM5p6Do%3D&se=2018-05-21T15:47:37Z&sp=rw"
    },
    "thumbnail_id": "9c4b345b-211f-46b9-9535-d9f8f2bef80c",
    "thumbnail_upload_request": {
        "headers": [
            {
                "name": "x-ms-blob-type",
                "value": "BlockBlob"
            },
            {
                "name": "x-ms-version",
                "value": "2015-12-11"
            }
        ],
        "method": "PUT",
        "url": "https://prodsarnxdocmn002blkbrdo.blob.core.windows.net/blackbauddocumentsvc/tenants/d69aa0de-73f5-4a81-a4b1-ff353509faec/documents/9c4b345b-211f-46b9-9535-d9f8f2bef80c/thumbnail_demo.png?sv=2015-12-11&sr=b&sig=H3vNyNWKdqK%2BGiD7cKt8uOL4Z0QEmZCbsE8a821S%2BDc%3D&se=2018-05-21T15:47:37Z&sp=rw"
    }
}

 

Next, you need to upload the image and thumbnail to their respective upload URLs. For this request, you need the headers that were provided in the original Documents (Create) response. You also need an appropriate Content-Type header for the type of data to upload.
 

Using the headers above, make a request to the upload URL with the binary data of your image in the body of the request. The appropriate HTTP method is also provided in the Documents (Create) response.

 

After you do this for the file and thumbnail, you are ready to attach your file to your constituent. Call the Constituent attachment (Create) endpoint with the following:

 

{

 "name": "Business Card For Robert Hernandez",

 "parent_id": "280",

 "tags": [

   "OurAppBusinessCard"

 ],

 "type": "Physical",

 "file_id": "e8ce3494-d961-4eef-9938-acf0a2d9a831",

 "file_name": "businesscard.jpg",

 "thumbnail_id": "5b181d20-9b5f-44ab-8e63-46d14424dfe5"

}

 

The attachment type is set to physical to tell the API to look for the required file_id and file_name fields. Then the file_id, file_name, and thumbnail_id are specified using the response from the provisioning call made previously. Finally, we specify the “OurAppBusinessCard” tag to filter on it later.

 

The API response includes an ID for the attachment, and you’re ready to make a request to the Constituent attachment list (Single constituent) endpoint and filter tags for “OurAppBusinessCard.” The endpoint contains both the URL and thumbnail URL, which are direct links to uploaded files that can you can use for display purposes within your application.

 

That’s it, you’ve successfully integrated physical attachments into your application and provided a new robust experience for end users.


Hopefully this blog post answers any questions that you’ll have when you dive into adding physical attachments to your app. However, if you have any other questions, feel free to start up a discussion on the Community site. We hope you’re as excited as we are that this awesome functionality is finally available in the Constituent API.
Posted by Rob Dorey on May 18, 2018 1:02 PM America/New_York