Monday, 6 August, 2018 UTC


Summary

Eventing is a new service available in Couchbase Server. The Cincinnati Reds are interested in using this feature to more quickly serve their VIP customers. A concierge is assigned to one or more VIPs. When the VIP enters the ballpark, a text message will be sent to the concierge. The concierge can then meet the VIP at their seats.
As a proof of concept, I’ve created an example that uses Functions (part of Eventing) to send a text message. I’m using a trial account of Twilio to send the messages. I don’t know if the Reds plan to use Twilio or text messages in their production system. But it’s free and easy to get started using Twilio, so that’s what I decided to use in my proof of concept. You can use any messaging/notification service you’d like (instead) as long as it has an HTTP API.
Eventing review
I’m not going to provide all the details for eventing here. This has been blogged about plenty already by my colleagues. Definitely check out their posts for more details:
  • Introducing Couchbase Eventing Service
  • Using the cURL Function with the Couchbase Eventing Service
  • Detect Sensitive Information In Your NoSQL Documents Automatically With Couchbase Functions
  • The Couchbase Data Platform in Action: Step-by-Step Setup
But the short story is this: Couchbase Functions (part of Eventing) allow you to write JavaScript functions that respond to documents getting created/updated/deleted. Inside of these functions, you can read documents, write documents (to other buckets), execute N1QL queries, and execute a curl function to make requests to HTTP endpoints. Note: The curl construct is still in Development. This feature is intended for Development purposes only and should not be used in Production environments.
I’m going to put together pieces of the above blog posts to create this eventing proof of concept for the Reds.
Scanning Tickets
The first step is to scan a customer’s ticket at the gate. I wrote a program to simulate this. It will create a randomish “ticketscan” document in a “tickets” bucket on Couchbase.
Before scanning tickets, I needed to prepopulate the bucket with some data.
I’ve decided that customers 1 through 9 are the VIPs, and any other customer is a “regular joe”.
_bucket.Upsert("customer::1", new { Name = "George Clooney" });
_bucket.Upsert("customer::2", new { Name = "Josh Hutcherson" });
_bucket.Upsert("customer::3", new { Name = "Darius Rucker" });
_bucket.Upsert("customer::4", new { Name = "Brooklyn Decker" });
_bucket.Upsert("customer::5", new { Name = "Eddie Vedder" });
_bucket.Upsert("customer::6", new { Name = "Nick Lachey" });
_bucket.Upsert("customer::7", new { Name = "Nick Goepper" });
_bucket.Upsert("customer::8", new { Name = "Johnny Bench" });
_bucket.Upsert("customer::9", new { Name = "Ryan Collins" });
Fun Note: these VIPs are all actual Reds fans!
I also created 3 concierges and divided up the VIPs amongst them.
_bucket.Upsert("concierge::1", new
{
    Name = "Matt Groves",
    CellNumber = _yourVerifiedNumber,
    vips = new List<string> { "customer::1", "customer::2", "customer::9" }
});
_bucket.Upsert("concierge::2", new
{
    Name = "Mr. Redlegs",
    CellNumber = _yourVerifiedNumber,
    vips = new List<string> { "customer::3", "customer::4", "customer::5" }
});
_bucket.Upsert("concierge::3", new
{
    Name = "Rosie Red",
    CellNumber = _yourVerifiedNumber,
    vips = new List<string> { "customer::6", "customer::7", "customer::8" }
});
In the above example, I’m assigning customers 1, 2, and 9 to “Matt Groves”. This means that George Clooney, Josh Hutcherson, and Ryan Collins are the VIPs that concierge Matt Groves is assigned to take care of. (Replace _yourVerifiedNumber with the phone number that you’ve confirmed with Twilio).
I’m also storing Twilio credentials in a document. I did this because I’ll need the credentials inside of a Couchbase Function, and I didn’t want to hard-code them there. The credential document looks like:
{
  "url": "https://api.twilio.com/2010-04-01/Accounts/< twilio user name here >/Messages.json",
  "username": "< twilio user name here >",
  "password": "< twilio password name here >",
  "fromNumber": "< twilio 'from' number here >"
}
I’ve created a console app that will create a new “ticketscan” document. When you run it, you can choose to create a VIP scan or a “regular Joe” scan.
Console.WriteLine("1 - Simulate a VIP ticket scan.");
Console.WriteLine("2 - Simulate a regular joe ticket scan.");
Console.WriteLine("Q - End simulation.");
var choice = Console.ReadKey().KeyChar;
A ticketscan document contains only three fields: the ID of the customer document, a timestamp, and a seat number.
_bucket.Upsert(ticketScanId, new {CustomerId = customerId, Timestamp = ticketScanTimestamp, Seat = seatInformation });
You can find the full source code on Github.
Eventing function
The core of this eventing example is the function. When I created this function, I called it “notifyConcierge”; I used a “tickets_metadata” bucket (as pictured below). Most importantly, I created an alias for the “tickets” bucket and called it “src”. Within the function, this bucket is read-only, but I need it to get customer and concierge information as well as the Twilio credentials.
The entire function can be viewed on Github. Here is the breakdown of the function, step by step:
1 – Is the mutated document a ticketscan? If it is, proceed. If not, this function can ignore it.
if (meta.id.indexOf("ticketscan::") !== -1) {
2 – Is the customer who scanned this ticket a VIP? If so, get the concierge’s details and proceed. Otherwise, ignore it. Notice the inline N1QL in this part of the function. This is a feature unique to the flavor of JavaScript used in Couchbase functions.
let customerId = doc.customerId;
let stmt = SELECT t.cellNumber, t.name
           FROM tickets t
           WHERE ANY v IN t.vips SATISFIES v == $customerId END;

//get the concierge (there should only be one)
let concierge = null;
for (var record of stmt) {
    concierge = record;
}

// only proceed with notification if
// the customer has a concierge
if (concierge) {
3 – Get the details of the VIP.
let customer = src[customerId];
4 – Get Twilio credentials.
let twilioCredentials = src["twilio::credentials"];
5 – Construct a message (containing VIP’s name, seat number, and concierge’s name). data is the minimum needed to use Twilio’s API.
let message = "Hello '" + concierge.name + "'. A VIP assigned to you just checked in. '" + customer.name + "' will be in '" + doc.seat + "'";
let from = twilioCredentials.fromNumber;
let data = "To=" + concierge.cellNumber + "&From=" + from + "&Body=" + message;
6 – Send a text message to the concierge using Twilio API. The curl construct is still in Development. This feature is intended for Development purposes only and should not be used in Production environments.
let url = twilioCredentials.url;
let auth = twilioCredentials.username + ": " + twilioCredentials.password;
var result = curl(url, { "data": data, "header": ["Content-Type: x-www-form-urlencoded"], "method": "POST", "auth": auth });
Eventing in action
Now, whenever a ticketscan document is created or modified, a concierge will be notified on their cell phone. Here’s an example of the entire demo, from ticket scan to SMS notification:
In this image, I’m creating 4 ticket scans. The first is for a VIP, the next two are for regular Joes, and the last is for a VIP. Two text messages appear. In reality, these would appear on different phones, but I’m sending all the notifications to a single number for testing. Note: I’m using join.me to show my live Android screen side-by-side with the console).
If you’re running into any issues, the good news is that debugging is available for Functions in Couchbase. You can set breakpoints in the JavaScript and step through it using a tool like Chrome. For more about it, check out the Eventing announcement post.
Summary
With this function running in Couchbase’s eventing system, every new ticketscan for a VIP will trigger a text message notification. Note that the ticket scanning system doesn’t need to know anything about Twilio, as long as the data ends up in Couchbase. Also, if any other system is creating ticketscan documents, the SMS will be triggered there as well. The logic is close to the data.
This wraps up my series of Cincinnati Reds posts (for now). The other two posts in the series were:
  • Nifi Processing and Flow with Couchbase Server – This is how the Reds are actually going to put ticket scan data into Couchbase.
  • Data Visualization with Couchbase and Knowi – This is another use case that the Reds are looking at using ticket scan data for.
Please leave a comment below or find me on Twitter @mgroves. Go Reds!
The post Eventing: Notification with Couchbase Functions appeared first on The Couchbase Blog.