Hi
This is possible, and not too difficult. In short, every JourneyApps container registers a custom URL handler once it is installed on the device. This custom URL handler allows you to use “deep linking” to enroll into the container using a link with a very specific format, amongst other things.
The problem you will face with just trying to email a link in that special format is that most modern email clients actively remove links that use custom URL handler patterns, even when you try to include it in the HTML body of the email. This means that in order to actually do this you will need a 2 step process.
- Send email with link to a webpage
- Have that webpage redirect using the special custom URL handler
And luckily you can do both fairly easily within CloudCode. Like so
CC task to generate enrollment link and email
const sgMail = require("@sendgrid/mail");
const handlebars = require("handlebars");
// To send email, a SendGrid API key is required
sgMail.setApiKey("");
const emailTemplate = handlebars.compile(`
<!DOCTYPE html>
<html>
<body>
<h1>Welcome to your app</h1>
<p>Please follow the link below to enrol in your new app</p>
<a href="{{ webtaskLink }}">Enroll Here</a>
</body>
</html>
`);
export async function run(params) {
// Generate an HTML email, using handlebars again
var userID;
if (params) {
userID = params.userID
} else {
userID = "some user ID"
}
var options = {
method: "POST",
headers: {
"Authorization": `Bearer ${this.backend.token}`
}
}
// Get a new enrollment token / url for the userID in question from the Backend Users API: https://docs.journeyapps.com/reference/backend-api/api-reference/manage-app-users-and-sessions
var response = await fetch(`${this.backend.url}/users/${userID}/authentication-token`, options)
if (!response.ok) {
console.log("Error, response not ok");
var message = await response.text();
console.log(`Error: ${message}`);
return;
} else {
var body = await response.json();
var url = body.url;
// custom URL scheme of the container in question
// reach out to JourneyApps support for the custom URL scheme of your containers if you are not sure what they are
var urlScheme = "journeyapps:///"; // JourneyApps vanilla container custom URL scheme
// replace the default enrollment url prefix with the custom URL scheme
var customEnrollmentLink = url.replace('https://embark.mobi/', urlScheme)
// URL encode the new enrollment link
var encodedURL = encodeURIComponent(customEnrollmentLink);
// create the full link that will be included in the HTML email body
// it's a link to a different CC webtask, hosted at the specific domain that you specify per backend
// and that will be expecting the custom enrollment url as a URL parameter
const backendDomain = "" // Insert your full backend domain here, including https:// (Backend domains are specified on a per deployment basis using the Deployment Settings interface
// Example
// const backendDomain = "https://exampleDomainName.poweredbyjourney.com"
const webTaskName = "" // Insert the name of your CC webtask here
var taskUrl = `${backendDomain}/${webTaskName}?url=${encodedURL}`
const html = emailTemplate({ webtaskLink: taskUrl });
console.log("HTML Template: ", html);
const email = {
from: "", // from email address
to: "", // to email address
subject: "", // email subject
html: html, // Or: text: "Plain email"
};
try {
await sgMail.send(email);
} catch (error) {
// This helps for debugging
if (error.response) {
console.error(error.response.body);
}
throw error;
}
}
}
You can obviously decide how you want to trigger this task, but in short it just generates a new enrollment link for a specific user, creates the custom enrollment URL from that link, and then sends an email with a link to the redirect webpage, passing the custom url as a parameter to that page
CC Webtask to serve a redirect webpage
The name of this task needs to match the value of webTaskName
in the previous block of code
const handlebars = require('handlebars')
// HTML template that will be used as the webpage
// Includes an immediate redirect to the specified 'redirectURL'
const webpageTemplate = handlebars.compile(`
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="0; url='{{ redirectURL }}'" />
</head>
<body>
<p>Please follow <a href="{{ redirectURL }}">this link</a>.</p>
</body>
</html>
`)
// This must be defined, and should return either access.authorized() or access.unauthorized()
export async function authenticate({request, access}) {
return access.authorized();
}
// HTTP GET request
export async function get({params, request, response, authContext}) {
// create the HTML - passing in the custom URL that was included as a URL param
const html = webpageTemplate({ redirectURL: params.url });
// render the HTML page
response.contentType('text/html');
return html;
}
export async function run() {
// This function is not used for web tasks, but can be used for editor testing
}
So basically the email recipient will get the email with the link to the webtask, they will click on the link which will take them to the webtask, the webtask will serve the HTML page and immediately redirect to the redirect URL that was passed along as a URL parameter. At this point, if the custom container is installed on the user’s device, the user would get enrolled into the custom container.
I hope this helps