Showing posts with label SharePoint Online. Show all posts
Showing posts with label SharePoint Online. Show all posts

Saturday, November 7, 2015

Embed an Office Group Conversation into SharePoint Online using a JavaScript App, CORS, and the Office 365 Unified API

I am very happy to publish a post where I can use the brand new Office 365 unified API to embed a conversation of the brand new Office Group into a SharePoint Online page!


1 - Architecture
A SharePoint Online html page sends an Ajax request to the Office 365 Unified API and get the data of the Office Group.(The SharePoint Online site and the Office Group belong of course to the same Office 365 tenant).
It seems simple at first but it wasn't possible since recently. Why?
Because of the different hostheaders of the different part of Office 365, You can check while navigating through Office 365. For example, recently I created an Office 365 environment and first registered as contososoftware. My domain was contososoftware.onmicrosoft.com. Then I had to buy a domain to activate Yammer (You should have a verified domain in Office 365 to have Yammer activated to Enterprise. The "onmicrosoft.com" is not a domain but an Office 365 tenant name or a default domain and cannot be used to activate Yammer Enterprise. So I bought marccharmois.com.
(roughly 14 US$ a year, not a big deal). After that, when I go to
  • My mail, My calendar, My contacts (people), My Tasks, the Url starts with https://outlook.office.com/owa/?realm=marccharmois.com#path=
  • NewsFeed, OneDrive, Sites, Delve, Video, the Url starts with https://contososoftware-my.sharepoint.com/
  • Yammer, the Url starts with https://www.yammer.com/marccharmois.com/
  • a SharePoint Online site, the Url starts with https://contososoftware.sharepoint.com/
So if I want to deploy an html page somewhere Online in Office 365 and make an Ajax request to a part that has a different hostheader (for example displaying some of my mails into a SharePoint Online page), it normally doesn't work because crosss domain Ajax requests are forbidden by the browsers. It is worse if my HTML page is deployed on a server.
Cross-origin resource sharing (CORS) is a mechanism that allows that. CORS defines a way in which a browser and server can interact to safely determine whether or not to allow the cross-origin request. It allows for more freedom and functionality than purely same-origin requests, but is more secure than simply allowing all cross-origin requests. It is a recommended standard of the W3C. (Wikipedia)
Of course Microsoft sets up Cors within Office 365 in order developers to be allowed to performed Ajax requests without being bothered by the different hostheaders of Office 365.
The CORS of Office 365 is based on Microsoft Azure:
  • You register an App in Azure and you are provided with ID's that you place in your code.
  • In the Azure App, you also reference the Urls of the pages that are planned to call the Office 365 API with cross domain requests
This double registration allows the CORS of Office 365 to properly work and also manage the oauth authentication.

That leads to the fact that the term "Application" or App has a double meaning. It could be:
  • The pages that you have deployed somewhere on a server or within the Office 365 cloud (for example SharePoint Online) and that performs the Ajax requests and displays the data. Let's call this the physical part of the App, or the physical App
  • The Application that you had to add to Azure for getting the Office 365 CORS and the oauth authentication to work. Let's call that the virtual part of the App, or the virtual App
In the case of this tutorial, my physical App is just an html page added to a SharePoint Online team site using explorer mode (WebDAV protocol)
It is very similar of what I did when I embedded a Yammer conversation within SharePoint Online. This is super convenient because I can program and deploy quickly a physical App in Office 365 based on an html page that uses only Javascript!
It could seem a little bit difficult to understand at this point of the post, but I will explain all the operations to do it step by step with all the detailed screenshots as usual, so don't worry. I also did a diagram that can summarize all this in a clearer way:



2 - What you need to do this tutorial
You need:
Once you can access to an Office 365 environment using a business account with global administrator privileges, the first thing you need to do is register your application with Azure AD.

3 - Creating the (virtual) App within Microsoft Azure
3.1 Create a new subscription to Microsoft Azure
To Navigate to the Azure Portal you can use this link: https://manage.windowsazure.com/
you can also access to it within 0ffice 365:
Log on to Office 365. From the Home page, select the Admin icon to open the Office 365 admin center.



In the menu page along the left side of the page, scroll down to Admin and select Azure AD.



If prompted, log in using the credentials you created for your O365 subscription.



After logging in, you should see a screen notifying you that you do not have a subscription



Create a new subscription.
If you're using a trial version of Office 365, you'll see a message telling you that Azure AD is limited to customers with paid services. You can still create a trial 30-day Azure subscription at no charge, but you'll need to perform a few extra steps:
Select your country or region, and then choose Azure subscription.
Enter your personal information. For verification purposes, enter a telephone number at which you can be reached, and specify whether you want to be sent a text message or called.
Once you've received your verification code, enter it and choose Verify code.
Enter payment information, check the agreement, and select Sign up.
Your credit card will not be charged.
Do not close or refresh your browser while your Azure subscription is being created.
Once your Azure subscription is created, choose Portal.
The Azure Tour appears. You can view it, or choose X to close it.
You should now see all items in your Azure subscription. It lists a directory with the name of your Office 365 tenant.

3.2 Register your App in Azure Management Portal

Once signed in, follow these instructions:
Click the Active Directory node in the left column and select the directory linked to your Office 365 subscription.



Select the Applications tab and then Add at the bottom of the screen.





On the pop-up, select Add an application my organization is developing.



Choose an explicit name for your app,(I took Embed-OfficeGroup), and select Web application and/or web API as its Type. Then click the arrow to continue.



The value of Sign-on URL is the URL where your application will be hosted. As I will call the App using JavaScript within a SharePoint page, I put the Url of my SharePoint site.
The value of App ID URI is a unique identifier for Azure AD to identify your app. You can use http://{your_subdomain}/{YourAppName}, where {your_subdomain} is the subdomain of .onmicrosoft you specified while signing up for your Office 365 Developer Site. Then click the check mark to provision your application. For example, my Office 365 global admin account is, in this tutorial case:

marc.charmois@marccharmois.onmicrosoft.com





Now that your app has been provisioned, select the Configure tab.



Scroll down to the permissions to other applications section and click the Add application button.



In this tutorial, we want our App to read the conversation of an Office group. To access to the Office Group we have to use the new Office 365 Unified API.
Click the plus sign in the application's row and then click the check mark at the top right to add it. Then click the check mark at the bottom right to continue.



In the Office 365 Unified API row, select Delegated Permissions, and in the selection list, choose Read All Groups.



Click Save to save the app's configuration.







3.3 Configure your app to allow the OAuth 2.0 implicit grant flow


In order to get an access token for Office 365 API requests, your application will use the OAuth implicit grant flow. You need to update the application's manifest to allow the OAuth implicit grant flow because it is not allowed by default.
Select the Configure tab of your application's entry in the Azure Management Portal.


Using the Manage Manifest button in the drawer, download the manifest file for the application and save it to your computer.









Open the manifest file with a text editor. Search for the oauth2AllowImplicitFlow property. By default it is set to false; change it to true and save the file.



Using the Manage Manifest button, upload the updated manifest file.







You've now successfully registered your application with Azure AD.

4 - Coding the SharePoint page (physical App) that's using the Azure App (Virtual App)

4.1 Creating the app.html page

In your 0ffice 365 environment, create a new site collection. Once it's done, navigate to the "Site Assets" library. Open the library in Explorer mode




and using the window navigate to the root folder of your site. Create an html page within the folder and name it app.html



You can now open this page with Visual Studio or Notepad ++ and start to programm the displaying of the Office Group conversation



You can find the complete app.html page in the dedicated Github repository

4.2 Determine the resource endpoint

In order to make any API requests, you'll need to determine the correct endpoint of the resource you want to use. The endpoint you'll use is determined by what information you want from Office 365. Refer to the API reference documentation to get the endpoint you want.
Mail API reference
Contacts API reference
Calendar API reference
Files API reference
Alternatively, you can take advantage of the Office 365 unified API (preview) to access all of the APIs from a single endpoint, https://graph.microsoft.com. Refer to the Office 365 unified API reference to browse all of the supported endpoints.
For this sample, we will use the Office 365 unified API to get a conversation of an Office Group. The endpoint for this operation is
https://graph.microsoft.com/beta/{your_domain}/groups, where {your_domain} is the domain you specified while signing up for your Office 365 Developer Site. In my case marccharmois.onmicrosoft.com.

My endpoint is: https://graph.microsoft.com/beta/marccharmois.onmicrosoft.com/groups

4.3 Get an access token from Azure

Office 365 uses OAuth 2.0 tokens issued by Azure AD to authenticate JavaScript clients. Tokens are obtained using the OAuth 2.0 implicit grant flow. Using implicit grant, your application requests an access token from Azure AD for the currently signed-in user by sending the user to an authorization URL where the user signs in with their Office 365 credentials and then is redirected back to the app with the access token in the URL.
The following function builds the authorization URL and navigates to it to begin the authentication process.

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    = 'e77659cc-bf72-4276-bd33-bdd876660a74';//ID of your App in Azure
  var replyUrl    = 'https://marccharmois.sharepoint.com/sites/intranet/app.html'; //my sharepoint page that requests an oauth 2 authentification and data
  //It is also referenced in the REPLY URL field of my App in Azure
  var endpointUrl = 'https://graph.microsoft.com/beta/marccharmois.onmicrosoft.com/groups';
  //var endpointUrl = 'https://marccharmois-my.sharepoint.com/_api/v1.0/me/files';//getting files from SharePoint
  //var endpointUrl = 'https://outlook.office.com/api/V1.0/me/messages';//getting messages  from outlook
  var resource = "https://graph.microsoft.com/";
  //var resource = "https://marccharmois-my.sharepoint.com"; //getting files from SharePoint
  //var resource = "https://outlook.office.com"; //getting messages  from outlook
  
  var authServer  = 'https://login.windows.net/common/oauth2/authorize?';  
  //var authServer  =  'https://login.microsoftonline.com/common/oauth2/authorize?';//this works either
  var responseType = 'token'; 

  var url = authServer + 
            "response_type=" + encodeURI(responseType) + "&" + 
            "client_id=" + encodeURI(clientId) + "&" + 
            "resource=" + encodeURI(resource) + "&" + 
            "redirect_uri=" + encodeURI(replyUrl); 

  window.location = url; 
}

At this point what's going on?
When I use this function, I am redirected to the same page, but with the acces token in the Url as a parameter:





I can even display the token

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)); 
})(); 



function displayToken(){
// Extract token from urlParameterExtraction object.
var token = urlParameterExtraction.queryStringParameters['access_token'];
alert('token : \n'+ token);
}

Now that I have the token, here is the code to request the Office 365 Unified API to get all the specific conversation of an Office Group:
function getToken(){

var token = urlParameterExtraction.queryStringParameters['access_token'];
return token;
}

function getGroupsFromO365() { 
  try 
  { 
    //var endpointUrl = 'https://graph.microsoft.com/beta/marccharmois.onmicrosoft.com/groups'; //getting all groups to get the ID of the group you want
 //var endpointUrl = 'https://marccharmois-my.sharepoint.com/_api/v1.0/me/files';//getting files from SharePoint
 //var endpointUrl = 'https://outlook.office.com/api/V1.0/me/messages';//getting messages from SharePoint
 var endpointUrl = "https://graph.microsoft.com/beta/contoso.com/groups('4eba7454-b490-46ae-bb5e-774efaec7c6f')/conversations('AAQkADZjOTdkMTIwLWFjNTItNDUyYy05MTc4LTg1NmJmMDk1MjYxOQAQAD_Ql6WI-GlHs3VmVZsV3QA=')/threads('AAQkADZjOTdkMTIwLWFjNTItNDUyYy05MTc4LTg1NmJmMDk1MjYxOQMkABAAP5CXpYj8aUezdWZVmxXdABAAP5CXpYj8aUezdWZVmxXdAA==')/Posts";

    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", endpointUrl); 
    var myToken = getToken();
    // The APIs require an OAuth access token in the Authorization header, formatted like this: 'Authorization: Bearer '. 
    xhr.setRequestHeader("Authorization", "Bearer " + myToken); 

    // Process the response from the API.  
    xhr.onload = function () { 
      if (xhr.status == 200) { 
     //alert('data received');
  var message="";  
  var object = JSON.parse(xhr.response); 
  for(i=0;i<object.value.length;i++){
  message+='From: ' + object.value[i].From.EmailAddress.Name + '<BR>';
  message+='At: ' + object.value[i].CreatedDateTime + '<BR>';  
  message+= object.value[i].Body.Content + '<BR>';  
  }
        //var formattedResponse = JSON.stringify(JSON.parse(xhr.response), undefined, 2);
        document.getElementById("results").innerHTML = message;
      } else { 
        document.getElementById("results").textContent = "HTTP " + xhr.status + "<BR>" + xhr.response; 
      } 
    } 
    // Make request.
    xhr.send(); 
  } 
  catch (err) 
  {  
    document.getElementById("results").textContent = "Exception: " + err.message; 
  } 
}
Now, you can display this app.html into any SharePoint page by calling it within an iframe tag...
<span style="display:block;margin-bottom:3px;font-size;13px;">Embedded Office Group Conversation:</span> <iframe src="https://marccharmois.sharepoint.com/sites/intranet/app.html" style="height:400px;width=300px;border:solid 1px silver"></iframe>
As I did for this Web Part page;
5 - Aknowledgements

Tuesday, October 27, 2015

Programmatically post a message to Yammer from SharePoint Online

In my previous post, I showed how to programmatically embed a Yammer feed into a SharePoint Online page, using the JavaScript SDK for Yammer and the Yammer REST API. In this post I will show how to post a message into a Yammer group from a SharePoint Online page, using again the JavaScript SDK for Yammer and the Yammer REST API.



1 - Adding a new feature to post a message to a Yammer group, from SharePoint on line


In my previous post (the one for displaying the Yammer feed into SharePoint Online) I have explained why you have to create a Yammer App and how to do it. I also explained the basis of programming for Yammer with the Yammer Javascript SDK and the REST API. I advice you to do the previous tutorial.

Here, I will just explain some pieces of the code. You will find the complete page on the dedicated GitHub repositery.

The first function gets the Yammer topic value (selected by the user with the radio button). It is the place to manage authentication if needed. I have managed authentication for the getMyFeed function. It is explained also in the previous post.

function postMessage() {
   topicToPost=getTopicValue();
   yamPostRequest(this);
   /*If needed you have to manage authentication as in the script "authentication" I used for getting the feed (line 130)*/
   }

then you send the post to Yammer after having checked that no elements are missing. Because you cannot send a topic with an empty value you have to check if there is a topic:
if (topicToPost.length>0){
     yam.platform.request(
     { 
       url: "https://api.yammer.com/api/v1/messages.json"
       , method: "POST"
       , data: {
         "body" :  msg_value
        ,"group_id" : groupID
        ,topic1 : topicToPost
        ,"cc": "[[user:1557787745]],[[user:1557794361]]"//use your own user ID to notify them
        //,direct_to_id : "1537569057" seems not to work
        ,"skip_body_notifications" : "true"
      }
       , success: function (msg) { 
       document.getElementById('msg_body').value="";
      //alert("Post was Successful!"); 
      }
       , error: function (msg) { //alert("Your message cannot be published\nThe request to Yammer didn't work... "); 
      }
     })
  }else {
      //if there is no topic you do the same request except you avoid the "topic1" parameter
  }

Monday, October 26, 2015

Programmatically embed a Yammer feed into a SharePoint Online site

In this post I will show how to use JavaScript and the Yammer SDK for easily embedding a Yammer feed into a SharePoint Online team site.








I will show 2 different approaches and will explain the pros and the cons of each :

- the first approach is the Yammer Embed and is a good initiation to the topic
- the second uses more advanced knowledge regarding the Yammer SDK

1 - Regarding environments
I have also to write something regarding the available environements for testing. Either you have a Yammer available at your company or at your client place, or you have to mount your own environmement (that I did). The important thing is to log to Yammer with an account that is not an external account. Programming with the SDK doesn't work for external accounts any longer since 2015.
Thus, don't think to make this tutorial work by using a trial version of SharePoint Online and a Yammer you can access with an external account. It won't work. (Except for Yammer embed).

If you want to mount a trail environment as I did, you need to subscibe to the Office 365 Enterprise E3 trial offer that is the only one which with you can get Yammer. But be careful. To make SharePoint Online and Yammer works properly with this Office 365 Enterprise E3 trial offer you will have to buy a Domain.

- Here is the part of the Yammer activation guide that explains how to add a company Domain for your Office 365 environment.

- And the Yammer Activation Guide FAQ


2 - The Yammer Embed approach

You will find a lot of post explaining how to add a Yammer Embed to a SharePoint Online page. Here is the official documentation of Microsoft that is also announcing that the Yammer App for SharePoint 2013 will be discontinued and will stop working on September 15th, 2015. Yammer Embed will be our single solution to integrate Yammer feeds into SharePoint.

Yammer Embed is limited. As it is displaying the feed within an Iframe, it is not so easy to customize the feed as you should want, for example change the styles, the fonts size, the font family, color, etc.
However, there is some parameters you can add to the code to modify the way Yammer Embed is displaying. I will illustrate that with and example. Look at a page with the Yammer Embed on it:



You will notice that the header is showing the Domain I had to buy to mount my Office 365 Enterprise E3 trial environment. Assume you want to hide this header. For doing that you have to add to the Yammer Embed code the following instruction:

config :{
header: false
}

Here is the Yammer embed code after having done that :

<script type="text/javascript" src="https://assets.yammer.com/assets/platform_embed.js"></script>
<script type="text/javascript"> yam.connect.embedFeed({
container: "#embedded-feed",
network: "marccharmois.com",
feedType: "group",
feedId: "6574317",
config :{
header: false
}
});
</script>

...and the result...



That gives you already a good idea about the way you can give instructions to Yammer by using the JavaScript SDK. It is like working on fragments of JQuery Ajax request .

3 - The Yammer JavaScript SDK and REST API approcah

Now is the time to examine a more powerful approach that allows you embed a Yammer feed into a SharePoint page while being able to customize things the way you want. For example, in a next post, I will show how to post a message to Yammer from SharePoint Online. When I will have such a feature I won't need the "What are you working on?" input zone any longer. So I have to find a way to embed my Yammer feed without using Yammer Embed to hide this zone.

3.1 Creating a Yammer App

To program for Yammer using the SDK and the REST API, first you have to create a Yammer APP. The Yammer APP will:
  • provide you with a Client Id that you will use in your SharePoint page code.
  • register your SharePoint page within Yamer to avoid the problem of cross-domain requests (CORS), because, even in an Office 365 integrated environment, you will notice that the SharePoint Online hostheader, and the Yammer hostheader are different . For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. Thus you cannot request the Yammer Web Services from a SharePoint Online page using client side code and XMLHTTPRequest. However, using a Yammr App will allow you to do that using the Yammer SDK.

So, let's create the Yammer App. Go to Yammer and locate the APPS menu and click it.



You land on the Apps Directory page. Locate the "My Apps" button and click on it.



You land on the "Registered Applications" page. Here you can click the "Register New App" button to create your Yammer App.



The registration Form is displaying.



Here is an explaination regarding the settings:

  • Application Name : chose an explicit name. In my case, it is a Yammer App to display a Yammer feed into a SharePoint Online Page.
  • Organisation : the one of your Office 365 environment
  • Website : the website that will host the page with the new App information (Client ID) for requesting the Yammer REST API. In my case, https://contososoftware.sharepoint.com/sites/intranet
  • Redirect Url : the website that will host the page with the new App information (Client ID) for requesting the Yammer REST API + "/oauth/callback". In my case : https://contososoftware.sharepoint.com/sites/intranet/oauth/callback

Then, click on the "continue" button for creating the new Yammer App, but it is not finished yet. An important thing to do is to define the JavaScript Origin for the New Yammer App. This is one of the important settings that is needed by Yammer to manage the concern of the HTTP Access Control (CORS). Roughly explained: Yammer needs to know the domain that will request its REST API using the client side code of a web page to tell the browser that a cross domain request is permitted.
So, when your Yammer App is created, click on its name to open the page gathering its informations and settings.



You will notice that one of the informations is the client ID that you will have to reference within the code of your web page when programming.



Then, click the "Basic Info" link in the left menu. On the opening page, locate the "JavaScript Origin" input area, and type domain of the SharePoint Online site that will host the page that will request the Yammer RET API client side. In my case https://contososoftware.sharepoint.com



When all this is done, we can start programming the SharePoint page...


3.2 Programming the SharePoint page for displaying the custom Yammer feed

Now we are going to create the web page that will request the Yammer REST API. It will be a simple html page. When this page will be programmed, displaying the Yammer feed, we will display the custom yammer feed in a SharePoint Web Part page using an Iframe.
So let's create the yammer-app.html page.

Go to SharePoint Online Intranet, navigate to the site contents, then to the "Site Assets" library. In the "Library" tab of the Ribbon locate the "open with explorer" Ribbon.



It takes a little time and you have sometimes two warning pop-ups to close until the explorer open and show the SharePoint files. You can then navigate up to the root folder of your intranet site. And you can create a new file (let's say a text document).



Then, you can rename the text document into "yammer-app.html".



And for programming the page you can open it with Notepad ++ or even Visual Studio.



You can find the complete code of the yammer-app.html page within the dedicated GitHub repositery, but here are the key points to understand the code:
  • First, load the Yammer SDK while passing your Yammer App Client ID

    <script> type="text/javascript" data-app-id="aMqiweJ1Co7RQJkHX6TFg" src="https://c64.assets-yammer.com/assets/platform_js_sdk.js"></script>

  • Second, you musn't call the Yammer web services directly using an Ajax request.
    You call the Yammer REST API with the "yam" object. Examples :

    triggering the authentication Pop-up if the user click the Yammer login button

    yam.connect.loginButton('#yammer-login', function (resp) {
    if (resp.authResponse) {
    //User is logged
    // do stuff
    }
    });

    calling Yammer to get the messages of a Yammer group

    yam.platform.request(
    {
    url: "https://api.yammer.com/api/v1/messages/in_group/6574317.json" //replace the group ID with your
    , method: "GET"
    ,success: function (data) {
    //process the Yammer feed data...
    },
    error: function (msg) { alert("error getMyFeed ajax : " + msg.value); }
    })

Last, when your yammer-app.html page is working properly, you have finally to display the custom Yammer feed via a script editor Web Part into a SharePoint Web Part Page, or a SharePoint page customized via an Iframe tag:

<iframe style="height:500px;overflow:visible;" scrolling="no" src="https://contososoftware.sharepoint.com/sites/intranet/yammerapp.html"></iframe>

Note

Note that the messages/in_group/6574317.json web service is maybe not the best one for displaying messages. I read some posts that tell it doesn't retrieve all the messages. It seems that this web service has been removed from the Yammer documentation. I let you go to the Yammer documentation and find the best web service for retrieving the messages depending on your needs...


4 - Regarding the Yammer authentication

It' seems there is a way to enable Single Sign On (SSO) from SharePoint Online to Yammer so as the users authenticated on SharePoint Online don't have to authenticate another time while wanting to access to Yammer.
I didn't try to enable the SSO yet on my trial environment, thus when a user of my environment land on the SharePoint page displaying the custom Yammer Embed feed, I have developped the presence of the Yammer Login Button.



For displaying the Yammer custom Embed feed, the user has to click the Yammer Login button, and has to authentify.



Then, the custom Yammer Embed feed is displaying.



In my environment, if the user is refeshing the page, he doesn't have to authentify again, but in my company and in my client Office 365 environments, when refreshing the page, the user HAS to authentify again.
There is a way to avoid this. You have to store the Yammer oauth token and reuse it when the page is refreshing.


4.1 Storing the Yammer oauth token to reuse it

When the user is authentified you store the token in the localStorage property that is compliant with most of the browsers. It is an amazing way to simulate the session variables.
yam.connect.loginButton('#yammer-login', function (resp) {
            if (resp.authResponse) {
        
              localStorage.setItem(1, JSON.stringify(resp.access_token.token).replace(/"/g, ""));
              console.log("token" + localStorage.getItem(1));
              //Hiding the login button because the user is logged in
              document.getElementById('yammer-login').style.display = 'none';
            }
          });
        

Now, when the page is refreshing, there is a way to test if the user is logged or not using the JavaScript SDK of Yammer:

yam.getLoginStatus( function(response) {
                    if (response.authResponse) {
                       //user is logged in
                       //nothing to do
                        
                    } else {
                       //check if a oauth token is stored for this user
                       //if yes,
                       //reload the custom Yammer Embed feed and use the oauth token stored in local storage to authentify the request 
                    }
                });
        

Finally, here is the correct syntax to pass the bearer token to yammer while loading a feed usinf the JavaScript SDK:

function getMyYammerFeed(){
        document.getElementById("yammer-feed").innerHTML="<img src='/sites/portail-dircom/PublishingImages/ajax-loader1.gif' style='margin-top:100px;margin-left:95px;' />";
        var tokenToSend = "Bearer " + localStorage.getItem(1);
        console.log("authorization bearer : " + tokenToSend);
        yam.platform.request(
           { 
              url: "https://api.yammer.com/api/v1/messages/in_group/6572783.json" 
           ,method: "GET"
           ,beforeSend: function (xhr){xhr.setRequestHeader('Authorization', tokenToSend)}
              ,success: function (data) { 
                 try{
                      //process the feed datas
             }catch(error){alert("error getMyFeed process : " + error); }
         },
              error: function (msg) { alert("error getMyFeed ajax : " + msg.value); }
            }
          )
        }