Umbraco

How to Extend Uno into a Complex System with Integrated External Services

How MVP Anthony Dang extended Uno's functionality and you can too!

Written by: MVP Anthony Dang

Here's to experimentation! MVP Anthony Dang integrated Uno with Eventbrite and Sendgrid to create an event booking website - and you can do the same using a combination of Umbraco Forms, Azure Functions, and CosmosDB triggers 💻

Update March 30, 2022: Umbraco Uno has been discontinued as a product. Find the reason here.

I recently launched UmbrCoach, a mentoring and coaching community for developers. On the surface, it looks like an event booking system. Under the hood, it uses Umbraco Uno

You thought that Uno was just for brochure sites? Nope!

Enabling custom code in Uno allows you to extend its functionality in ways it was not necessarily envisioned to do. 

In this article, I will give an overview of how I built an event booking system where members can create events, have them listed on the website, and register attendees. As part of this, there are also some automated email alerts. Note that there is no programmatic control over Uno without Custom Code, so here comes that buzz word… Microservices!

How Did I Build It?

Let’s start with some full disclosure… I say that I am full-stack, but what I really mean is that I am heavy on the back-end, and will hack together a Bootstrap website that would make designers and front-end developers shriek and cringe. Thankfully, Umbraco came to my rescue by launching Uno in early 2020. 

When I trialled Uno, here’s what stood out to me:

  • Slick modern design,
  • Good flow for the end user, 
  • The backoffice follows established patterns

It was a no brainer for me to try and use this to create my community event booking site!

 

Member Registration & Login

My website needed member registration, and surprisingly, this was the easiest part. You have a choice of either creating them manually, or using the block widget you can see here on the left.

The resulting rendered form looks something like this:

Block widgets are a super easy way to create a slick website in Uno.

You can find more info in the documentation.

Member Login

Securing a “logged in” member section is as simple as right-clicking and selecting Public Access on the node, then using the Login widget on a page. There’s not much else to say about this. It just works!

 

Limitations

Member Type

There are some limitations in Uno when it comes to members. The Register widget currently only creates members of type ‘member.’ If you have another member type in the backoffice, then you’re out of luck.

Forgot Password

It seems strange that there are Register and Login widgets but no Forgot Password widget. I submitted a support ticket for this.

 

Event Creation

This is where it got fun. I wanted to integrate my site with Eventbrite to manage all the events. Eventbrite has a very detailed API and takes care of a lot of the heavy lifting. So I created DangEasy.Eventbrite - c# library to interact with the Eventbrite API. But how was I meant to get Uno to use this?

Luckily, Uno comes with Umbraco Forms out of the box. This is great because it means that form data can be posted to an endpoint using a workflow. I used webhook.site to see what was actually being posted.

Then I created an Azure Function App with an HTTP trigger to accept the posted data and fire off requests to Eventbrite using my library. To test locally, I pointed the Umbraco form to ngrok.

The response from Eventbrite is saved in a database via a CosmosDb output binding. The reason for storing this will become apparent in the following sections :)

 

Event Confirmation

Upon event creation, I wanted members to be sent a confirmation email with the details they submitted along with a link to the Eventbrite event. Conveniently, Azure Function Apps have a Sendgrid output binding for this purpose. 

To trigger the confirmation email send, I used a CosmosDB trigger. (This means that when a document is added to CosmosDB, my “emailing” Function App is triggered.)  Everything I need for the email comes from a combination of the Umbraco Form and the Eventbrite response to creating the event.

 

Event Listing

The public session page and member dashboard show the event listings. This is accomplished by a HTTP triggered Function App.

The Function App is queried by some javascript using the Uno Code widget. In my case, I used jQuery .ajax(). For maintainability, I actually automatically deploy this javascript to blob storage using Azure Devops.

The Member dashboard shows only the sessions for the logged-in Member, so I needed some sort of member identifier to perform a query.

I added a hidden Umbraco Form on the page and used the magic string {member.id} in a hidden field, then used jQuery to grab the member ID and called .ajax() to make a GET request to my Function App.

 

Where Does the Data Come from? 

While I was initially calling the Eventbrite API to get events, I realised I needed to query the events differently for the public and member feeds, while also keeping in mind that I’ve already experienced a lockout from my Eventbrite account due to API overuse.

Therefore, this Function App does a query to the CosmosDB collection mentioned above. I have a library for this! The coincidental side effect of this approach is that I could perform some more complex queries in the future.

 

Attendee Registration Notification

The session list links off to Eventbrite, and that’s where all the booking/registration occurs. So how does the Uno Member know if someone signed up to their session?

Eventbrite has webhooks, which for me meant writing an HTTP-triggered Function App to act. To test locally, I used ngrok to accept the webhook. My Function App, in this case, hits the Eventbrite API to get more info, then outputs to CosmosDB. Finally, Sendgrid is used to send a notification to the member with details about the attendee.

 

What's Not Possible with Uno?

Let’s recap.

It’s clear, based on my experimentation, that you can:

  • Perform CRUD operations via Umbraco Forms workflows and Azure Function Apps,
  • Query via javascript calls to external data feeds. 

But I have almost reached the limit of what is possible via javascript, Umbraco Forms, and Function Apps. 

My wish list for Uno:

  • I would like to add some new properties to members, and perhaps their images, and be able to post that data via the Umbraco Forms. 
  • I would also really like to programmatically control content, members, and media (be able to create, edit/update, publish/unpublish, and delete Umbraco nodes). 
  • I would love it if the Umbraco Heartcore API was integrated into Uno. 

For the last one, I created a feature request.

 

Final Thoughts

Umbraco Uno is a slick website experience for your end users. The backoffice follows some known structural doctype patterns, so overall it is a typical Umbraco editor experience. Changing the theme and finding my way around was quite easy. Adding content is a breeze, and the Block Widget editor really makes adding content a joy.

Complex integrations can be accomplished by pushing functionality off to external services, and I think that I have pushed Uno to the near-limit of how it can be extended. At this time, there is no way to programmatically control Umbraco content, members or media in the standard Uno setup. If this happens, then the sky’s the limit for Uno.

 

 

🙌 We're so excited to offer our MVPs the chance to showcase their work on our blog. Want to see your name here next? 🙌

BECOME AN UMBRACO MVP