Most Popular
Courier is a notification service that centralizes all of your templates and messaging channels in one place which increases visibility and reduces engineering time.
Sign-up
GitHub Repository: https://github.com/shreythecray/lie-detector
Follow along with the video tutorial:
We will build a serverless application that uses Artificial Intelligence to conduct facial recognition and uses Courier to send alerts based on the results. We just launched our first hackathon and are giving away over $1K in prizes! Join us in building a cool project and winning any of the following prizes. 🏆
Additionally, everyone who submits a project successfully integrating the Courier API will receive a $20 Amazon gift card! Submissions close on September 28th. Register now to submit this project for a chance to win some cool prizes.
Register for the Hackathon: https://courier-hacks.devpost.com/
Not sure where to start? In this tutorial, we will build a serverless lie detector that uses Artificial Intelligence for Facial Recognition.
Let’s get started. We are secret agents and headquarters is telling us that one of our spies has betrayed us and has been leaking sensitive, top-secret information to our enemies. Our goal is to build a lie detector that will alert our spy network when we identify the mole. We will use Azure's Cognitive Services to perform facial recognition on everyone on our team. When the Face API recognizes that one of our spies is being deceitful, we will use Courier to broadcast the identity of the mole to our spy network.
Some spies are in an area where they can only guarantee secure messaging through emails, and others prefer quick and secure SMS, so we need to ensure our app can accommodate all spy preferences.
Note: The first three Secret Agents to successfully complete this tutorial and task will receive a top-secret gift from HQ via Courier.
In Part 1, we will create our serverless application using Azure Functions. In Part 2, we will first integrate the Gmail and Twilio APIs, which Courier will use to send emails and text messages. In Part 3, we will demonstrate how to send single messages and set up routing to send multi-channel notifications from the Azure function. And finally, in Part 4, we will explore Azure Cognitive Services and integrate the Face API to analyze emotions and use the Courier API to send alerts when specific deceiving emotions are detected.
We first need to set up our local development environment to enable using Azure and testing our code.
Once the two extensions have been installed successfully, check the left menu for Azure’s A symbol. Completely close and reopen VS Code if the symbol does not automatically appear.
To build an HTTP Trigger Function:
If the subscription is not showing up locally, follow instructions from the documentation on how to set up our account, which tells us to sign out of Azure on VS Code and sign back in.
Once the location has been selected, we are prompted to make a few decisions about the type of function we want to create.
You can edit settings later within the function.json file. Let’s open the index.js file and take a moment to understand the boilerplate function.
1module.exports = async function (context, req) {2context.log('JavaScript HTTP trigger function processed a request.');34const name = (req.query.name || (req.body && req.body.name));5const responseMessage = name6? "Hello, " + name + ". This HTTP triggered function executed successfully."7: "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.";89context.res = {10// status: 200, /* Defaults to 200 */11body: responseMessage12};13}
Line #4 demonstrates how we can get data from the function query or request body. Line #5 contains a string assigned to a variable named responseMessage
, which uses the data from line #4. On lines #9-12, this variable is then passed into the response object, context.res
.
Courier sends messages by consolidating multiple API calls into one. In this second part, we will need to authorize our API to send messages via the Gmail and Twilio APIs.
Once you see Agent Pigeon dancing, we are ready to use Courier to communicate with our spies. Before we build out our application, we need to set up the Twilio provider to enable text messages.
Lastly, you need to locate the Messaging Service SID, which you create in the Messaging tab on the left menu. Checkout Twilio’s docs on how to create a Messaging Service SID, linked in the description.
We can use Courier to send single messages or set up routing to send multi-channel notifications from within the Azure function. In this third Part, we will start sending messages and will refer to the Courier Node.js quick start, which outlines how to get started with the SDK, and can be found within the Docs page on courier.com.
If you would rather use the Courier API, check out the Secret Message tutorial for instructions or Courier’s API Reference for documentation.
The SDK documentation walks us through getting access to the API key.
const apiKey = process.env["API_KEY"]
. This application can now be authorized to use our Courier account.1{2"IsEncrypted": false,3"Values": {4"AzureWebJobsStorage": "",5"FUNCTIONS_WORKER_RUNTIME": "node",6"API_KEY": "replace-with-your-key"7}8}
npm install @trycourier/courier
1const { CourierClient } = require("@trycourier/courier");
The last step is to walk through the API call within the API docs and integrate it into our codebase.
1import { CourierClient } from "@trycourier/courier";2// alternatively:3// const { CourierClient } = require("@trycourier/courier");45const courier = CourierClient({ authorizationToken: "YOUR_AUTH_TOKEN_HERE" });67const { requestId } = await courier.send({8message: {9to: {10email: "email@example.com",11},12content: {13title: "Welcome!",14body: "Thanks for signing up, {{name}}",15},16data: {17name: "Peter Parker",18},19routing: {20method: "single",21channels: ["email"],22},23},24});
The code on lines #8-23 defines the message object, which provides data to Courier about the messages: the to
object about the user receiving the notification, the content
object about what the message contains, the data
object about any variables that impact the content
object or conditions for the outgoing notifications, and the routing
object about the types of notifications being sent.
title
or email subject to Mule Identified
and the body
to Beware! The mule is {{name}}.
In this case, we can either hardcode the name or get it from the HTTP trigger function body.responseMessage
and log it to the console. This new responseMessage
will indicate to us that this HTTP triggered function runs successfully by outputting the requestId
response from the Courier API call.func start
command in the terminal, enabling the trigger for this function (and all functions within this project, if there were others). This command will also return to us the corresponding local endpoint that we can use to trigger this function.1const { requestId } = await courier.send({2message: {3to: {4email: "courier.demos+liedetector@gmail.com",5},6content: {7title: "Mule Identified!",8body: "Beware! The mule's name is {{name}}.",9},10data: {11name: name,12},13routing: {14method: "single",15channels: ["email"],16},17},18});
We can use Postman or Insomnia to test this function. Here we will use the REST Client VS Code extension, which we installed earlier
###
at the top of the request.http file.POST
, and paste the endpoint next to it.name
parameter and define it as Secret Agent Pigeon.
1###2POST http://localhost:7071/api/LieDetector34{5"name": "Secret Agent Pigeon"6}
Azure Cognitive Services enables us to add cognitive capabilities to apps through APIs and AI services. Check out all of the services provided. In this final part, we will explore Azure Cognitive Services, integrate the Face API to analyze emotions, and use the Courier API to send alerts when specific deceiving emotions are detected.
1{2"IsEncrypted": false,3"Values": {4"AzureWebJobsStorage": "",5"FUNCTIONS_WORKER_RUNTIME": "node",6"API_KEY": "replace-with-your-key",7"FACE_API_KEY": "replace-with-your-azure-key",8"FACE_ENDPOINT": "replace-with-your-azure-endpoint"9}10}
These values are treated as secret keys and this file is included in the .gitignore.
Just as we used the Courier SDK, we will use the Face service with Azure’s SDK, which can be found on the Azure Cognitive Services npm page. We will need to use both commands on this page.
npm install @azure/cognitiveservices-face
in the terminal to install the Face service SDK.npm install @azure/ms-rest-azure-js
in the terminal to install the REST Azure Client.1const { FaceClient, FaceModels } = require("@azure/cognitiveservices-face");2const { CognitiveServicesCredentials } = require("@azure/ms-rest-azure-js");34async function main() {5const faceKey = process.env["faceKey"] || "<faceKey>";6const faceEndPoint = process.env["faceEndPoint"] || "<faceEndPoint>";7const cognitiveServiceCredentials = new CognitiveServicesCredentials(faceKey);8const client = new FaceClient(cognitiveServiceCredentials, faceEndPoint);9const url =10"https://pbs.twimg.com/profile_images/3354326900/3a5168f2b45c07d0965098be1a4e3007.jpeg";11const options = {12returnFaceLandmarks: true13};14client.face15.detectWithUrl(url, options)16.then(result => {17console.log("The result is: ");18console.log(result);19})20.catch(err => {21console.log("An error occurred:");22console.error(err);23});24}2526main();
Now, we can update the variables within the code snippet.
analyze_face()
.options
object between lines #50 to #52 to returnFaceAttributes
and add an array with emotion
as an element.1async function analyze_face() {2const faceKey = process.env["FACE_API_KEY"];3const faceEndPoint = process.env["FACE_ENDPOINT"];4const cognitiveServiceCredentials = new CognitiveServicesCredentials(faceKey);5const client = new FaceClient(cognitiveServiceCredentials, faceEndPoint);6const url =7"https://www.allkpop.com/upload/2021/12/content/231225/web_data/allkpop_1640280755_untitled-1.jpg";8const options = {9returnFaceAttributes: ["emotions"]10};11client.face12.detectWithUrl(url, options)13.then(result => {14console.log("The result is: ");15console.log(result);16})17.catch(err => {18console.log("An error occurred:");19console.error(err);20});21}2223analyze_face();
Finally, we need to be able to manipulate the response from this API call.
result
.stringify
method.1const result = await client.face.detectWithUrl(url, options);2const resultJSON = JSON.stringify(result, null, 2);
We run into an error when we use the REST Client to test our function. The result is not displayed, which means that for some reason, analyze_face()
is not returning the correct response. We can check the Face API reference to determine the cause of the error. We can first attempt to resolve the issue by removing a specific emotion
from the result object.
1const result = await client.face.detectWithUrl(url, options);2const anger = result[0].faceAttributes.emotion.anger;3const angerJSON = JSON.stringify(anger, null, 2);
The actual error stems from a typo on line #51 where the object returned is not plural and should be called emotion
. When we test the code, we see that the anger emotion has a value of 0, which matches the selected image.
1const options = {2returnFaceAttributes: ["emotion"]3};
analyze_face()
function to return the entire emotion
object. This will enable us to compare multiple emotions' values and determine whether the face being analyzed is deceitful.1const result = await client.face.detectWithUrl(url, options);2return result[0].faceAttributes.emotion;
Following instructions from Headquarters, we know that our questions should only invoke specific reactions. If a face shows any hint of anger, neutral, or contempt emotions, we will have to assume that the person being questioned is the mule.
1const emotions = await analyze_face();2const anger = emotions.anger;3const angerJSON = JSON.stringify(anger, null, 2);4const neutral = emotions.neutral;5const neutralJSON = JSON.stringify(neutral, null, 2);6const contempt = emotions.contempt;7const contemptJSON = JSON.stringify(contempt, null, 2);
1if((angerJSON > 0)||(neutralJSON > 0)||(contemptJSON > 0)) {2deceptive = true;3}
1const { CourierClient } = require("@trycourier/courier");2const { FaceClient, FaceModels } = require("@azure/cognitiveservices-face");3const { CognitiveServicesCredentials } = require("@azure/ms-rest-azure-js");45const apikey = process.env["API_KEY"];6const courier = CourierClient({ authorizationToken: apikey });78module.exports = async function (context, req) {9context.log('JavaScript HTTP trigger function processed a request.');1011const name = (req.query.name || (req.body && req.body.name));1213const emotions = await analyze_face();14const anger = emotions.anger;15const angerJSON = JSON.stringify(anger, null, 2);16const neutral = emotions.neutral;17const neutralJSON = JSON.stringify(neutral, null, 2);18const contempt = emotions.contempt;19const contemptJSON = JSON.stringify(contempt, null, 2);2021let deceptive = false;2223if((angerJSON > 0)||(neutralJSON > 0)||(contemptJSON > 0)) {24deceptive = true;25}2627if(deceptive) {28const { requestId } = await courier.send({29message: {30to: {31email: "courier.demos+liedetector@gmail.com",32},33content: {34title: "Mule Identified!",35body: "Beware! The mule's name is {{name}}.",36},37data: {38name: name,39},40routing: {41method: "single",42channels: ["email"],43},44},45});46}4748const responseMessage = "The HTTP trigger function ran successfully.";4950context.res = {51// status: 200, /* Defaults to 200 */52body: {53responseMessage,54"anger": angerJSON,55"neutral": neutralJSON,56"contempt": contemptJSON5758}59};60}6162async function analyze_face() {63const faceKey = process.env["FACE_API_KEY"];64const faceEndPoint = process.env["FACE_ENDPOINT"];65const cognitiveServiceCredentials = new CognitiveServicesCredentials(faceKey);66const client = new FaceClient(cognitiveServiceCredentials, faceEndPoint);67const url =68"https://www.allkpop.com/upload/2021/12/content/231225/web_data/allkpop_1640280755_untitled-1.jpg";69const options = {70returnFaceAttributes: ["emotion"]71};72const result = await client.face.detectWithUrl(url, options)73return result[0].faceAttributes.emotion;74}
Our lie detector is ready and will alert our spies anytime a captive tries to mess with us. Try building a lie detector of your own and alerting courier.demos+liedetector@gmail.com, and we will send a gift to the first three Secret Agents to complete this task! Head to courier.com/hack-now to get started. Don’t forget to submit your project to our Hackathon for a chance to win over $1000 in cash and prizes!
🔗 GitHub Repository: https://github.com/shreythecray/lie-detector
🔗 Video tutorial: https://youtu.be/0RJ9m-T7sgU
🔗 Courier: app.courier.com
🔗 Register for the Hackathon: https://courier-hacks.devpost.com/
🔗 Courier's Get Started with Node.js: https://www.courier.com/docs/guides/getting-started/nodejs/
🔗 Courier Send API Docs: https://www.courier.com/docs/reference/send/message/
🔗 Twilio Messaging Service SID Docs: https://support.twilio.com/hc/en-us/articles/223181308-Getting-started-with-Messaging-Services
🔗 Courier API Reference: https://www.courier.com/docs/reference/
🔗 Azure for Students: https://azure.microsoft.com/en-us/free/students/
🔗 Troubleshooting Azure Account Setup: https://github.com/microsoft/vscode-azure-account/wiki/Troubleshooting#setup-your-azure-account
🔗 Azure Cognitive Services: https://azure.microsoft.com/en-us/services/cognitive-services/#overview
🔗 Azure Portal: https://portal.azure.com/
🔗 Azure Cognitive Services SDK: https://www.npmjs.com/package/@azure/cognitiveservices-face
Courier is a notification service that centralizes all of your templates and messaging channels in one place which increases visibility and reduces engineering time.
Sign-up
How to Set Up Automatic Push Notifications Based on Segment Events
Push notifications have carved their own niche as a powerful tool for continuous user engagement. Regardless of whether an app is actively in use, they deliver your messages straight to your user's device. Two key players that can combine to enhance your push notification strategy are Segment and Courier. In this tutorial, we show you how to set up Courier to listen to your Segment events and then send push notifications to an Android device based on data from these events.
Sarah Barber
November 17, 2023
How to Send Firebase Notifications to iOS Devices Using Courier
This tutorial explains how to send push notifications to iOS devices from your iOS application code using Firebase FCM and Courier’s iOS SDK.
Martina Caccamo
November 01, 2023
Free Tools
Comparison Guides
Send up to 10,000 notifications every month, for free.
Get started for free
Send up to 10,000 notifications every month, for free.
Get started for free
© 2024 Courier. All rights reserved.