Hi all,

You'll find a description with better images there !

This is the result we expect :Capture d’écran 2015-11-26 à 12.23.05.png

I'd like to share with you THE CODE !
It's extremely easy : everything is done with JavaScript.

First things first : to embed a tile from Power BI, you have to know its URL, to put in into the Iframe !

Prerequisites :
1. A Power BI report uploaded on the Power BI Portal
2. Tile(s) pined on a dashboard, on the Power BI Portal
Sound's like this :
Capture d’écran 2015-11-28 à 12.16.52.png

Let's code !
3. Get the URL of the tile you want to embed. Please use : apiary.io

You have to authenticate with your O365 account on it, and add an Application on your Azure AD, extremly simple :Capture d’écran 2015-12-06 à 10.20.26.png

Authentication :

Capture d’écran 2015-12-06 à 10.20.49.png

Allow Apiary to connect to Power BI Service

Capture d’écran 2015-12-06 à 10.21.00.png

Back to Apiary, "switch to code" and then, "Call ressource"

Capture d’écran 2015-12-06 à 10.21.16.png

Scroll down to the "Body", and find the JSON ! Get the ID of the dashboard you want.

Capture d’écran 2015-12-06 à 10.21.40.png

List all tiles of the dashboard !

Capture d’écran 2015-12-06 à 10.22.05.png

Get the embed URL of the tile you want to show in SharePoint/Website.

Capture d’écran 2015-12-06 à 10.22.48.png

Let's go to Visual Studio !
I'm going to show you a SharePoint Online integration, so you have to install Office Dev Tools with your Visual Studio.

New Project and create a Provider Hosted App

Capture d’écran 2015-12-06 à 10.45.52.png

Capture d’écran 2015-12-06 à 10.46.35.png

Get connect, then...

Capture d’écran 2015-12-06 à 10.47.19.png

Note that I choose an MVC app because I must use MVC every time it's possible for me (to learn it). You can use a web forms app if you want. The JS code I'll show later won't be change.

Capture d’écran 2015-12-06 à 11.23.58.png

Capture d’écran 2015-12-06 à 11.24.20.png

 

Now, we are really happy to have an app. But, before going further, we have to create and set an application in your Azure AD (the Azure AD used by your Office 365 Tenant).

So, go to your Azure Portal (if you didn't dit it already, subscribe on Azure with your Office 365 Admin account, you'll see your Azure AD after that).

Capture d’écran 2015-12-06 à 11.40.35.png

Capture d’écran 2015-12-06 à 11.41.53.png

Capture d’écran 2015-12-06 à 11.42.01.pngCapture d’écran 2015-12-06 à 11.42.33.png

Back to Visual Studio, you need to get an information there !

Capture d’écran 2015-12-06 à 11.43.10.png

Back to Azure !

Capture d’écran 2015-12-06 à 11.43.34.png

You're AAD Application has been created. Now clic on "Configure"

Capture d’écran 2015-12-06 à 11.44.04.png

Scroll down and and "Add an application"Capture d’écran 2015-12-06 à 11.44.26.png

Select "Power BI Service"

Capture d’écran 2015-12-06 à 11.44.37.png

Give authorizations ! And Save !

Capture d’écran 2015-12-06 à 11.44.56.png

Scroll up and copy the Client ID of the app. Paste it in a notepad.

Capture d’écran 2015-12-06 à 11.45.35.png

Then, we have to make a few changes in the AAD Application JSON configuration. It's needed to make it works with our Javascript authentication code. So, go back on the dashboard of your AAD Application.

Download the manifest

Capture d’écran 2015-12-06 à 11.54.11.png

Open it, and set the value of the parameter "oauth2AllowImpliciteFlow" to "true". Save the file.Capture d’écran 2015-12-06 à 11.55.43.png

Re-upload it in AzureCapture d’écran 2015-12-06 à 11.55.55.pngCapture d’écran 2015-12-06 à 11.56.11.png

 

Nice ! Everything is ready. Now we can code !!! Go back to Visual Studio !

Let's prepare the app.
Change your HomeController.cs, so it'll seem like this (don't forget to remove the [SharePointContextFilter]).

Capture d’écran 2015-12-06 à 14.35.21.png

Comment the code in _ViewStart.cshtml

Capture d’écran 2015-12-06 à 14.01.34.png

 

Now, we add the HTML code to "Index.cshtml"

In this example I will embed three tiles ; so I've added three iFrame elements.

 <div>  
     <table>  
       <tr>  
         <td colspan="2">  
           <!--Top des likeurs-->  
           <iframe ID="iFrameEmbedTile3" src="" height="280px" width="900px" frameborder="0" seamless></iframe>  
         </td>  
       </tr>  
       <tr>  
         <!--Like par auteurs-->  
         <td><iframe ID="iFrameEmbedTile1" src="" height="350px" width="600px" frameborder="0" seamless></iframe></td>  
         <!-- Nombre total de likes-->  
         <td><iframe ID="iFrameEmbedTile2" src="" height="350px" width="300px" frameborder="0" seamless></iframe></td>  
       </tr>  
     </table>  
   </div>  

And the JS code !

Line 13 to 19, you'll see three call to "UpdateEmbedTile". The first parameter is the ID of the iFrame you add in the HTML, the second parameter is the "embedUrl" we get with Apiary. You have to set it to your own value.

In the function requestToken(), don't forget to change the var "clientId" with the client ID of your AAD application (you've just copied to the notepad) and, if needed, the redirectUrl, with the SSL Url of your application.

 <script type="text/javascript" src="/Scripts/jquery-1.10.2.min.js"></script>  
   <script type="text/javascript">  
     //https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-integrate-a-power-bi-tile-or-report/  
     var token = null;  
   
     $(document).ready(function () {  
   
       //Get Token  
       if (urlParameterExtraction.queryStringParameters['access_token'] == null) { requestToken(); }  
       // Extract token from urlParameterExtraction object.  
       token = urlParameterExtraction.queryStringParameters['access_token'];  
   
       //Like par auteurs  
       updateEmbedTile("iFrameEmbedTile1", "https://app.powerbi.com/embed?dashboardId=c822f941-7d5a-4769-abf3-0bfdfe7d202b&tileId=bd39ae2a-5499-44c9-81e7-212e4ddc7e9e", 300, 450);  
       //Nombre total de likes  
       updateEmbedTile("iFrameEmbedTile2", "https://app.powerbi.com/embed?dashboardId=c822f941-7d5a-4769-abf3-0bfdfe7d202b&tileId=98c7349d-0c80-4054-a9db-f556fb99acc1", 300, 250);  
       //Top des likeurs  
       updateEmbedTile("iFrameEmbedTile3", "https://app.powerbi.com/embed?dashboardId=c822f941-7d5a-4769-abf3-0bfdfe7d202b&tileId=8dc31946-6b46-4f60-9316-1a7fcd6a5ead", 250, 800);  
   
     });  
   
   
     //**********************//  
     //***TILE MANAGEMENT***//  
     //********************//  
     function updateEmbedTile(iFrameId, embedTileUrl, h, w) {  
       console.log("updateEmbedTile");  
       // check if the embed url was selected  
       if ("" === embedTileUrl)  
         return;  
   
       // to load a tile do the following:  
       // 1: set the url, include size.  
       // 2: add a onload handler to submit the auth token  
       iframe = document.getElementById(iFrameId);  
       iframe.src = embedTileUrl + "&width=" + w + "&height=" + h;  
       iframe.onload = function () { postActionLoadTile(iFrameId, h, w); }  
     }  
     function postActionLoadTile(iFrameId, h, w) {  
       console.log("postActionLoadTile");  
       // get the access token.  
       accessToken = token;  
   
       // return if no a  
       if ("" === accessToken)  
         return;  
   
   
       // construct the push message structure  
       var m = { action: "loadTile", accessToken: accessToken, height: h, width: w };  
       message = JSON.stringify(m);  
   
       // push the message.  
       iframe = document.getElementById(iFrameId);  
       iframe.contentWindow.postMessage(message, "*");;  
     }  
   
     //************************//  
     //********UTILS**********//  
     //**********************//  
     function requestToken() {  
       // Change clientId and replyUrl to reflect your app's values  
       // found on the Configure tab in the Azure Management Portal.  
       // Also change {your_subdomain} to your subdomain for both endpointUrl and resource.  
       var clientId = 'dd4870e9-992c-4e26-b464-28f66a738930';  
       var replyUrl = 'https://localhost:44300';  
       var resource = "https://analysis.windows.net/powerbi/api";  
       var authServer = 'https://login.windows.net/common/oauth2/authorize?';  
       var responseType = 'token';  
   
       var url = authServer +  
            "response_type=" + encodeURI(responseType) + "&" +  
            "client_id=" + encodeURI(clientId) + "&" +  
            "resource=" + encodeURI(resource) + "&" +  
            "redirect_uri=" + encodeURI(replyUrl);  
   
       window.location = url;  
     }  
   
     //***  
     //URL EXTRACTION  
     var urlParameterExtraction = new (function () {  
       function splitQueryString(queryStringFormattedString) {  
         var split = queryStringFormattedString.split('&');  
   
         // If there are no parameters in URL, do nothing.  
         if (split == "") {  
           return {};  
         }  
   
         var results = {};  
   
         // If there are parameters in URL, extract key/value pairs.  
         for (var i = 0; i < split.length; ++i) {  
           var p = split[i].split('=', 2);  
           if (p.length == 1)  
             results[p[0]] = "";  
           else  
             results[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));  
         }  
   
         return results;  
       }  
   
       // Split the query string (after removing preceding '#').  
       this.queryStringParameters = splitQueryString(window.location.hash.substr(1));  
     })();  
   </script>  
   

 

On the SharePoint part of the project, we will add a Client Web Part to embed our page that contains tiles.Capture d’écran 2015-12-06 à 13.41.12.png

 

Capture d’écran 2015-12-06 à 13.41.37.png

Capture d’écran 2015-12-06 à 13.42.12.png

In the Elements.xml of your webpart, change the code with that :

 <?xml version="1.0" encoding="utf-8"?>  
 <Elements xmlns="http://schemas.microsoft.com/sharepoint/">  
  <ClientWebPart Name="Embed Power BI Tiles" Title="Embed Power BI Tiles" Description="Show Embed Power BI Tiles" DefaultWidth="900" DefaultHeight="2000">  
   
   <!-- Content element identifies the location of the page that will render inside the client web part  
      Properties are referenced on the query string using the pattern _propertyName_  
      Example: Src="~appWebUrl/Pages/ClientWebPart1.aspx?Property1=_property1_" -->  
   <Content Type="html" Src="~remoteAppUrl" />  
   
   <!-- Define properties in the Properties element.  
      Remember to put Property Name on the Src attribute of the Content element above. -->  
   <Properties>  
   </Properties>  
   
  </ClientWebPart>  
 </Elements>  
   


You can now press F5 and launch the debug ! 
Allow the app in your SharePoint.

The first thing you'll see in your web browser will be a page with your tiles.

Capture d’écran 2015-12-06 à 14.57.28.png

Now, go to your SharePoint, add a page, edit it and add a webpart. Choose the webpart we add in the Add In !Capture d’écran 2015-12-06 à 13.44.51.png

And that's it !

Capture d’écran 2015-12-06 à 15.00.08.png

 

Before upload it in production environment, don't forget to change redirection address in your AAD Application AND in your JS code.

Note that I tried the API to embed some reports, but it seems to be a little bit buggy, so I'm in touch with Power BI team to see how we can fix it !

Do not hesitate to ask if you meet any issue !