EventBrite Integration using their webhook and HTTP Authentication Request Header

In my previous blog post I outlined how we can periodically retrieve EventBrite attendee details from an event using the Recurrence trigger and the GET HTTP step.

The problem with that solution is that you’ll need to create a flow for each individual event and the attendee details are not updated in real-time. I then revisited the EventBrite webhook function to see if there’s a way for me to setup a single generic Flow that captures EventBrite attendee registrations, check-ins and cancellations. I wanted the single flow to be usable for all events and provide the details in real time to Dynamics 365. I also wanted to authorise access to their API using their recommended “HTTP Authentication Request Header” method as opposed to including the OAuth token in query string as a parameter.

Figure 1. The EventBrite API documentation recommendations for authenticating with the EventBrite API

In this blog post I’ll go through step by step how to setup a reusable flow that accepts the EventBrite webhook JSON payload, authenticates and then dynamically create event registrations and allocate them to the correct event. Below is a sample flow I’ve created to handle EventBrite webhook JSON payloads, which I’ve broken down into 7 steps.

Figure 2. Image of what the Flow should look like at the end to handle attendee registrations and check-ins dynamically

Step 1. Creating the Flow with trigger to accept webhooks

The first step is to create a Flow using the “When a HTTP request is received” trigger. This will generate the URL endpoint for which to send EventBrite webhook payloads to. I’ve written about what this trigger does in this blog post here.

Step 1.1. Creating the webhook in EventBrite

Once we have the URL endpoint, we can then create a webhook in EventBrite to send real-time events to Flow. As we only want to track attendee details, we’ll only check the “attendee.updated” webhook action (for more information on how to create a webhook in EventBrite click here). You can also narrow down the events in which the webhook triggers on by selecting a test event but my Flow will handle for all events so long as the events are created as a record in Dynamics 365.

Figure 3. Creating a webhook in EventBrite

Step 1.2. Creating the API Key in EventBrite

Once you have the webhook created. You will then need to create an API key (or use an existing key) in EventBrite. The key will generate a “Private token” which you will use to authenticate. To learn how to create an EventBrite API key click here.

Step 2. Store Generated API Key

Step 2 is really an optional step as I use the “Initialize Variable” step to store the generated EventBrite API token as a variable to use in the 3rd step as authorization. You can alternatively just copy in the API token in the 3rd step within the header area.

Figure 4. Storing the API key/token as a variable to use in the 3rd step. This step is optional

Step 3. Retrieve Attendee Details from EventBrite API

When an EventBrite webhook is triggered, the JSON payload that it sends does not include any attendee data. It instead sends within the JSON payload a “api_url” value which is the API endpoint to retrieve the actual attendee details.

Figure 5. The “api_url” value which is the actual endpoint which the Flow needs to perform a GET request to retrieve that specific event attendee detail

The “api_url” will then need to be called using a “HTTP” GET step along with the OAuth protocol for authentication in the “Headers” section of the “HTTP” step. Note in the below screenshot I’ve used the “api_url” dynamic content created by the webhook JSON payload as the endpoint and the API key variable I used to stored the key/token created via EventBrite to authenticate/authorize the GET request. This is using the “HTTP Authentication Request Header” method as opposed to the “Query String Parameter” method used in my previous blog post (more information can be found on the EventBrite authentication page).

Figure 6. The GET request using the provided API endpoint from the webhook and the “HTTP Authentication Request Header” method to authenticate the request

Step 4. Parse returned JSON into Dynamic Content

Once the GET request has retrieved that individual attendee detail, you will then need to use the “Parse JSON” step to parse the returned JSON into usable dynamic content. You should poke the Flow with a test registration to then get the sample payload to use for auto-generation of the JSON schema.

Figure 7. Parse the JSON returned from the previous GET request into usable Dynamic content

Step 5. Retrieve Event based on EventBrite Event ID

This step will use the list record step to retrieve Dynamics 365 event record using the unique EventBrite event ID. This allows in the future for this single Flow to funnel all attendee registrations/check-ins from all events into Dynamics without the need to create a Flow for each event in EventBrite.

You will be using the retrieved unique Dynamics 365 event record ID to set the lookup value of the Event Registration entity’s Event field lookup.

Figure 8. Retrieve the Event record in Dynamics 365 using the unique EventBrite event id. The retrieved result will be used to set the Event lookup field on the Event Registration record

Step 6. Retrieve Event Registrants

Step 6 will also use the “list record” flow step to retrieve Event Registrant record from Dynamics 365. This is used in the next step to perform a conditional check to see if the event registration record already exists in Dynamics 365 so the Flow know whether to create a new event registration record or update the existing record. This utilises the unique attendee id EventBrite assigns for each registered attendee (which is also passed to Dynamics as a field value).

Figure 9. Retrieve event registrants to use as a check to see if they already exist in Dynamics 365 or not. This helps the Flow in determining whether to create new or update existing event registrant

Step 7. Conditional Step to determine whether to create new event registration or update existing

The final step is a conditional one. It utilises the list record step for Event Registrations to perform a conditional check whether a new event registration record should be created or an existing one should be updated. For more information on how to setup the condition, see my first blog post on EventBrite integration using Flow.

Figure 10. Conditional step to check whether to update or create new event registrant

Also of note is that the Event lookup field in the Event Registration entity record is set to the dynamically retrieved event record in step 5.

Figure 11. The “Event” lookup field is set to the retrieved event record in step 5

This Flow used in conjunction with the “When a Event is created” connector for EventBrite (which creates the event record in Dynamics) will allow you to setup a webhook trigger to this flow for all attendees registering for all events as it will now dynamically handle the creation and update of event registration records as well as dynamically setting the event lookup field to the right event.

Figure 12. You can now create a webhook in EventBrite that triggers for all attendee registrations and updates for all events, which will funnel into a single Microsoft Flow

Webhook, Microsoft Flow and Dynamics 365

I’ve been playing around with Microsoft Flow and it’s really exciting stuff the things you can do with some of the out of the box flow triggers.

Often times with Microsoft Flow we tend to try and find existing connectors between two programs and use them to create the integration. As Flow is quite new to the game, there isn’t as many connectors for Flow compared to Zapier as an example, but this gap can be bridged by tools Flow already provide that essentially allows it to connect with almost any software (so long as that software has an API).

figure 1. The amazingly powerful suite of Microsoft Flow out of the box trigger/actions that can be used to integrate almost any system together

We saw in my EventBrite and Dynamics 365 integration blog post how to use the Recurrence trigger and HTTP trigger/action to call the EventBrite API endpoint and retrieve a list of event attendees periodically to create/update event registration records in Dynamics 365.

Another common requirement I’ve come across is usually to integrate a webform like Gravity Forms, Typeform or Unbounce to Dynamics 365 and creating a lead or other record type.

In this blog post we’ll look at using the “When a HTTP request is received” trigger to receive webhook JSON payloads, which we can then use to create/update Dynamics 365 records.

What is a webhook?

Webhooks are a method for an app to provide real-time data to other apps by way of an automated message triggered by an event. The message usually delivers a JSON payload to a unique URL of the receiving app. As webhooks are triggered by events at the source app, the payload delivered is light-weight and in real-time.

Most cloud base softwares now have webhooks as a method to deliver information to another app. Today we’ll look at Gravity Forms (Grav Form) which is a commonly used plugin for WordPress.

Setting up Flow to receive a Webhook

The first step is to setup a Flow with trigger of “When a HTTP request is received” This trigger type generates a URL endpoint to receive the webhook payload.

Figure 2. The trigger which will receive the webhook JSON payload

Note that:

  1. The “HTTP POST URL” will only generate once you’ve saved the flow
  2. We will leave the JSON Schema blank for now and poke the flow with a test JSON payload from our Grav Form to auto-generate the schema using the “Use sample payload to generate schema” button.

Once the trigger is setup, you’ll then add in a “Compose” step temporarily and input the “Body” dynamic content into the “Inputs” area. This is to allow the Flow to be saved and generate a “HTTP POST URL”.

Figure 3. Adding the Compose step allows for the Flow to be saved, which will then generate the URL endpoint to send the webhook JSON payload

Once these steps are completed, you can now setup the webhook on your Grav Form.

Setting up the webhook in Grav Form

The first step in setting up the Grav Forms webhook add-on in WordPress. To install this, follow the instructions outlined on the Grav Forms website.

After installing the add-on you will then need to configure the webhook for your Grav Form. You can find more details on configuring the webhook triggers here. Below is an example of a webhook trigger setup in Grav Forms.

Figure 4. Sample webhook setup for Grav Forms

The “Request URL” section is where you will paste the generated URL from your Flow setup previously.

Note that the Flow generated URL has a section that comes out like:

%2Ftriggers%2Fmanual%2Frun

You will need to replace “%2F” parts of the URL with “/” as Grav Form does not accept endpoints with that type of format.

Once the webhook is setup, it is now time to test it by submitting a dummy record through the Grav Form.

Poking the Flow with the webhook and setting up the JSON schema

To poke the flow with a sample webhook JSON payload we simply have to do a dummy submission to the Grav Form. This both provides a sample JSON payload for Flow to generate the schema and also tests that the webhook is triggering properly.

Once you have submitted a test. Go into your run history and open the run that was triggered by the test.

Figure 5. Open the test run in Flow

Note the Body output that was received by URL. This is the sample JSON payload from the webhook. You can now use this to automatically generate a JSON schema.

Figure 6. Grab the sample JSON payload from your test to use in generating the JSON schema

Paste the sample JSON payload into the trigger, which will automatically generate the JSON schema. This will then provide you with a list of dynamic content variables you can use in the Dynamics 365 connectors to create, get and list records (e.g. Create lead when someone submits a Grav Form).

Figure 7. Paste the sample JSON payload to generate a JSON schema

Note that Grav form’s JSON payload has the fields identified by the ID number instead of the label. You will need to check which number corresponds with which fields in order to utilise the dynamic content.

Figure 8. A sample flow utilising webhook dynamic content from Grav forms. Note that dynamic content are labeled by their ID number as opposed to the actual name

Good to know: Dynamics 365 organisation database settings

The “Good to know” posts will cover useful features and/or nuances of Dynamics that system administrators should be aware of. My first post of this category will cover great feature called the “organisation database settings” ( also known as OrgDBOrgSettings). The settings allows admins to customise specific database settings previously only available to on-premise deployments. It contains a list of settings which control specific areas of Dynamics 365 and this post will go through how to install “Organization Settings Editor” a few useful control settings and what they do.

Installing the “Organization Settings Editor” solution

To use the OrgDBOrgSettings you’ll need to install the “Organization Settings Editor” solution which is available for download at this GitHub repository. After downloading and importing the managed solution into your Dynamics 365 tenant, you can then double click on the solution to open the setting editor window.

Figure 1. The Organization Settings Editor from the installed managed solution

The the components of the editor are as followed:

Name – The name of the database setting and an idea of what it controls

Default Value – The default value of the setting if no value is set manually by the CRM Administrator

Current Value – The current value set by the CRM Administrator. If the setting has not been touched then it would generally say “not set”

Type – The value type you should enter to change the setting. As an example a boolean type means when you set the value it can only either be “false” or “true”

Min – The minimum value you can set to this setting. Usually only applies to settings with “Type” of number as it outlines what’s the maximum and minimum number you can set to this setting

Max – The maximum value you can set to this setting.

Action – Click this to commit the changes

Support Url – The url to either the KB article or other supporting document outlining what this setting does.

Setting Description – When you select one of the settings, the setting description will appear and provide more information on what the setting does as well as what each of the values you set will do

How to change the database settings

To change the respective database setting:

  1. find the setting you would like to change (ensure you read the “Setting Description” and corresponding KB article before making any changes) and double click the row.

  2. This will then open the editor to make changes to the setting. Type in an accepted value for that setting and click “Update”. A pop-up will come up asking whether you want to proceed with the changes to your database setting. Select OK to commit the changes to Dynamics.

Useful database settings

TrackAppointmentsFromNonOrganizer

This function resolves a annoyance quite few CRM Administrators had regarding the Dynamics 365 App for Outlook and the tracking of appointments.

You’ll notice that when trying to track an appointment created by another user within your organisation who also is a CRM user that it won’t allow you to track their appointment in Dynamics. You instead get the “You can’t track this meeting because it was organized by another user”.

Figure 2. The default setting for Dynamics is to not allow one CRM user to track appointments created by another CRM user

You can allow this form of tracking by going to the database settings, finding the setting called “TrackAppointmentsFromNonOrganizer” and setting the value to “true”.

Figure 3. Turning on the setting to allow appointment tracking by non-organisers

You can now track appointments even if you’re not the organiser in your organisation.

OverrideTrackInCrmBehaviour

This setting forces the users on Dynamics 365 App for Outlook to set a regarding value for any activities tracked from Outlook.

This is quite handy when activities need to be associated to a record for reporting purposes and for the CRM to force users to set regarding as a behaviour.

Integrating EventBrite to Dynamics 365 Using Flow

Hi everyone and welcome to my inaugural blog post on everything Dynamics and Power BI.

My first post will be on integrating EventBrite to Dynamics 365 using Microsoft Flow. This article will be an add-on from an already amazing post written by Glenn Turnbull which you can read about here. In it he talked about using the new out of the box Microsoft Flow connectors for EventBrite to push events and event registrations back into Dynamics as either leads or contacts.

For those of you who don’t know what Microsoft Flow is, it’s software that allows the creation of automated workflows across multiple platforms. It’s basically Microsoft’s answer to Zapier, Automate, Skyvia etc. It includes a range of out of the box connectors for various cloud base applications and softwares including EventBrite.

The connector provided in Flow allows for two types of triggers:

  • When an event is created – Triggers the workflow to pass EventBrite event details to other applications
  • When an order changes – Triggers the workflow to pass EventBrite order details to other applications when the order changes or is created
Figure 1. The two out of the box EventBrite triggers for Microsoft Flow

We will be using the first trigger to automatically create an event in Dynamics when an event is created in EventBrite. The second trigger for EventBrite order, while it’s used in Glenn Turnbull’s blog to capture “event attendees”, it does have limitations due to the way EventBrite structures its data. Whilst the order table does store basic details of who ordered the “tickets” it does not provide any information on attendee or attendance data.

You can assume that the person who’s ordered the ticket will attend, but if they’ve ordered more than 1 ticket, it will only bring in 1 event registration record regardless of how many tickets/attendees are included in the one order.

You can see in the below screenshot that the management of EventBrite order details and attendee details are done separately on the Developer API documentation and there are two different API endpoints for retrieving event orders and event attendees.

Figure 2. API documentation on retrieving attendees and orders from EventBrite

This indicates that using the out of the box Flow trigger of EventBrite Order will not accurately reflect the true attendee numbers and details. What it also will not do is when checking in those attendees, it will not update registration status.

Thankfully Microsoft Flow provides several trigger methods that allows you to connect directly to the EventBrite API to retrieve the attendee data. Whilst it means the status and registrations won’t come in real-time, it does mean you can pull all event registration data automatically from EventBrite into Dynamics using Flow.

Before we look at Microsoft Flow and how it can pull the EventBrite data from its API we’ll first create our required Event and Event Registration entities to store event details and registrant details. I won’t cover how to create the entities or what fields you’ll need to create as you can again read about this on Glenn Turnbull’s blog post. I’ve put together an Entity Relationship Diagram outlining the key lookup fields that need to be created so that correct table relationships are in place.

Figure 3. Entity Relationship Diagram for the newly created Event and Event Registration entity

Note in the above diagram that I’ve made some field additions to the entity different to Glenn’s outline:

  • Added an account lookup field to form a many to one relationship between Event Registration to Account. This helps future reporting requirements, customisations and allows you to include a sub-grid in Account for event registrations.
  • Added a campaign lookup field to form a many to one relationship between Event and Campaign. This is done again for reporting purposes and to attribute events back to a specific marketing campaign. You can also skip creating the Event entity altogether and use the Campaign entity to store event details.

Setting up the Microsoft Flow for EventBrite

Flow to create events in Dynamics

What you will first need to do is setup an event creation flow to automatically create an event in Dynamics when an event is created in EventBrite. This process is quite straightforward as the out of the box connector does this quite well. Below is a screenshot of my setup. One thing to note is that all it does is create an event when you create the event in EventBrite. It does not update the event details in Dynamics if you update the event details in EventBrite. In this regard pay attention when cloning events as it may inherit some of the cloned event data like event time and description.

Figure 4. The flow used to create an event record in Dynamics

Flow to Create and update event registrations

To push the event attendee details back into Dynamics 365 is a bit trickier as the out of the box connector only retrieves EventBrite orders and not attendees. This means that it also does not track if an attendee has actually checked into an event or not on the day.

In order to get around this issue, we look to using 3 out of the box functions Microsoft Flow provides to connect with the EventBrite API, retrieve the JSON payload from a GET request to the attendees endpoint, parse the JSON and use it to create or update Event Registration records in Dynamics.

Figure 5. A sample flow to retrieve EventBrite attendee details via the API and use them to create and update records in Dynamics 365

I’ve highlighted the 3 Flow functions that will work together to retrieve the attendee JSON payload for use in creating Dynamics 365 records:

Recurrence – This is a commonly used trigger to time when and how often a Flow runs. As we’ll be using a GET request to the EventBrite attendee API endpoint we need to use this as a trigger to specify how often Flow should trigger the GET request. Note that you can skip Recurrence as a trigger and directly use the HTTP function as the trigger to get data. If you do use HTTP without a recurrence trigger, it will trigger the call every minute, which will use up your monthly flow allowances quite quickly.

Figure 6. Using the Recurrence trigger and setting it to run every 12 hours is a better use of your monthly flow allowance

HTTP – The HTTP function of Flow allows you to use any standard HTTP request on a web API endpoint (including the ability to add authentication token into the header). EventBrite has two authentication methods and for the case of simplicity I chose to just include the secret key generated in EventBrite into the URL. More information on how to generate your EventBrite API key can be found here.

Figure 7. Using the HTTP request, it will make a GET request to the EventBrite API endpoint and return in JSON event attendee details.

As you’re authenticating using the secret key directly in the endpoint URL. EventBrite will immediately return the attendee details in JSON. The next step will then be to use the Parse JSON function of Flow to get it in a format usable in Flow actions.

Parse JSON – This function will then take the JSON payload in the body and parses the JSON so that it’s usable in other Flow actions. You will need to specify the JSON schema which you can generate automatically by pasting a sample JSON payload.

Figure 8. Parse JSON used to parse the JSON sent through via the HTTP request

You have now completed all the steps to retrieve attendee details from the EventBrite side. The next several Flow steps will now be creating or updating Dynamics 365 event registration records based on what is retrieved from EventBrite. I’ll go through each flow step and what they do.

Figure 9. First portion of the flow steps to updating Dynamics 365 with EventBrite attendee information

Get record – This is a Dynamics 365 flow connector function to retrieve a single record from Dynamics 365. We will use this to get the event you want to link your event registrants to. You’ll need to specify your Dynamics 365 tenant, entity and grab the record GUID. This will take the specific event record and store it as a variable/parameter to be used in the later steps of the flow similar to what the Parse JSON function did for the retrieved attendee details of the EventBrite event.

Figure 10. Get record flow step. Remember to add in the GUID of the event record in the Item identifier and not the name of the event

TIP: A handy tool you can use to automatically grab the Dynamics 365 record ID of the record you’re viewing is a Copy Record Id bookmarklet. I’ve provided a link to a list of handy bookmarklet JavaScript functions which you can save into your browser bookmark. When you select the respective bookmarklet in Dynamics it will perform the function.

List records – Similar to the Get record function, List records will retrieve a list of Dynamics 365 records from a specified entity and based on specific filter criteria. You’ll need to familarise yourself with Dynamics 365 query operators and when specifying a field you must use its schema name. The below screenshot shows how I’ve configured the List records step to retrieve event registration records by the EventBrite attendee ID which is unique for each attendee. The ID is parsed from the JSON payload collected from the GET request to the EventBrite attendee API endpoint. When creating the entities needed to store EventBrite event and event registrants, you would of already created a field in Dynamics to hold the Event Registration attendee ID from EventBrite. This will be the field you’ll use in your Filter Query. My field was called new_eventbriteid. Note how I’ve written out the filter query and how the id paramter is surrounded by single quotes.

You will need to add a filter criteria similar to the below:

new_eventbriteid eq '@{items('Apply_to_each_2')?['id']}'
Figure 11. The List record step of the flow will retrieve a list of event registrants based on a specific filter query

Note that when you add in the list record step and filter query, Flow will automatically surround that step with a Apply to Each box. This is because the List record function will return multiple values and any subsequent steps afterwards will apply to each record returned. The Output that you’ll need to use will be “attendees”.

Figure 12. Apply to each function will run subsequent flow steps against every attendee retrieved from EventBrite

Condition – Now that you set the step to retrieve a list of event registrants from Dynamics 365 you’ll need to add in a conditional step to determine what needs to be done if Dynamics returns a value and what needs to be done if Dynamics doesn’t return an event registrant value. The idea will be to perform two different actions based on those conditions:

  1. If Dynamics 365 was able to retrieve an event registrant based on the EventBrite attendee ID then it should update that record with any new information updates on the EventBrite side. This is mostly used for checking whether the attendee has checked into the event on the day and flag the attendee status in Dynamics to “Checked-In” when they do.
  2. If Dynamics 365 is not able to retrieve an event registrant then it should create a new event registrant (passing through first name, last name, ID, email, mobile number etc.)

Glenn Turnbull’s blog provided a great condition formula that checked if the list does not return any value for a specific EventBrite attendee ID and if yes create new record and if no update the existing record.

Unfortunately Microsoft removed the ability for users to custom write their condition expressions using the Advanced Mode since he published his blog post. Fortunately you can do something similar with the new UI. Below is a screenshot of how I’ve set out my condition.

Figure 13. The condition I put in place to check if event registrant already exists in the CRM

You now have to set the condition as a formula with an equal to operator set to “true”. The formula for the first part of the condition is:

 empty(body('List_records')?['value']) 
Figure 14. First part of the condition

You set the operator to “is equal to” and then set the second part of the condition to the “true” function. Now if the condition returns to be not “true” the flow will update the existing event registrant record. Note again flow will wrap the update step in a “Apply to each” box as flow could return multiple event registrant values in CRM to update. The output for the update is then the List records step value (which is the event registrants returned)

Figure 15. The step to update existing event registrant values in CRM if the List records step returns a value

Note in the above screenshot. The purple dynamic content are from the previous Parse JSON step we used to get the EventBrite event attendee data.

The condition “Yes” will then create a new event registrant record in Dynamics if the List record step does not return a value. Note that on the field that says “Event” I’ve added in the “Get record” step event parameter/variable to associate those event registrants with the specific event.

Figure 16. The condition set if no event registrant matching the EventBrite attendee ID exists in the CRM. It will create a new event registrant record

Now you have a running working Microsoft Flow that periodically runs a GET request to retrieve all event attendees from an EventBrite event and update/create the event registrations in CRM! A few things to note before you go ahead and create your own:

  • The JSON payload only returns 50 records and paginates the rest. You will need to factor this in when creating your flow
  • This flow runs only for a specific event as you’ll need to event ID of a specific event to pull the attendee values