I get the following error when trying to read headers in an email:
code: 7000
message: "You don't have sufficient permissions for this action."
name: "Permission Denied"
I'm using the new version of Outlook for Mac 16.41 and the latest iOS version. In both apps, I can't read the headers in the selected email, even though it works on the Web or on the old version of Outlook.
I'm using the following method to load the headers:
private _loadHeaders(): Promise<string> {
return new Promise((resolve, reject) => {
this.mailbox.item.getAllInternetHeadersAsync(({ status, value, error }) => {
if (status === Office.AsyncResultStatus.Succeeded) {
const header = value.replace(/[\r\n]+? ?=\?[a-z\-]+\?[A-Z]{1}\?([\S]+)\?=?/g, (_, data) => data.replace("=2E", ".").replace("=5F", "_"));
return resolve(header);
} else {
return reject(error);
}
});
});
}
and have the following permissions in my manifest:
<Permissions>ReadWriteMailbox</Permissions>
Any help would be really appreciated. Thanks!
Turns out that getAllInternetHeadersAsync
is only available in requirement set 1.8
which is not supported by the iOS or the modern mac app in August 2020. The solution is to use Exchange rest requests. I'm sharing the code I used, in case anyone might need it in the future (typescript).
private get _itemRestId() {
if (this._mailbox.diagnostics.hostName === 'OutlookIOS') {
// itemId is already REST-formatted
return this._mailbox.item.itemId;
} else {
// Convert to an item ID for API v2.0
return this._mailbox.convertToRestId(
this._mailbox.item.itemId,
Office.MailboxEnums.RestVersion.v2_0
);
}
}
private get _headersUrl() {
return `${this._restUrl}/v2.0/me/messages/${this._itemRestId}?$select=*,internetMessageHeaders`;
}
private get _accessToken(): Promise<string> {
return new Promise((resolve, reject) => {
this._mailbox.getCallbackTokenAsync({ isRest: true }, ({ status, value, error }) => {
if (status === Office.AsyncResultStatus.Succeeded) {
return resolve(value);
} else {
return reject(error)
}
});
});
}
get headers(): Promise<string> {
return this._accessToken
.then(accessToken => fetch(this._headersUrl, {
headers: {
'Content-Type': 'application/text',
'Authorization': 'Bearer ' + accessToken
}
}))
.then(response => response.json())
.then(data => data.InternetMessageHeaders.reduce((carry, item) => `${carry}\n\r${item.Name}: ${item.Value}`, ""));
}