How a non-engineer used Webhooks and APIs to make something awesome

This guide was written by our wonderful customer Elizabeth Toy from Gloo.

 

Disclaimer: so I refer to myself as a non-engineer. And I am not one, in the truest sense. But I do work with a bunch of them and have learned enough to get by. I also took some classes in college but have not retained any of it, nor is it even something I’d use (VBA, ha).

 


I work on the Support team at my company. Our engineering team decided to make the switch to Clubhouse. It promised Zendesk integration—great! I didn’t have time to check it out in depth, but my manager told me to trust him, that it was better than our last system’s Zendesk integration.

Fast forward to all our engineers clamoring to use the new tool and wondering when we’d be sending bugs their way from Zendesk. Time to set this up. Should be easy right?

Nope. Wrong.

The integration consists of a Zendesk app. Nothing in Zendesk apps is trigger-able, action-able, filter-able, etc. in Zendesk or Zapier (the two tools I can usually count on to make things do what I want). We would have to manually select to add a card to Clubhouse. Manual processes have the potential for human error.

So I checked Zapier. Clubhouse has some actions available there (by invite). But no triggers (no bueno) and the only action is to Create a Story. So that’s actually worse than our last system’s Zendesk integration.

What to do? APIs and Webhooks!

Clubhouse’s API documentation saved the day, along with Zapier’s Webhooks app. Fair warning: this is about to get crazy.

 


Zendesk → Clubhouse Zap

1. Set the Zap’s trigger to be a new Zendesk ticket.

2. Add an action using Formatter by Zapier to work with Text to Replace a specified value in a given input.

In our case, I set the input to be the Zendesk ticket description and have it find quotation marks () and replace them with \”. (Do this if you don’t want errors later! If you have a quotation mark in your Webhook later, it’ll error.) Do this for any text that you’ll be sending into Clubhouse that could potentially have a quotation mark in it. I did it for the Zendesk ticket subject and description.

3. I added some paths because there are different ticket conditions that would send it to different boards (like if the ticket is an issue on web, it goes to the Web team’s board). Set these up after the formatting actions if you need to send to different Clubhouse boards or do something similar.

4. Add an action using Code by Zapier to Run Python.

  • Add one Input Data item called owner_email with the Assignee Email from the Zendesk ticket
  • The code will look something like this (please look at the screenshot below though to get the appropriate line indentations! Zapier is very particular about running this with the correct indentations):
    import argparse
    import requests
    session = requests.Session()
    session.header = {‘Content-Type’ : ‘application/json’}
    get_members_url = “https://api.clubhouse.io/api/v2/members?token=
    [YourTokenHere]
    members = []

    author = “
    [BackupAuthorIDHere]

    while get_members_url:
    response = session.get(get_members_url)
    if response.status_code != 200:
    print(‘Failed to get members with error {}’.format(response.status_code))
    exit()
    members = response.json()
    for member in members:
    if member[‘profile’][‘email_address’] == input_data[‘owner_email’]:
    author = member[‘id’]
    return {
    ‘author’ : author
    }

Replace any non-bold text above with your own inputs. (You need to generate a Clubhouse API Token.)

 

                            Python Code to Get Clubhouse Member ID

 

 

5. Add an action using Webhooks by Zapier to fire a Custom Request.

  • The Method is POST.
  • The URL is https://api.clubhouse.io/api/v3/stories?token=[YourTokenHere]
  • The Data will look something like this:
    {
    “description”: “
    Description of the card goes here. I used the Zendesk ticket description from step 1 / trigger.”,
    “name”: “
    Title of the card goes here. I used the Zendesk ticket subject from step 1 / trigger.”,
    “project_id”: 1234,
    “story_type”: “bug”,
    “requested_by_id”: “[author output from previous Python step]
    “labels”: [
    {“name”: “
    label 1”},
    {“name”: “
    label 2”},
    {“name”: “
    label 3”}
    ],
    “external_id”: “
    [zendeskTicketID]”,
    “external_tickets”: [{
    “external_id”: “
    [zendeskTicketID]”,
    “external_url”: “
    https://[subdomain].zendesk.com/agent/tickets/[zendeskTicketID]
    }]
    }

Replace any non-bold text above with your own inputs. Or check out Clubhouse’s Create Story API documentation for available parameters and make a custom request to fit your needs. To get the Project ID, I recommend a quick GET request using the List Projects API endpoint.

  • The Headers are Content-Type application/json

6. Continue on through and test the Zap.

7. Add an action using Zendesk to Update a Ticket. Use the ticket ID from the Trigger step in the Zap and have it post a private note to say the card was added and include a link to the card.

I also have a custom field in Zendesk to capture the URL of any corresponding story, card, task, etc. in other systems, and I also set that field to the card URL in this final step.

 


Clubhouse → Zendesk Zap

1. Set the Zap’s trigger using Webhooks by Zapier and a Catch Hook trigger.

Zapier will generate a custom webhook URL for you to send requests to. Copy that URL. In Clubhouse, you’ll have to set up an outgoing webhook using that Zapier URL. Once you’ve set it up, test the webhook to get some samples.

2. Add an action using Formatter by Zapier to work with Text to Split Text to separate the Actions data from the Webhook to new lines using [:newline:] with the Segment Index of All (as Separate Fields).

3. Add a Filter step to only continue if the Actions data does not contain the string story-task.

In our case, any event related to Story Tasks aren’t relevant, so we can filter them all out. (The order of steps 2/3 isn’t particularly important.)

4. Add an action using Formatter by Zapier to work with Text to Extract Pattern in a specified value in a given input.

In our case, I set the input to be the Catch Hook “Actions” portion of the response and I have it look for the pattern entity_type: story\nid: (\d+)

5. Add a Filter step to only continue if Output from the previous step Exists.

6. I set up different paths based on the type of update (Lane Changes, Comments, and Archived/Deleted) but for my own sanity, will only explain how I set up Comments. But if you want to do it similar to how I did, add your paths now.

7. Set up a filter (or path rule) to only continue if the Catch Hook “Actions” portion of the response contains entity_type: story-comment and the “Actions” does not contain action: delete

8. Add an action using Webhooks by Zapier to fire a Custom Request.

9. Add a Filter step to only continue if Output from the previous step Exists.

For an Archive/Delete path, you should omit steps 10/11 as it will error (there’s no card to get). And in the steps following, you would use the story ID rather than the external ID. (You could technically omit steps 10/11 for all paths, but the external ID is a more reliable source of the ID of the ticket to update.) Also for the Archive/Delete path, make sure to filter if the “Actions” portion of the response does not contain story-comment. Comment deletions would otherwise cause a false positive for a Story being deleted.

10. Add an action using Zendesk to Find a Ticket. For the Query, use the External ID item from the Custom Request in step 8.

For an Archive/Delete path, you would use the query: https://app.clubhouse.io/[ClubhouseProject]/story/[storyID]” or, if you have a custom field to capture the URL (see step 6 in Zendesk→Clubhouse above) then you should use the query 

fieldvalue:“https://app.clubhouse.io/[ClubhouseProject]/story/[storyID]”

11. Add a Filter step to only continue if ID of the ticket from the previous step Exists and the Status of our ticket from the previous step Does not exactly match Closed.

12. Add an action using Webhooks by Zapier to fire a Custom Request.

This gets the profile information for the commenter.

13. Add an action using Webhooks by Zapier to fire a Custom Request.

This gets the comment information.

14. Add an action using Zendesk to Update a Ticket. For the Ticket field, choose the option to Use a Custom Value and for the Custom Value for Ticket ID use the External ID from the Custom Request in step 8.

 

Have it post a private note that says something like this: 

[commenterName] commented on Clubhouse card [storyID]: [commentText]

Fill in the commenterName using the Custom Request in step 12 “Profile Name” portion of the response. Fill in the storyID using the output from step 3. Fill in the commentText using the Custom Request in step 13 “Text” portion of the response.


 

If you made it to this point, kudos to you. What I explained above is a pretty specific use-case, but it’s meant to show you that with awesome APIs and a little webhook magic, you can do a whole lot.

Maybe you want to have comments on Clubhouse cards post to a Slack channel. Easy! Take the Clubhouse→Zendesk steps and omit step 5–7 and change step 11 to post to a Slack channel instead of update a ticket.

Once you get one thing set up, you’ll realize all the data you have to work with and will want to keep going. Especially in Clubhouse’s case, with so many APIs available, you can GET and POST until you’re blue in the face.

Didn't find what you were looking for?

New post
Would you like to add your +1 to this post?
1 out of 1 found this helpful

Comments

4 comments

  • Comment actions Permalink

    As a completely unbiased user, I think this is awesome! 

    1
  • Comment actions Permalink

    Interesting experience, thanks for sharing. I want to add that webhooks are custom HTTP callbacks. Usually they are triggered by some event, for example, a code submission to a repository or a comment posted on a blog. When this event occurs, the origin site sends an HTTP request to the URL specified for the webhook. Once configured, events will be sent to the URLs of your choice and can be used to build apps for various purposes such as notifications and reports. You will need to set a separate URL for the webhook to send events to, this can be anything The url you want. Webhook data is sent as JSON in the body of the POST request. The events sent to the webhook are described in the developer documentation. I gathered this information from Twitter posts in which experienced engineers talk about setting up webhooks. There you can find a couple of dozen posts on this topic and I noticed that mostly such posts are published by accounts that have about 52 thousand subscribers! I am sure this is because their owners used the services of https://viplikes.net/buy-twitter-followers to quickly increase their number.

    0
  • Comment actions Permalink

    Interesting, thanks for sharing!

    0
  • Comment actions Permalink

    Interesting experience, thanks for sharing. I want to add that webhooks are custom HTTP callbacks. Usually they are triggered by some event, for example, a code submission to a repository or a comment posted on a blog. When this event occurs, the origin site sends an HTTP request to the URL specified for the webhook. Once configured, events will be sent to the URLs of your choice and can be used to build apps for various purposes such as notifications and reports. You will need to set a separate URL for the webhook to send events to, this can be anything The url you want. Webhook data is sent as JSON in the body of the POST request. The events sent to the webhook are described in the developer documentation. I gathered this information from Facebook posts in which experienced engineers talk about setting up webhooks. There you can find a couple of dozen posts on this topic and I noticed that mostly such posts are published by accounts that have about 52 thousand subscribers! I am sure this is because their owners used the services of https://soclikes.com/buy-facebook-likes to quickly increase their number.

    0

Please sign in to leave a comment.