The code shown here is designed for Outlook 365 but the flow should be basically the same for any other client. We are going to show the parts of the add-in that deal with Circle since this is about using Circle API not how to write an Outlook add-in.
Here is an Outlook task panel boilerplate project following this.
const appKey = "FROM YOUR CONFIGURATION"; const circleId = "ENTER CIRCLE ID HERE"; const topicId = "ENTER TOPIC ID HERE"; Office.onReady(async (info) => { if (info.host === Office.HostType.Outlook) { let isRunning = await Circle.isServiceRunning(); if (isRunning) { let token = await getCircleToken(); let iniResult = await Circle.initialize(appKey, token); if (iniResult && iniResult.Status.Result) { console.log("Initialized."); // CircleService is running and token is authorized let circles = await Circle.enumCircles(); console.log("enumCircles done."); } else { document.getElementById('runningResult').innerText = 'Failed to get permission.'; console.log("initialized failed."); } } } }); // this is just for this testing, the actual token should be coming from your web server async function getCircleToken() { const url = "https://us-central1-serious-app-273117.cloudfunctions.net/circleLicense/api/demo/token?t=1"; return fetch(url).then((res) => res.json()).then((objJson) => { return objJson.Token; }); }
Button is added to the task pane called encrypt and hooked up this handler
export async function encrypt() { // Get a reference to the current message var item = Office.context.mailbox.item; item.body.getAsync("html", encryptSetbody); // get the body of the email } async function encryptSetbody(asyncResult) {
// convert the body to base64 so we can encrypt it let base64String = utf8_to_b64(asyncResult.value);
// use the Circle and topic ID you want to encrypt with let r = await Circle.secureContents(circleId, topicId, base64String, true); // now generate the new body that includes the URL of the encrypted file let emailHtml = "<div style='text-align: center;'> <p>Click the Cirlce Logo below to view the email.</p>
<a href=https://demosupport20220414211325.azurewebsites.net/Home/Render?url="+ r.SecureFileUrl+">
<img src='https://circleauth.circlesecurity.ai/demo/files/circle-logo-nocompromise.svg'</a><p><br/>This email is secured by Circle.</p>
</div>" // Get a reference to the current message var item = Office.context.mailbox.item; try { await item.body.setAsync(emailHtml, { coercionType: Office.CoercionType.Html, asyncContext: { var3: 1, var4: 2 } }); } catch(ex) { console.log(ex); } }
Later, when we need to render the document on our web server, here’s the Javascript that we use. The URL to the encrypted email (from the encrypt phase above) is passed in.
async function checkCircleServiceIsRunning() { let isRunning = await Circle.isServiceRunning(); if (isRunning) { document.getElementById('status').innerText = 'Requesting permission, please wait.'; } else { document.getElementById('status').innerText = 'Could not find CircleService'; return false; } let token = await getCircleToken(); document.getElementById('status').innerText = 'Initializing Circle Service for Circle Data functions.'; let iniResult = await Circle.initialize(appKey, token); if (iniResult && iniResult.Status.Result) { console.log("Initialized."); document.getElementById('status').innerText = 'Initialized'; } return true; } async function DecryptAndLoad(circleFileUrl) { console.log(fileUrl); document.getElementById('status').innerText = 'Circle Service is decrypting message. Please wait...'; document.getElementById('spinner').visibility = "visible"; var v = await Circle.getSecureFileContents("", circleFileUrl); // get the decrypted Base64 var html = atob(v.FileData); document.open(); // replace the entire document with the email contents. document.write(html); document.close(); } async function RenderORama(circleFileUrl) { await checkCircleServiceIsRunning(); await DecryptAndLoad(circleFileUrl); } window.onload = function () { RenderORama(fileUrl); }