I started looking into Launch Audit Events a while back, which then lead me to the topic of creating Callbacks using the Launch APIs. The general idea is pretty simple — you subscribe to one or more events based on a combination of resource type (e.g. property) & event (e.g. updated) and specify an endpoint for the request. So I spent a bit of time creating a callback that sent a request to Zapier; the reason for doing this was because my ultimate goal was to send the property update info into a Slack app, which meant the data in the Launch request needed re-structuring slightly.
Fast-forward a few weeks (after my Zapier Pro Plan 14 day trial had expired) and I concluded that it was nice functionality to have but my curiosity had been sated. However, a few months later, after some time spent playing around with Node.js and AWS Lambda, I realised that it would actually be pretty simple to set something up that sent an e-mail alert when my Launch library was published to production; the steps below explain how I did it.
#1 Design Overview
Whilst this will sound obvious for most people, I’m finally getting into the habit of sketching out what I want the end result to be before I set off down the rabbit hole. I’ve found this is helpful for two reasons: a) I don’t get (too) distracted by things I uncover on the way that aren’t relevant; and b) it stops me from continuously adding new features (usually related to the things I’m distracted by).
The requirements are pretty simple here:
i) create an Adobe IO Integration, in order to access the Launch APIs
ii) create a Lambda function that the Launch request is sent to
iii) create an API Gateway for the Lambda function
iv) register a callback that makes a call to the API Gateway endpoint
v) configure the Lambda function so it can translate the request from Launch into content that’s suitable for an e-mail
I won’t go through the creation of the Adobe IO integration again because I went through that in the last article, so we’ll jump to step 2 and the creation of a new Lambda function.
#2 Create Lambda function
This initial step of creating the Lambda function is very straightforward, just a question of giving your function a name and then choosing which language you want to write it in:
Once the function has been successfully created, you will see the Designer view, which shows that there isn’t anything set up to actually trigger the function. So the next step is to head over to the API Gateway UI and set up the endpoint that will trigger the function.
#3 Create API Gateway
In this step you are going to create the endpoint that will be included in the Launch callback configuration.
The first step is to create a new REST API:
Then provide a name for your API and click “Create API”:
The next step is to create a resource name:
Then go to the Actions menu again, click “Create Method”, choose “Any” and click on the tick icon. You need to tick “Use Lambda Proxy Integration” so that the request details from Launch are accessible via the event object of your Lambda handler function; finally, add the name of your Lambda function and click save:
If everything has gone smoothly you should see something that looks like this. You can also use use this area of the UI to send requests to your Lambda function for testing:
The final step is to deploy the API, which can be done via the Actions menu. The first time you deploy, you will need to create a new stage name; it doesn’t matter what this name is but just be aware that it will form part of the endpoint URL that you eventually use in the Launch callback:
With the API deployed and a new stage created, you can now go into the Stages tab and get the endpoint URL that you will need to create the Launch callback:
It’s worth testing the URL to make sure that the API Gateway is connecting successfully to your Lambda function. So just copy and paste the URL into your browser — I chose “Author from scratch” when I created my Lambda function in Step 1, which means that the function is created with a simple “Hello from Lambda!” response:
#3 Create the Launch callback
This is going to be a one-time request to register the callback, so I’d recommend using something like Postman for this part of the setup. All that’s required is to make a POST request to https://reactor.adobe.io/properties/your-property-id/callbacks with a couple of values in the body of the request.
As per the usual API process, you need to exchange a jwt for an access token, which you will then use in your API requests; see more information here on generating the access token if you’re not familiar. In the screenshot below I have set up the POST request for the particular property I want to register the callback against, as well as including the bearer token for authentication purposes.
Next, you will need to add Accept & Content-Type headers to your request, along with the x-api-key (i.e. the client ID from your IO integration) and x-gw-ims-org-id (i.e. the org ID from your IO integration):
The final step is to create a simple object to include in the body of the request — the only two things you need to include are the “url” value and at least one value in the “subscriptions” array. As a reminder, the url should be the endpoint you want to send the callback request to, so in my case that’s the API Gateway that’s linked to my Lambda function:
Assuming the request that you submitted was valid, you should then receive a response that provides an id for the callback, as well as confirmation of the event(s) and url details that you submitted:
If you want to be absolutely certain that the callback was registered successfully, you can submit the same request as GET instead of POST and it will return a list of the callbacks registered to that property.
#4 Configure the Lambda function
If you now head back to your Lambda function, you should hopefully see that the Designer shows the link to your API Gateway trigger that you created earlier:
You might remember from section 2 that I mentioned enabling “Use Lambda Proxy Integration” so that you can access the request details via “event” in your handler function. This means that the code within the exports.handler function has access to all of the Launch callback request details via “event”.
The first step here is to parse the body of the Launch request to find the attributes that are needed for the e-mail content. Also, I only want my e-mail notification to be sent when the production environment is updated, so the code that’s actually sending the e-mail is wrapped inside a condition that checks the environment name:
I’m using the nodemailer library, so after the contents of that library have been loaded I then need to set up some basic configuration options:
The next step is to compose the message that I want to send, which is a simple process with nodemailer. I want my e-mail notification to include the Property Name, Property ID, Environment Name, Deployment Time and the name of the person that made the update, so I need to create an html structure that will dynamically populate these values based on the information I parsed from the Launch request:
The final task is to trigger the e-mail send:
#5 The end result
The end result is an e-mail notification that is triggered when a user publishes the Launch environment to production:
One thing to bear in mind is that some of the events that callbacks can be registered against often get triggered twice, which was the case with the environment.updated event I used. However, I noticed that not all of the values I was parsing from the body were present on both requests, so it was simple enough to add a condition that prevented two e-mails being sent every time.
I think it’s quite likely that e-mail build notifications will be included in a forthcoming Launch update but in the meantime this is a relatively simple way of monitoring your deployments. Either way, I hope this has given you some inspiration to have a look at creating something similar yourself or to spend some time getting more familiar with Launch APIs, Node.js and Lambda.