Based on Set custom header (x-header) on Outlook compose mail with JS addin post, I used the following code to set a custom x-header when composing emails in OWA or Outlook 2019.
function addCustomHeadersAsync(classificationMarking) {
return new Office.Promise(function (resolve, reject) {
try {
/* The itemId property is not available in compose mode. If an item identifier is required,
the saveAsync method can be used to save the item to the store, which will return the item identifier in the asyncResult.value parameter in the callback function.*/
Office.context.mailbox.item.saveAsync(function (saveAsyncResult) {
/* The getCallbackTokenAsync method makes an asynchronous call to get an opaque token from the Exchange Server that hosts the user's mailbox.
The lifetime of the callback token is 5 minutes. The token is returned as a string in the asyncResult.value property.*/
Office.context.mailbox.getCallbackTokenAsync({ isRest: true }, function (getCallbackTokenAsyncResult) {
var ewsId = saveAsyncResult.value;
var token = getCallbackTokenAsyncResult.value;
var restId = Office.context.mailbox.convertToRestId(ewsId, Office.MailboxEnums.RestVersion.v2_0);
var getMessageUrl = Office.context.mailbox.restUrl + '/v2.0/me/messages/' + restId;
// The PropertyId for PS_INTERNET_HEADERS is {00020386-0000-0000-C000-000000000046}.
// https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/commonly-used-property-sets?redirectedfrom=MSDN
// https://stackoverflow.com/questions/38214197/set-a-custom-header-with-outlook-office-365-rest
var securityHeaders = JSON.stringify({
SingleValueExtendedProperties: [
{
PropertyId: "String {00020386-0000-0000-C000-000000000046} Name X-Custom-header",
Value: classificationMarking
}
]
});
// https://learn.microsoft.com/en-us/previous-versions/office/office-365-api/api/version-2.0/extended-properties-rest-operations#ExtendedpropertyoperationsCreateextendedpropertyinanewitem
// PATCH request is required to create an extended property in an existing item
var xhr = new XMLHttpRequest();
xhr.open('PATCH', getMessageUrl);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.onload = function (e) {
//console.log(this.response);
resolve();
}
xhr.send(securityHeaders);
});
});
}
catch (error) {
reject("Unable to set email custom security headers");
}
})
}
As on-premises Office 2019 + Exchange 2016 only supports API 1.5, I'm not able to use the new setCustomHeaders function which has been available since API 1.8 (https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/internet-headers)
Everything works in https://outlook.office.com/mail/inbox & on-premises OWA (Exchange2016).
When using Outlook 2019 (online mode) :
Is this code correct to set custom email headers using SingleValueExtendedProperties with Outlook 2019 ?
How can I make Outlook 2019 aware of the new SingleValueExtendedProperties / x-header added to the draft message though the Exchange REST API ?
Edit 11/10/2021 : tested with makeEwsRequestAsync & test summary
Outlook 2019 build 2108 (Office 365) |
Outlook on the web |
Outlook 2019 build 1808 (Exchange 2016) |
OWA Exchange 2016 |
|
---|---|---|---|---|
Exchange REST API XMLHttpRequest | X-Custom-header correctly set server side but removed when sending the draft email from Outlook. If opening and sending the draft from OWA after having set the X-header from the addin in Outlook, X-Custom-header is preserved | OK | X-Custom-header correctly set server side but removed when sending the draft email from Outlook. If opening and sending the draft from OWA after having set the X-header from the addin in Outlook, X-Custom-header is preserved | OK |
makeEwsRequestAsync() | OK | OK | X-Custom-header correctly set server side but removed when sending the draft email from Outlook. If opening and sending the draft from OWA after having set the X-header from the addin in Outlook, X-Custom-header is preserved | EWS request proxy error |
What you are trying to do is not possible on Win32 Outlook Client. Your Step #2 (XMLHttpRequest) effectively creates two version of the item, one on the client and one on the server. When the item is eventually sent, one will overwrite the other (most likely the one sent from the client), and overrides the changes that you made.
setCustomHeaders in 1.8 was created to address this problem. setCustomHeaders, actually does not rely on the server for it's functionality, so it should work as long as your client supports 1.8.
Office 2019 (retail) does support 1.8. Office 2019 (volume-licensing) does not.
Users on the volume licensed version will need to upgrade to get this support.