Turning Envoy’s notifications into conversations

Employees responding to host notifications

Notifications at Envoy

Notifications have been a core part of Envoy Visitors, our visitor management product, since its initial launch. We invested heavily in visitor host notifications because users need to know when they have someone waiting for them in the lobby. It’s part of the “automagical” experience Envoy customers have come to expect.

When we began building Envoy Deliveries, we realized that delivery notifications would be just as important. We decided to take steps to leverage what we had learned from Envoy Visitors and extract a service that would help us serve both Deliveries’ and Visitors’ notifications needs. We chose this route for several reasons:

Reliability

With a centralized service that handles sending notifications, we could dedicate more resources to robust error handling and performance tuning since we wouldn’t have to re-implement this logic in each individual application.

Monitoring

Since all notifications flow through the same service, we’re able to centrally monitor failure rates and responses times, making it easier to identify, diagnose and communicate problems.

Parity

Deliveries, Visitors, and our future products will all have access to the same notification channels. We don’t need to re-implement channels when we decide to build a new product.

We also wanted to make Envoy’s product experience more dynamic and interactive — even when the product is experienced in Slack, outside of our own dashboard. We saw that our users frequently replied to “no-reply” messages informing them of a waiting visitor or package. This data gave us a clear indication that our notifications are not one-off alerts and should be treated as the start of a conversation.

Because of our close relationship with Slack, as both a mutual customer and integration partner, the clear first step towards a solution was to upgrade our existing Slack app. Using Slack interactive elements would enable us to build, learn, and iterate towards an effective solution for creating the conversations our customers wanted. First however, we needed to update our new Notification Service to accommodate two-way messaging.

Technical overview

The Notification Service’s primary job is to receive a generic notification event from one of our core products and route that event to channel specific microservices based on company and user preferences. In the case of Slack, the Notification Service would send the generic payload to the Slack microservice, which would translate it into an API request with fields that the Slack API expects.

Since both our Visitor Registration and Deliveries backends are developed in Rails, we created a Ruby SDK our developers can use to generate the notification payload that the Notification Service expects.

Notification.new
.recipient(recipient)
.message(message)
.details(details)
.attachments(attachments)
.add_action(action)

This abstract payload is what gets sent to the Notification Service and, eventually, to one or more microservices. The resulting Slack message looks like this:

Envoy host notification in Slack

One-click replies from the Slack web, mobile, or desktop client make interaction easy. Providing the user confirmation about how their reply was routed gives them confidence that we have appropriately taken action.

Envoy delivery notification in Slack

Proxying action callbacks

In addition to translating an abstract notification payload into a Slack API payload, the Slack microservice has another, equally important responsibility: it handles all action callbacks from Slack. In the Envoy Slack app we’ve configured the request URL that gets invoked when an action is taken to point to an endpoint handled by the Slack microservice. When a user selects a button in one of our notifications, the value of the button contains an encoded callback URL that the originating application specified when creating the abstract notification payload.

The Visitors app routes replies to host notifications to the reception team

This allows each application sending notifications through the Notification Service to specify where they want to receive action callbacks and the Slack microservice will forward the slack request to that URL. This separation of concerns is really nice; applications only need to worry about business logic, while the Notification Service and the Slack microservice can handle the infrastructure needed to make it all happen.

In conclusion

As Envoy continues to grow, notifications will play an important role in our mission to create delightful experiences out of otherwise mundane — and sometimes frustrating — interactions. Keeping a product simple as it grows more featureful is difficult, but with forward-thinking partners like Slack and the right investments in a scalable and extensible infrastructure, we’re eager to take on the challenge.