Search code examples
javascriptapiexchangewebservicesoffice-addins

Convert ItemId (EwsId) into EntryId in office addin


I have an office addin (js), and I need this EntryId property to identify mails (I use this EntryId in a VSTO plugin, need it for BC)

After searching I have tried ConvertId operation but I always get a This request is invaild response.

It turns out, ConvertId is not supported when using makeEwsRequestAsync call.

So I thought about getting messages headers using GetItem but the PR_ENTRYID header is not returned:

        <?xml version="1.0" encoding="utf-8"?>
        <soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="https://www.w3.org/2001/XMLSchema"
            xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
            <soap:Header>
                <RequestServerVersion Version="Exchange2013" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" soap:mustUnderstand="0" />
            </soap:Header>
            <soap:Body>
                <GetItemInfo xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
                    <ItemShape>
                        <t:BaseShape>AllProperties</t:BaseShape>
                    </ItemShape>
                    <ItemIds><t:ItemId Id="${itemId}"/></ItemIds>
                </GetItemInfo>
            </soap:Body>
        </soap:Envelope>

tl;dr: So what is the way to convert EwsId to EntryId in Office Addin ?


Solution

  • I solved it, ended up using GetItem operation with ExtendedFieldURI:

        import xpath from 'xpath';
        import { DOMParser } from 'xmldom';
        import { Buffer } from 'buffer';
    
        private getEntryIdFromItemId(itemId: string): Promise<string>
        {
            const request = `<?xml version="1.0" encoding="utf-8"?>
            <soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
                xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
                <soap:Header>
                    <RequestServerVersion Version="Exchange2013" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" soap:mustUnderstand="0" />
                </soap:Header>
                <soap:Body>
                    <GetItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
                        <ItemShape>
                            <t:BaseShape>IdOnly</t:BaseShape>
                            <t:AdditionalProperties>
                              <t:ExtendedFieldURI PropertyTag="0x0FFF" PropertyType="Binary" />
                            </t:AdditionalProperties>
                        </ItemShape>
                        <ItemIds><t:ItemId Id="${itemId}"/></ItemIds>
                    </GetItem>
                </soap:Body>
            </soap:Envelope>`;
            return new Promise((resolve, reject) => {
                Office.context.mailbox.makeEwsRequestAsync(request, async (asyncResult) => {
                    if(asyncResult.status == Office.AsyncResultStatus.Failed)
                    {
                        reject();
                        return;
                    }
    
                    const doc = new DOMParser().parseFromString(asyncResult.value);
                    const entryId = xpath.select("//*[local-name()='Value']", doc)[0] as Node;
                    const entryIdHex = new Buffer(entryId.textContent!, "base64").toString("hex").toUpperCase();
                    resolve(entryIdHex);
                });
            });
        }
    

    Also had to convert the returned base64 value to an hex value, since thats what Outlook client uses.

    If you wonder how I figured the 0x0FFF value part, here is how.