Channel framework startup tutorial - Step 4: Post new resources to the origin service (Channelback)

In this step you will add an endpoint to post comments from Zendesk Support to WordPress. It will return the external id of the newly created WordPress comment back to Zendesk Support.

To make a comment using the WordPress REST API, the integration service needs the endpoint URL, user information, the comment text for the new comment, and the identifier of the comment the agent is replying to. We’ll handle this logic in the channelbackOptions function.

Add the channelbackOptions function to wordpress.js:

function channelbackOptions(metadata, parent, post, content) {  return {    uri: `${metadata.wordpress_location}/wp-json/wp/v2/comments`,    qs: {      parent,      post,      author:,      content    },    auth: {      user: metadata.login,      pass: metadata.password    }  };}

The main difference between this and pullRequestOption is the query parameters qs , on lines 5-8. channelbackOptions specifies the comment the agent wanted to post back content , the author of this new content author and the parent and post WordPress ids to tell WordPress to which comment the agent is replying.

Now you can add logic to post the new comment to WordPress using the request options.

In wordpress.js, add the channelback logic:

exports.channelback = (metadata, parentId, channelbackMessage, channelbackAttachmentUrls, res) => {  // Wordpress doesn't support adding attachments to comments out-of-the-box, so  // we'll append the URLs to the comment.  This is NOT A GOOD IDEA in general  // since the URLs may be secured or may not be available in the future.  // Normally, we'd download the attachment (using the push OAuth token), then  // upload it to the origin service.  if (channelbackAttachmentUrls != null) {    var arrayLength = channelbackAttachmentUrls.length;    channelbackMessage += '\n\nAttachments:'    for (var i = 0; i < arrayLength; i++) {      channelbackMessage += '\n' + channelbackAttachmentUrls[i];    }  }
  const postId = parseExternalCommentId(parentId).post_id;  const options = channelbackOptions(    metadata,    parseExternalCommentId(parentId).comment_id,    postId,    channelbackMessage);  let bodyInfo;  let errorDescription;    options,    (error, wordpressResponse, body) => {      if (!error && wordpressResponse.statusCode === 201) {        // Successfully created WordPress comment.  Return the ID of the new        // comment.        bodyInfo = JSON.parse(body);        res.status(200).send({          external_id: externalCommentId(                        parseExternalCommentId(parentId).link,              ,                        postId)        });      } else if (wordpressResponse && wordpressResponse.statusCode) {        // WordPress returned an error        errorDescription = {};        if (body) errorDescription = { error_info: body };        res.status(wordpressResponse.statusCode).send(errorDescription);      } else {        // Networking error or similar- no response        // 503 == service unavailable        res.sendStatus(503);      }    }  );};

Lines 2-13 report any channelback attachment URLs that were POSTed to the integration. In a robust integration, these URLs would be used to download the attachments and then upload them to the origin system. However, Wordpress doesn't support attaching files to comments, so we will not implement that logic. A production oriented implementation of the Wordpress integration would probably not support attachments at all. Instead, the manifest would indicate that attachments are not supported.

Line 15 parses the external id to get the post id we are going to reply to. See the External IDs for more information. Lines 16-20 prepare the parameters which will be POSTed to the WordPress API. Line 26 posts the request to WordPress. Similar to the pull implementation, line 26 passes a response handler function to the post call.

Lines 28-36 are invoked when WordPress returns HTTP status code 201 (Created). The handler parses the response from WordPress on line 30, creates the external id for Zendesk Support on lines 32-34, and returns 200 (OK) to Zendesk Support with the external id. Zendesk Support records the external ID. If it sees this external ID in a future poll, Zendesk Support will not import it again.

If WordPress returns an error or the network request times out, lines 38-41 and 43-45 return appropriate error codes back to Zendesk Support. Read the pull request documentation on how Zendesk Support handles errors from integration service.

To recap: In this step you added logic to turn Zendesk Support comments into WordPress comments by generating the appropriate WordPress API parameters. You also generated an external ID for the WordPress comment.

External IDs

Here is the explanation of what does external ids mean in the Channels Framework. Zendesk Support uses external ids to determine if an external resource has been previously imported. Zendesk Support also uses external ids to specify which external resource is being replied to. The external id is created by the integration service, and each external resource must have a unique external id.

Integration services identify resources by “external id.” In Zendesk Support, the term “external id” refers to identifiers used by the integration service itself, which may or may not match IDs in the origin system, and will not match IDs inside of Zendesk Support.

For example, suppose you were creating an integration service for Stack Overflow. Stack Overflow might have a question with ID 1234, and that question might contain a comment with ID 5678. Stack Overflow might not guarantee that comment IDs are globally unique. The id 5678 might not be enough to uniquely discover a comment in Stack Overflow- you also need to know that comment 5678 is on question 1234. You might form an external ID for a Stack Overflow comment by concatenating the comment ID and the question ID with a separator, like “1234:5678”. Comment ID 5678 in Stack Overflow is represented by external ID “1234:5678” in the integration. In turn, that Stack Overflow comment might be imported into Zendesk Support as comment 9876. The same Stack Overflow comment has 3 IDs- it’s called 5678 in Stack Overflow, it’s called “1234:5678”, and it’s called comment 9876 in Zendesk Support. Zendesk Support never needs to know about the ID in Stack Overflow- it only deals with “external IDs” (like “1234:5678”), and Zendesk Support internal IDs.

This tutorial integrates with WordPress, and the external ID is formed by concatenating the post id, comment id and the post link, delimited by colons (for example, 8:2:http://localhost:25789/index.php/rick-astley-50/#comment-2 ). We will discuss later why the integration service needs the link in external id.

Read the externalCommentId and parseExternalCommentId functions to see how our integration service handles external ids.

Now you can verify that your implementation works by curl'ing both the pull and channelback endpoints. (Note: This assumes you have completed step 2.)

Make sure there is at least one comment in WordPress. Restart the server, set the WordPress variables , and run this curl command to pull. You’ll use the results to get the external id of a WordPress comment, which you’ll pass to the channelback command.

curl -d "metadata={\"password\":\"$WORDPRESS_PASSWORD\", \"login\":\"$WORDPRESS_USER\", \"wordpress_location\":\"$WORDPRESS_URL\",\"author\":\"1\"}&state={}" http://localhost:3000/pull

The result should include an external ID for a WordPress comment. After that, run this curl command to channelback:

curl -d "metadata={\"password\":\"$WORDPRESS_PASSWORD\", \"login\":\"$WORDPRESS_USER\", \"wordpress_location\":\"$WORDPRESS_URL\",\"author\":\"1\"}&parent_id=<external id of the wordpress comment to reply>&message=<message>" http://localhost:3000/channelback(Add a message and set parent_id with the external_id you get from the pull command)

You should get a response like this:


Also, if you go to the WordPress UI, you should see the new comment created by the channelback.

Continue on Channel framework startup tutorial - Step 5: Connect the integration service to Zendesk Support - Part 1 (Admin UI, Manifest) .