Mechanism for determining EWS and REST URL - outlook

I have what I hope is a quick question. We are trying to track down why a specific EWS/REST API URL is being returned in OWA by Office Add-ins. Are you able to share the mechanism by which the REST and EWS URLs are determined when running Office.context.mailbox.ewsUrl (or .restUrl). How does the framework determine the right URL to use when in OWA. It doesn't appear to make any extra calls to Exchange. The specific JS in use is outlook-web-16.01.js. It looks like when the Extensions load a service.svc action called GetExtensibilityContext is used and this returns the EWS and REST URLs. However, we were hoping for some more information about what properties in Exchange would impact which URL is used here.
What we are seeing external URLs returned that are only set on four servers where other servers in the environment do not have an external URL set, including the servers where the mailbox in question resides.
Is it designed that if there's an external URL set anywhere in the environment, that is what is returned for the EWS/REST URLs?

Whenever an add-in is launched, it creates an instance of an office object inside the global window object.
Many of the common attributes are stored in that instance of the office itself.
Like ItemId of the item on which the add-in has been opened.
For instance, you can check all the office attributes in the console itself.
Switch the Javascript context to the iframe (since add-ins are loaded inside an iFrame).
Then console log the window.office.context.mailbox object. You'll find all the attributes stored with respect to the item there.
Hope it answers your query.

Related

Outlook addin - js or api generate email file

I have an outlook addin that I've built using Yeoman. The addin communicates with a server API on my server to combine data from an email with additional data from a database that a user has saved against an email address. This is all working great.
Next I want to store a copy of the email server side, as a file on disk, .msg preferred but I'll take a .eml if thats the only option.
I have 2 options but don't know if either are possible. Either the addin generates the .msg file and posts it to the server API OR the server side API generates the .msg file directly. I have got the server side using the Outlook v2 API and able to pull back the email information when the client passes it the token, id etc. If it could just generate/download a .msg file server side this would be ideal.
As a side note, many of the Microsoft API pages point out the deprecation of the Outlook API in favor of the Graph API, however there are inconsistent links between the pages and it get confusing. I have discovered the token from getCallbackTokenAsync only works with the Outlook API and not Graph, but I cant find out a way to generate a graph compatible token. All the example code from MS uses Office.context.mailbox.restUrl which still gives the Outlook API url and not Graph!
So I guess I'm trying to find out if it's even possible to get/generate a .msg or .eml file either client side using outlook.js or server side using one of the api's. Thank you.
I can get message data both client and server side but cannot get a physical email file.
The Office JavaScript API (OfficeJS) doesn't provide anything for saving messages as msg files (or getting streams). The best what you could do is to use Graph API where you could get the EML file, see Get MIME content of a message for more information.
The server-side code may use the OAuth 2.0 On-Behalf-Of flow (OBO) to request a new access token with permissions to Microsoft Graph. Read more about that in the Authorize to Microsoft Graph with SSO article.
The on-behalf-of (OBO) flow describes the scenario of a web API using an identity other than its own to call another web API. Referred to as delegation in OAuth, the intent is to pass a user's identity and permissions through the request chain.
For the middle-tier service to make authenticated requests to the downstream service, it needs to secure an access token from the Microsoft identity platform. It only uses delegated scopes and not application roles. Roles remain attached to the principal (the user) and never to the application operating on the user's behalf. This occurs to prevent the user gaining permission to resources they shouldn't have access to. See Microsoft identity platform and OAuth 2.0 On-Behalf-Of flow for more information.
Eugene's answer is good. If ultimately you need to get that message to your backend service, using Graph as Eugune described would be the recommended approach. If for whatever reason you are still looking for a capability to access it on client using Office.js, it is not a part of the product. We track Outlook add-in feature requests on our Tech Community Page. Please submit your request there and choose the appropriate label(s). Feature requests on Tech Community are considered, when we go through our planning process. Note there is already a couple of similar ideas there, if you search for "eml" keyword, that you may want to upvote.

how to get full path of attachment in office outlook add in?

Is there any way to get the full path of an outlook add in attachment? Checking the api I only find that it returns the content of the file. I need the path to pass it to a third party library.
Outlook does not store attachments as files. They are stored inside the mailbox and only exist in the context of the parent messages.
As a rule attachments are not saved automatically to the disk until users open them. So, you need to save the attached file to the disk first. Typically attachments are kept in the data store in the Outlook profile.
If you develop a COM add-in you need to save the attached file on the disk by using the Attachment.SaveAsFile method and then pass the file path to a third-party library.
But in case of web add-ins there is no disk APIs due to security reasons (web add-ins are run in a sandboxed environment), so you may pass the attachment content to any web service for processing, see Get attachments of an Outlook item from the server for more information.

MS Teams custom tab app changes Session.SessionID between requests

I'm making a custom tab app of MS Teams with ASP.NET, however, the tab doesn't seem to pass a same cookie between requests on MS Teams. So the ASP.NET app behind the tab generates a new Session.SessionID on every request.
I've checked the following question, and tried some settings according to that page, but nothing helped me. Actually my web site works nicely if I navigate it via Chrome or Edge.
ASP.NET: Session.SessionID changes between requests
How do I get a same cookie between requests on MS Teams?
I've not tested this specifically so haven't seen it, but basically the broad idea of session is to have to uniquely "remember" a user, and then restore State for them from a location (e.g. database). From your question, it seems like the out of box "Session" object is giving trouble, but at any rate you should probably avoid using it because it won't "remember" the user even across devices.
However, Teams provides you a way to achieve the same thing yourself quite easily. Remember that the Teams 'Context' object provides a userObjectId property that is unique and valid for the same user on all sessions on all devices (it's actually their Azure Active Directory id). You can simply store whatever you want in your own database, key'ed by this id, and request it on page load. It's also possible to get this from the querystring for a static (personal) tab if you want to handle the behaviour server-side (e.g. C#).

How to make Office Web App Server able to edit a document with Cobalt

I am trying to build my own WOPI host using ASP.NET MVC and its WebAPI functions according to this example
https://code.msdn.microsoft.com/office/Building-an-Office-Web-f98650d6
I successfully used that example to connect to my Office Web App Server and I can use that to access files of Excel and PowerPoint in local path and I am able to edit it, but I cannot use it to open word document in editing mode as the Post action handler isn't implemented completely without any response so that it cannot handle any edit request.
In order to add support for editing of Office document, I tried this example with POST request handler based on Cobalt library extracted from Office Web App Server.
https://github.com/marx-yu/WopiHost
With this example I managed to edit ans save all kinds of document with Office Web App Server. However, when I tried to integrate these two together I found that even if I can enter the edit window of Excel and PowerPoint and I can see that Post Requests from Office Web App Server like locking and Cobalt are handled by my WOPI Post API action handler. Those change doesn't take any effect on my local file at all. Moreover, I still cannot edit word document and when I checked the back log of Office Web App Server, I found the error message is Cobalt is not supported while I have already set the SupportsCobalt in CheckFileInfo response to true! Any help is very appreciated!
I think I have exactly what you are looking for. Check out my implementation of the WOPI host. It's an MVC6 app that takes the best from the both examples you are referring to and adds some extra features.

Multiple calls to ServiceObject.Load without reloading data

I'm building an object model layer on top of EWS, and am exposing an object that is an EmailMessage, internally, that has several standard properties which I load on startup, and allow the user to have different "views" on that object (ViewAsEntity1, ViewAsEntity2) which loads other custom properties on demand (some are Extended Properties, some Internet Headers).
The problem is that I call Item.Bind() with one PropertySet (the standard properties), but when the user asks to ViewAsEntity1, I call ServiceObject.Load() with the new PropertySet, which either means I lose the original set of properties, or I re-retrieve them.
So my question are:
1) If I call ServiceObject.Load twice, with the same properties in the PropertySet, does Exchange really send the same data over, or does it assume I already have it cached (if it is unchanged), and doesn't send it again? And if so, does EWS know not to clobber the existing data in the PropertyBag?
2) If the answer to #1 is no, what's the best way to avoid expensive EWS calls again and again? I was hoping to keep my Object Model layer thin and simply refer calls to properties into the internal EWS Item object, but if #1 is wrong, I guess I'll have to copy all the data to my objects manually. Is there a better way?
I'm using .NET 4.5, Managed EWS 2.0 and Exchange 2010 SP1
I have taken a look at the code for the EWS Managed API. It seems that every time you call ´ServiceObject.Load()´, the managed EWS API will send an HTTP request to your Exchange server. There is no caching built into the managed API when using ´ServiceObject.Load()´ which is good in my opinion. How would the API know when the item on the server has changed and you need a refresh?
There may be some caching on the Exchange server - who knows - but you still have to make the HTTP call.
If you want to spare some HTTP calls you have to build caching into your own client.

Resources