CHAPTER 8

image

Building Social Apps Using Yammer Windows Phone 8 SDK

Pathik Rawal

In last chapter you learned about Yammer JavaScript SDK. The JavaScript SDK helps you integrate HTML-based line-of-business applications with Yammer. In this chapter, you will learn about the Yammer Windows Phone SDK, released by Yammer. The Windows Phone SDK allows you to integrate Windows phone apps with Yammer. You can leverage the Windows Phone SDK to allow users to log in to your Windows Phone SDK using Yammer. You can implement the “Sign In with Yammer” button using the Windows Phone SDK to speed up the registration process and build a functional login system in minutes.

Introduction to Windows Phone 8 SDK

Yammer Windows Phone SDK is an open source program that enables developers to build Windows mobile apps on the Yammer platform or integrate Yammer functionality into their existing Windows phone apps. Like Yammer’s other SDKs for enterprise applications, the Windows Phone SDK helps organizations build more mobile capabilities and develop integrations with Yammer.

The Yammer Windows Phone SDK is a class library project that’s best suitable for Microsoft Windows Phone 8 apps.

The Windows Phone SDK enables:

  • Developers to authenticate users with OAuth 2.0 in a Windows phone app
  • Developers to call into Yammer’s API to integrate Windows phone app with Yammer
  • Developers to call into Yammer’s Open Graph and leverage social graph

The Windows Phone SDK is available at https://github.com/yammer/windows-phone-oauth-sdk-demo. This SDK consists of two projects:

  • Yammer.OAuthSDK: A class library that contains helper classes for Windows phone app. The library provides methods for login, authorization processes, and other APIs calls.
  • OAuthWPDemo: A sample project that demonstrates how to use the SDK to build the Windows Phone API for the Yammer network.

Image Note  This chapter does not explain how to develop Windows Phone 8 mobile apps. Refer to MSDN or other Apress books to explore Windows Phone 8 app development.

In the next section, you will learn about the basic setup required in order to leverage the Windows Phone SDK.

Setup Required to Use Windows Phone App 8 SDK

Before you learn about the different methods and functions, it’s important to understand the basic setup required to integrate the Windows Phone SDK.

Step 1: Register Your Yammer App and Set the Redirect URI

Register a new Yammer app as explained in Chapter 3 and configure the redirect URI to a custom one. The redirect URI has be unique to your WP8 app. For example, SPDSWP8App://Yammer. Make sure the scheme name (in this case SPDSWP8App) is unique to your company and Windows phone 8 app.

Step 2: Create an Instance of the Yammer.OAuthSDK.Model.OAuthClientInfo Class

The Yammer App registered in your Yammer network is identified by a unique ClientID, a client secret key, and a redirect URI, as shown in Figure 8-1.

9781484209448_Fig08-01.jpg

Figure 8-1. Registered Yammer app’s keys and tokens

The first step in setting up your Windows phone app is to create an instance of the class called Yammer.OAuthSDK.Model.OAuthClientInfo. This class defines the properties that store the Yammer App configuration values. The best place to do this is in the resource dictionary in your Yammer App.xaml file.

Adding Code to App.xaml

Define an object of class model OAuthClientInfo in the App.xaml file with the ClientID, ClientSecret, and RedirectURI values matching the Yammer app configuration values.

<model:OAuthClientInfo xmlns:model="clr-namespace:Yammer.OAuthSDK.Model;assembly=Yammer.OAuthSDK" x:Key="MyOAuthClientInfo"
            ClientId="ZaV9YiPAdnqa273m3HTH5w"
            ClientSecret="BzLv9AsfUrVaCY7XTvgFBxjGizsxGK7BPcs5YftkVtE"
            RedirectUri="SPDSWP8App://Yammer" />

Adding Code to App.xaml.cs

You can now define a property in App.xaml.cs. A property declared in App.xaml.cs will be available application-wide. Add the following code in App.xaml.cs for the getter property.

public OAuthClientInfo MyOAuthClientInfo
{
    get
    {
        return Resources["MyOAuthClientInfo"] as OAuthClientInfo;
    }
}

Step 3: Configure a URI Association

This step is important from the user experience perspective, as during the login process in your Windows phone app, the user will be redirected to an IE browser Windows app. The developer needs to do URI association so that the after a successful login, users are redirected to the Windows phone app from the IE browser.

Configure Project Manifest “WMAppManifest.xml

The configuration of URI association is done in the WMAppManifest.xml file, which is part of your Windows phone project.

The next step is to add an Extensions element in the app manifest file. Add the following code (below the tokens element) to WMAppManifest.xml. The Extensions element uses the Protocol element to specify the URI association (using a scheme name). Your Extensions element should look like this:

<Extensions>
  <Protocol Name="SPDSWP8App" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />
</Extensions>

Updating App.xaml.cs

Now you need to override the default URI-mapper class with the app’s redirect URI in the InitializePhoneApplication() method in App.xaml.cs:

// Override the default URI-mapper class with our OAuth URI handler.
RootFrame.UriMapper = new OAuthResponseUriMapper(MyOAuthClientInfo.RedirectUri);

That is all the basic setup required to use the Windows Phone SDK in your Windows phone app. Exercise 8-1 demonstrates the step-by-step process to leverage the Windows Phone SDK, including the basic setup required in order to leverage the capabilities of Yammer’s Windows Phone SDK.

Understanding Windows Phone SDK

Before we jump into the implementation of Yammer SDK for Windows Phone, let’s explore the Windows Phone SDK’s project structure and the functions provided by the SDK project. Later in this section, you will see the actual implementation of each function provided by the SDK.

Project “Yammer.OAuthSDK” Structure

Yammer.OAuthSDK is the C# class library project that contains all essential classes methods to integrate Yammer functionality into the Windows Phone App. This is a mandatory project you have to add to your Windows Phone App Visual Studio Solution to create an app for integration with Yammer. We will also explain how to implement this app in your project using an example later in this chapter.

Look at the class structure of the Yammer.OAuthSDK project, as shown in Figure 8-2.

9781484209448_Fig08-02.jpg

Figure 8-2. Class structure of the Windows Phone SDK

As you can see, this SDK project contains a folder named Model in the Yammer.OAuthSDK project. This folder contains all the model classes required for OAuth authentication for the Windows phone app.

All the classes under the Model folder are defined in the Yammer.OAuthSDK.Model namespace. The purpose of each class is listed in Table 8-1.

Table 8-1. List of Classes Available in the Yammer.OAuthSDK.Model Namespace

Class Name

Purpose

Methods

AccessToken

The object that contains the actual access token.

Token

AuthenticationResponse

The root object that desterilizes from a Yammer OAuth API call response.

AccessToken

OAuthError

OAuthClientInfo

Constants used to identify your app on the Yammer platform.

ClientId

ClientSecret

RedirectUri

OAuthError

Object used to deserialize an error response from a Yammer API call.

Type

Message

Code

Stat

HttpStatusCode HttpStatusDescription

There is another folder named Util in the Yammer.OAuthSDK project, also shown in Figure 8-1, that contains utility classes. All these classes are defined in the Yammer.OAuthSDK.Utils namespace. Table 8-2 provides details of these classes.

Table 8-2. List of Classes Available in the Yammer.OAuthSDK.Utils Namespace

Class Name

Purpose

Available Methods

Constants

This class defines all constants for constants that point to the Yammer API endpoints and constants that are used as the URL parameters for the API calls and responses.

Private variable:

ApiEndpoints

OAuthParameters

CryptoUtils

Utils class to handle cryptographic and encoding related operations.

Private variable:

redirectUri

Method:

GenerateUrlFriendlyNonce()

EncryptAndStoreMapUri()

DecryptStored()

UrlTokenEncode()

UrlTokenDecode()

OAuthResponseUriMapper

Converts a uniform resource identifier (URI) into a new URI to be redirected and based on the OAuth parameters received.

Private variable:

redirectUri

Method:

OAuthResponseUriMapper()

MapUri()

OAuthUtils

Utils class to handle Yammer OAuth API operations.

Private variable:

const string tokenFilePath

const string nonceFilePath

string AccessToken

Method:

LaunchSignIn()

HandleApprove()

GetJsonFromApi()

DeleteStoredToken()

HandleExceptions()

SerializationUtils

Utils class to handle serialization operations.

Private variable:

Method:

DeserializeJson()

StorageUtils

Utils class to handle storage-related operations.

Method:

DeleteFromIsolatedStorage()

WriteToIsolatedStorage()

WriteToIsolatedStorage()

ReadStringFromIsolatedStorage()

ReadBytesFromIsolatedStorage()

The Yammer.OAuth.Model and Yammer.OAuthSDK.Utils namespaces both contain important and mandatory classes to support Yammer integration with the Windows phone app.

In the next section, we will deep dive into some important functions mentioned in these classes.

Important Methods of Yammer.OAuthSDK

Before developing a Windows phone app, let’s look at the Windows Phone App SDK methods that are available in the Yammer.OAuthSDK.Utils namespace. Table 8-3 lists three important methods provided by the SDK.

Table 8-3. Important Windows Phone 8 SDK Functions

Method

Purpose

LaunchSignIn

Initiates the user login.

HandleApprove

Handles the OAuth approved response asynchronously by storing the information received from Yammer, like Code and State.

GetJsonFromApi

Calls the Yammer REST APIs asynchronously.

In the following section, you will dive deeply into each of these methods listed in Table 8-3. You will learn the actual implementation of each method with the syntax and parameter of each method.

LaunchSignIn Method

The LaunchSignIn method initiates the user login. Developers can invoke this method from a Windows phone app by using a “Login with Yammer” button. When called, this methods invokes the Internet Explorer browser on the Windows phone. The IE browser navigates to the Yammer login URL (https://www.yammer.com/dialog/oauth?client_id={0}&redirect_uri={1}&state={2}), which allows Yammer to authenticate the user as well as authorize the Yammer app.

The syntax of LaunchSignIn is as follows:

OAuthUtils.LaunchSignIn(clientId, redirectUri);

The LaunchSignIn method accepts two parameters, as listed in Table 8-4.

Table 8-4. LaunchSignIn Method Parameters

Tab4

The following code snippet provides the actual implementation of LaunchSignIn() method:

public static void LaunchSignIn(string clientId, string redirectUri)
{
    var ieTask = new WebBrowserTask();
    // need to generate and store this nonce to identify the request is ours when it comes back
    string nonce = CryptoUtils.GenerateUrlFriendlyNonce();
    StorageUtils.WriteToIsolatedStorage(nonce, nonceFilePath);
    string url = string.Format(Constants.ApiEndpoints.OAuthUserAuthentication, clientId, redirectUri, nonce);
    ieTask.Uri = new Uri(url, UriKind.Absolute);
    ieTask.Show();
}

HandleApprove Method

This is another very important method for Windows Phone SDK. HandleApprove is invoked after the user is redirected back to the Windows phone app. This method handles the OAuth-approved response asynchronously by storing the information received from Yammer, like Code and State.

The syntax of HandleApprove is as follows:

OAuthUtils.HandleApprove(clientId, clientSecret, Code, State,[ onSuccess],[onFailure])

The HandleApprove method accepts four parameters, as listed in Table 8-5.

Table 8-5. HandleApprove Function Parameters

Tab5

The following code snippet provides the actual implementation of the HandleApprove() method:

public static void HandleApprove(string clientId,
    string clientSecret,
    string code,
    string state,
    Action onSuccess,
    Action onCSRF = null,
    Action<AuthenticationResponse> onErrorResponse = null,
    Action<Exception> onException = null)
{
    // we get the stored nonce from the Isolated Storage to verify it against the one we get back from Yammer
    string nonce = StorageUtils.ReadStringFromIsolatedStorage(nonceFilePath);
    if (state != nonce)
    {
        // might be a CSRF attack, so we discard the request
        if (onCSRF != null)
        {
            onCSRF();
        }
        return;
    }
    string url = string.Format(Constants.ApiEndpoints.OAuthAppAuthentication, clientId, clientSecret, code);
    var appAuthUri = new Uri(url, UriKind.Absolute);

    var webclient = new WebClient();

    OpenReadCompletedEventHandler handler = null;
    handler = (s, e) =>
    {
        webclient.OpenReadCompleted -= handler;
        if (e.Error == null)
        {
            // the token should have been sent back in json format, we use serialization to extract it
            AuthenticationResponse oauthResponse = SerializationUtils.DeserializeJson<AuthenticationResponse>(e.Result);
            AccessToken = oauthResponse.AccessToken.Token;
            onSuccess();
        }
        else
        {
            HandleExceptions(e.Error, onErrorResponse, onException);
        }
    };

    webclient.OpenReadCompleted += handler;
    // make the actual call to the Yammer OAuth App Authentication endpoint to get our token back
    webclient.OpenReadAsync(appAuthUri);
}

GetJsonFromApi Method

The GetJsonFromApi method calls the Yammer REST APIs asynchronously. Developers can use this method to call any REST APIs that do not require any additional parameters.

The syntax of GetJsonFromApi is as follows:

public static void GetJsonFromApi(Uri endpoint,  Action<string> onSuccess,  Action<AuthenticationResponse> onErrorResponse = null, Action<Exception> onException = null)

The GetJsonFromApi method accepts four parameters, as listed in Table 8-6.

Table 8-6. GetJsonFromApi Function Parameters

Tab6

The following code snippet provides the actual implementation of the GetJsonFromApi() method:

public static void GetJsonFromApi(Uri endpoint,
    Action<string> onSuccess,
    Action<AuthenticationResponse> onErrorResponse = null,
    Action<Exception> onException = null)
{
    if (endpoint == null || onSuccess == null)
    {
        throw new ArgumentNullException();
    }

    var webclient = new WebClient();
    // We shouldn't use the url query paramters to send the token, we should use the header to send it more securely instead
    webclient.Headers[HttpRequestHeader.Authorization] = "Bearer " + AccessToken;

    DownloadStringCompletedEventHandler handler = null;
    handler = (s, e) =>
    {
        webclient.DownloadStringCompleted -= handler;
        if (e.Error == null)
        {
            var result = e.Result;
            // We just pass the raw text data response to the callback
            onSuccess(result);
        }
        else
        {
            HandleExceptions(e.Error, onErrorResponse, onException);
        }
    };

    webclient.DownloadStringCompleted += handler;
    webclient.DownloadStringAsync(endpoint);
}

Now that we have explained all the important requirements and structure of the Windows Phone SDK for Yammer integration, let’s create a Windows phone app using this SDK.

Building a Windows Phone 8 App Using Yammer Windows Phone SDK

This section provides a step-by-step guide on creating a new Windows phone app. You will use the Yammer Windows Phone App SDK in your project and call Yammer REST APIs for groups, message, users, and so on. Finally, you’ll use Visual Studio’s emulator to test your app.

EXERCISE 8-1: BUILDING A WINDOWS 8 PHONE APP

Create New Project

  1. If you already installed Visual Studio and the Windows Phone SDK tools, launch Microsoft Visual Studio.
  2. The first screen presented to you is the Visual Studio start page, shown in Figure 8-3.

    9781484209448_Fig08-03.jpg

    Figure 8-3. The Visual Studio start page provides a quick way to get started

  3. On the left side of the start page, on the navigation pane, choose New Project. Alternatively, you can choose the File image New Project image Windows Phone App menu command.
  4. This brings up the New Project window, where you can choose the type of project for the Windows phone app. Figure 8-4 demonstrates creating a simple Windows phone app from a Windows phone app template.

    9781484209448_Fig08-04.jpg

    Figure 8-4. Visual Studio provides a number of templates to choose from; to get started, select the Windows phone app

  5. Next you will be presented with a window to select the Windows app platform to target for this application. Choose Windows Phone 8.0.

    9781484209448_Fig08-05.jpg

    Figure 8-5. Select the Windows phone version

  6. After the wizard finishes, you should have a structure in Solution Explorer that resembles Figure 8-6. The solution includes one Windows phone app project, which contains the app structure with an App.xml file.

    9781484209448_Fig08-06.jpg

    Figure 8-6. Windows phone app project strucutre

    Add Yammer.OAuthSDK to the Solution

  7. Download the Windows Phone SDK for Yammer from GitHub.
  8. To add the Yammer.OAuthSDK project to your newly created solution, in the Visual Studio Solution Explorer, right-click on the solution name and then choose Add image Existing Project, as demonstrated in Figure 8-7.

    9781484209448_Fig08-07.jpg

    Figure 8-7. To add an existing project to solution in Visual Studio

  9. Navigate to the folder where Yammer.OAuth.SDK.csproj is located (Figure 8-8).

    9781484209448_Fig08-08.jpg

    Figure 8-8. Browse to the Yammer.OAuthSDK project file on your development machine

  10. Click open.

    Referencing the Yammer.OAuthSDK to Windows Phone App Project

  11. Once the Yammer Windows Phone SDK is added to your solution, you have to reference it in the Windows phone app project. In the Solution Explorer, expand the Windows phone app project, right-click on Reference and select Add Reference.

    9781484209448_Fig08-09.jpg

    Figure 8-9. To add the reference to the Yammer.OAuthSDK project that was added to the solution in the previous steps

  12. You’ll will be presented with a dialog box, as demonstrated in Figure 8-10.

    9781484209448_Fig08-10.jpg

    Figure 8-10. Select the project from the list to be added as a reference

  13. From the right side of this dialog box, choose Solution image Project image Yammer.OAuthSDK and click OK.

    Understanding the Visual Studio Solution Structure

  14. Your solution should have two projects, as illustrated in Figure 8-11.

    9781484209448_Fig08-11.jpg

    Figure 8-11. Windows phone solution structure

Table 8-7 lists the Windows Phone SDK’s Visual Studio projects available in SDK.

Table 8-7. Windows Phone SDK Projects

Name

Description

Yammer.OAuthSDK

This is class library project that contains helper functions that allow you to integrate OAuth login and functions to make APIs calls.

YammerIntegrationWindowsApp

A sample Windows Phone 8 application that demonstrates how to set up and use these helper classes in an app.

Add an Extension: WMAppManifest.xml

We will start by adding an extension to the WMAppManifest.xml file. Since you’ll be using Visual Studio Emulator to build and test this Windows phone app, the redirect_uri parameter must be set so that the IE browser on your Windows phone redirects the users to the Windows phone app after successful authentication and app authorization. To set up the redirect_uri, you need to set up the extension in the WMAppManifest.xml file.

The configuration of URI association is done in the WMAppManifest.xml file, which is part of your Windows phone project.

  1. Add the following code snippet to WMAppManifest.xml, just below the </Token> tag:
    <Extensions>
    <Protocol Name="SPDSWP8App" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />
    </Extensions>

    Image Note  The Protocol Name="SPDSWP8App" should match the App.xaml RedirectURI of the Yammer app redirect URI configuration.

  2. The next project file to modify is App.xaml. You’ll use this file to configure the Yammer app configuration values like ClientID, ClientSecret key, and RedirectURI. These parameters are required in order to call the Yammer REST API from your Windows phone app. The best place to configure those parameters is in the App.xaml file within <Application. Resources>.
  3. Open the App.xaml file by double-clicking on the filename in Visual Studio Solution Explorer.
  4. Add the following code to the Application Resources section (tag name <Application.Resources>), directly below the <local:LocalizedStrings> tag.
    <model:OAuthClientInfo xmlns:model="clr-namespace:Yammer.OAuthSDK.Model;assembly=Yammer.OAuthSDK" x:Key="MyOAuthClientInfo"
                ClientId="Fmi5JYfF5jqMLCcydqkJWQ"
                ClientSecret="GBE5vp3mOUZuRVKqFPsXOA6eOLro95DOFVP5PPgSII0"
                RedirectUri="SPDSWP8App://WPSample" />

    The redirectURI in this configuration should match your redirect_URI in the Yammer’s app configuration, as illustrated in Figure 8-12.

    9781484209448_Fig08-12.jpg

    Figure 8-12. Ensure that your Yammer app's redirect URI matches OAuthClientInfo’s redirect URI

    Image Note  The clr-namespace refers to the Yammer.OAuthSDK.Model class in the SDK library project you added in previous steps.

  5. Open the App.xaml.cs file by double-clicking on the filename in the Solution Explorer. Add the following two lines of code to the using section on the top of the code-behind:
    using Yammer.OAuthSDK.Model;
    using Yammer.OAuthSDK.Utils;
  6. Add the following code to declare an object of class OAuthClientInfo model class in the App.xaml.cs file. This object will be used to refer to the values for ClientID, ClientSecret key, and RedirectURI.
    public OAuthClientInfo MyOAuthClientInfo
    {
        get
        {
            return Resources["MyOAuthClientInfo"] as OAuthClientInfo;
        }
    }
  7. Now you’ll modify the InitializePhoneApplication method within the App.xaml.cs file to override the default URI-Mapper class of the RootFrame with the OAuth URI handler, which will be used to redirect the user to the Windows phone app from the IE browser after the successful authentication and authorizations. Add the following code to the method:
    // Override the default URI-mapper class with our OAuth URI handler.
                RootFrame.UriMapper = new OAuthResponseUriMapper(MyOAuthClientInfo.RedirectUri);

    Image Note  MainPage.xaml is the default page with some UI element. It is actually a startup UI for the Silverlight application in the Windows phone app. Here, you can use the Silverlight controls for developing user interface with different layouts.

  8. Open MainPage.xaml by double-clicking on the filename in the Solution Explorer. MainPage.xaml has the following markup code for the Windows phone page’s title and app name. In the StackPanel named x: Name="TitlePanel, change it to the text block of your choice for the Yammer app name and main page title.
    <!--TitlePanel contains the name of the application and page title-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock Text="SPDS University Windows Phone App" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
                <TextBlock Text="SPDS University" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
  9. Add the following code in <Grid x:Name="ContentPanel". This code contains the button markup code:
    <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button Name="btnSignInWithYammer" HorizontalAlignment="Center" VerticalAlignment="Top" Click="btnSignInWithYammer_Click">
                <Image Source="Assetsyammer-signin.gif" Width="179" Height="28" Stretch="Fill" />
            </Button>
        </Grid>

    Image Note  Yammer-signin.gif: Use the image of your choice stored in the Asset folder of your Windows app solution. You can also download an image from https://www.filepicker.io/api/file/KYDbdovdQAG9ABZ0LLiT.

  10. Add the text block control markup to <Grid x:Name="ContentPanel"> to store the token status. In the code-behind, we will use this text block to store the status=Yes if the Yammer app has already received the access token and Status=no if the access token for the current user has not been received. You can place this outside of the content panel grid:
    <TextBlock x:Name="txbIsTokenPresent" Text="Is Token Present: No." TextAlignment="Center" />

    After you have defined all the markup in the MainPage.xaml page, you add the code to the code-behind class of MainPage.xaml.

  11. Open MainPage.xaml.cs to add some code-behind to refer to the class library from a Yammer.OAuthSDL project like the Yammer.OAUthSDK.Model and Yammer.OAUthSDK.Utils classes.
    using Yammer.OAuthSDK.Model;
    using Yammer.OAuthSDK.Utils;
  12. Declare three variables on top of the page class:
    string clientId = default(string);
    string clientSecret = default(string);
    string redirectUri = default(string);
  13. Next you need to read the Yammer app configuration values defined in App.xaml in the previous steps. To do that, add the following code to MainPage.xaml’s constructor (add the following code to the InitializeComponent();) to populate the ClientID, ClientSecret, and RedirectUri variables.
    // we extract these values from the App's Resource Dictionary config
              clientId = ((App)App.Current).MyOAuthClientInfo.ClientId;
              clientSecret = ((App)App.Current).MyOAuthClientInfo.ClientSecret;
              redirectUri = ((App)App.Current).MyOAuthClientInfo.RedirectUri;
  14. We added the login button markup in the MainPage.xaml, so now it is time to add an event handler code for the login button.
    private void btnSignInWithYammer_Click(object sender, RoutedEventArgs e)
     {
         OAuthUtils.LaunchSignIn(clientId, redirectUri);

     }
    • The LaunchSignIn method launches Internet Explorer using a WebBrowserTask to redirect the user to the proper user authentication endpoint (see https://www.yammer.com/dialog/oauth?client_id={0}&redirect_uri={1} which is defined in the constants class of the Yammer SDK.
    • The LaunchSignIn method also stores the access token in an isolated space which will be used to make further calls.
    • Generate and store this nonce to identify the request is yours when it comes back.
  15. Add the UpdateTokenMessage method to the MainPage.xaml.cs file.
    private void UpdateTokenMessage(bool isTokenPresent)
    {
        Dispatcher.BeginInvoke(() => txbIsTokenPresent.Text = isTokenPresent ? txbIsTokenPresent.Text.Replace("No.", "Yes.") : txbIsTokenPresent.Text.Replace("Yes.", "No."));
    }

    The final method you’ll add to the MainPage.xaml.cs file handles the redirect call. This is required as the IE browser window will redirect users to the Windows app after a successful user authentication. This method

    Once the login is successful, the IE browser redirects users to REDIRECT_URI, which is configured in the Windows Phone App and App.xaml.cs’s <Extension> tag.

    The Windows Phone App provides an OnNavigatedTo() event, which is used to handle the request.

  16. Add the following code to implement the OnNavigatedTo method in MainPage.xaml.cs.
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        // Check the arguments from the query string passed to the page.
        IDictionary<string, string> uriParams = NavigationContext.QueryString;

        // "Approve"
        if (uriParams.ContainsKey(Constants.OAuthParameters.Code) && uriParams.ContainsKey(Constants.OAuthParameters.State) && e.NavigationMode != NavigationMode.Back)
        {
            OAuthUtils.HandleApprove(
                clientId,
                clientSecret,
                uriParams[Constants.OAuthParameters.Code],
                uriParams[Constants.OAuthParameters.State],
                onSuccess: () =>
                {
                   UpdateTokenMessage(true);
                }, onCSRF: () =>
                {
                    MessageBox.Show("Unknown 'state' parameter. Discarding the authentication attempt.", "Invalid redirect.", MessageBoxButton.OK);
                }, onErrorResponse: errorResponse =>
                {
                    Dispatcher.BeginInvoke(() => MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK));
                }, onException: ex =>
                {
                    Dispatcher.BeginInvoke(() => MessageBox.Show(ex.ToString(), "Unexpected exception!", MessageBoxButton.OK));
                }
            );
        }
        // "Deny"
        else if (uriParams.ContainsKey(Constants.OAuthParameters.Error) && e.NavigationMode != NavigationMode.Back)
        {
            string error, errorDescription;
            error = uriParams[Constants.OAuthParameters.Error];
            uriParams.TryGetValue(Constants.OAuthParameters.ErrorDescription, out errorDescription);

            string msg = string.Format("error: {0} error_description:{1}", error, errorDescription);
            MessageBox.Show(msg, "Error response is received.", MessageBoxButton.OK);

            OAuthUtils.DeleteStoredToken();

            UpdateTokenMessage(false);
        }

                   // if token already exist
        if (!string.IsNullOrEmpty(OAuthUtils.AccessToken))
        {
           // UpdateTokenMessage(true);
        }
    }

Code flow:

  • First check the arguments from the query string passed to the page and store them in the dictionary object called uriParams.
  • Check if the uriParams contains the code and state in the query string and the NavigationMode != NavigationMode.Back.
  • If it contains code and state, then the user has approved (authorized) the app to use the user’s data.
  • Make a call to Yammer SDK’s HandleApprove method to retrieve the access token.
  • Finally, call the UpdateTokenMessage method to update the UI status flag of the token existence in isolated storage.

Run the Application

  1. Build the solution and run the Windows phone app using the emulator, as shown in Figure 8-13.

    9781484209448_Fig08-13.jpg

    Figure 8-13. Run the Windows Phone App using the emulator

  2. In Run mode, the home page will look like Figure 8-14.

    9781484209448_Fig08-14.jpg

    Figure 8-14. Windows phone landing page

    When the Login with Yammer button is clicked, the Windows app will redirect you to the IE browser, as illustrated in Figure 8-15.

    9781484209448_Fig08-15.jpg

    Figure 8-15. The Yammer Login screen presented to the user in Internet Explorer

  3. Enter the login details and click on Log In.
  4. The next screen presented is the app authorization screen. It allows users to allow or deny the Yammer app to access and update the user’s data.

    9781484209448_Fig08-16.jpg

    Figure 8-16. The OAuth process prompts the user to authorize the Yammer App

  5. After a successful log in to Yammer, IE will redirect you to the Windows phone home page again (as per the settings in the Yammer app image Redirect_URI and the extension in App.xaml.cs).

Messages Management: Post a Message to Yammer’s Group

Yammer Windows phone enables developers to post a message to Yammer on behalf of users from their Windows phone apps.

  1. Modify Constants.cs (Project Yammer.OAuthSDK) by declaring a constant variable for the message endpoints in the public static class ApiEndpoints.
    public const string Message = @"https://www.yammer.com/api/v1/messages.json";
  2. Modify OAuthUtils.cs (Project Yammer.OAuthSDK). Add the following code to implement of the post message in the Windows phone SDK project’s OAuthUtils.cs file.
    public static void PostMessage(Uri endpoint, string method, string data,
        Action<string> onSuccess,
        Action<AuthenticationResponse> onErrorResponse = null,
        Action<Exception> onException = null)
    {
        if (endpoint == null || onSuccess == null)
        {
            throw new ArgumentNullException();
        }

        var webclient = new WebClient();
        // We shouldn't use the url query paramters to send the token, we should use the header to send it more securely instead
        webclient.Headers[HttpRequestHeader.Authorization] = "Bearer " + AccessToken;
        // webclient.Headers["Content-Type"] = "application/json";

        UploadStringCompletedEventHandler handler = null;
        handler = (s, e) =>
        {
            webclient.UploadStringCompleted -= handler;
            if (e.Error == null)
            {
                var result = e.Result;
                // We just pass the raw text data response to the callback
                onSuccess(result);
            }
            else
            {
                HandleExceptions(e.Error, onErrorResponse, onException);
            }
        };

        webclient.UploadStringCompleted += handler;
        webclient.UploadStringAsync(endpoint, method, data);
    }
  3. Add the following code to MainPage.xaml for a button just below the “Log In to Yammer” button using the following code:
    <Button Name="btnPostMsg" Grid.Row="1" HorizontalAlignment="Center" Background="Black" VerticalAlignment="Top" Click="btnPostMsgYammer_Click">
                    Post a Message
    </Button>
  4. Add a text block to store the response.
    <TextBlock x:Name="txtResponses" Text="" TextAlignment="Center" Grid.Column="1" Grid.Row="12" />
  5. Add the following code to MainPage.xaml.cs for the button’s click event handler.
    private void btnPostMsgYammer_Click(object sender, RoutedEventArgs e)
    {
        // Call this API to test if the auth token works
        var messageApiEndpoint = new Uri(Constants.ApiEndpoints.Message, UriKind.Absolute);
        String data = "body=We are in process of launching more technical trainings this year. Check our training portal home page for more details ";

        OAuthUtils.PostMessage(messageApiEndpoint, "POST", data, onSuccess: response =>
        {
            // we just dump the unformated json string response into a textbox
            Dispatcher.BeginInvoke(() => txtResponses.Text = "Message Posted");
        },
          onErrorResponse: errorResponse =>
          {
              Dispatcher.BeginInvoke(() =>
              {
                  MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                  txtResponses.Text = string.Empty;
              });
          },
             onException: ex =>
             {
                 Dispatcher.BeginInvoke(() =>
                 {
                     MessageBox.Show(ex.ToString(), "Unexpected exception!", MessageBoxButton.OK);
                     txtResponses.Text = string.Empty;
                 });
             }
     );
        Dispatcher.BeginInvoke(() => txtResponses.Text = "Posting…");

    }

In this method, YOU define a string variable called "data" which will hold the actual message to post. To post this message on a particular group, use the group_id. If group_id is omitted then the message will be posted to "ALL Company", which is your default group to post a message.

Once the message is constructed, call the OAuthUtils.PostMessage method by passing arguments. In addition, you can modify the data string variable to do the following.

Table 8-8. Variable Available for Data String

Variable

Example

Reply_to_Id

String data = “replied_to_id=432948966” + “&body=” + “Great!!”;

Add Topics

String data = “group_id=4659506&body=A message with Topic” + “&topic1=” + “YammerBook!!”;

Private Message

String data = “direct_to_id=1522209393&body=A message”;

Where direct_to_id is the user ID

Share a Post

String data = “shared_message_id=433483891” + “&body=” + “Sharing an useful blog!!”;

Messages Management: Like a Message

You can use the Yammer Windows Phone SDK to mark a message as Liked by the current user. Yammer provides current.json to support this activity. You’ll need the message_id in order to mark a message as Liked. In the following example, the post message, which was used while posting a message, is used with method type set to "POST". To like a message, the data parameter that was used as the message string to post is not required; therefore, it is passed as an empty string. The full URL of the current.json endpoint is:

https://www.yammer.com/api/v1/messages/liked_by/current.json?message_id=[:id]

where the ID represents the target message ID and method is the POST for marking a message as liked.

  1. Declare a constant variable for the current.json endpoints in Constants.cs (Project Yammer.OAuthSDK).
    public const string current = @"https://www.yammer.com/api/v1/messages/liked_by/current.json";
  2. Add a button’s markup for the “Like a Message” button using the following code in MainPage.xaml:
    <Button Name="btnlikemsg" Grid.Row="2" HorizontalAlignment="Center" Background="Black" VerticalAlignment="Top" Click="btnLiketMsgYammer_Click">
                    Like a Message
    </Button>
  3. Add the following code for the event handler for the button’s click event to MainPage.xaml.cs:
    private void btnLiketMsgYammer_Click(object sender, RoutedEventArgs e)
    {
        // Call this API to test if the auth token works
        var messageApiEndpoint = new Uri(Constants.ApiEndpoints.current + "?message_id=508413888", UriKind.Absolute);
        String data = "";

        OAuthUtils.PostMessage(messageApiEndpoint, "POST", data, onSuccess: response =>
        {
            // we just dump the unformated json string response into a textbox
            Dispatcher.BeginInvoke(() => txtResponses.Text = "Message Liked");
        },
          onErrorResponse: errorResponse =>
          {
              Dispatcher.BeginInvoke(() =>
              {
                  MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                  txtResponses.Text = string.Empty;
              });
          },
             onException: ex =>
             {
                 Dispatcher.BeginInvoke(() =>
                 {
                     MessageBox.Show(ex.ToString(), "Unexpected exception!", MessageBoxButton.OK);
                     txtResponses.Text = string.Empty;
                 });
             }
     );
        Dispatcher.BeginInvoke(() => txtResponses.Text = "Liking…");

    }

Messages Management: Unlike a Liked Message

You can use the message endpoint method to unlike a message that was marked as Liked by the current users. You’ll need message_id to unlike a message. The “mutator” method to unlike a message is DELETE.

  1. We will add a PostMessage function with six parameters in the SDK. We need this method to pass the method parameter DELETE. Add the following code in the OAuthUtils.cs file:
    public static void PostMessage(Uri endpoint, string method, string data,
        Action<string> onSuccess,
        Action<AuthenticationResponse> onErrorResponse = null,
        Action<Exception> onException = null)
    {
        if (endpoint == null || onSuccess == null)
        {
            throw new ArgumentNullException();
        }

        var webclient = new WebClient();
        // We shouldn't use the url query paramters to send the token, we should use the header to send it more securely instead
        webclient.Headers[HttpRequestHeader.Authorization] = "Bearer " + AccessToken;
        // webclient.Headers["Content-Type"] = "application/json";

        UploadStringCompletedEventHandler handler = null;
        handler = (s, e) =>
        {
            webclient.UploadStringCompleted -= handler;
            if (e.Error == null)
            {
                var result = e.Result;
                // We just pass the raw text data response to the callback
                onSuccess(result);
            }
            else
            {
                HandleExceptions(e.Error, onErrorResponse, onException);
            }
        };

        webclient.UploadStringCompleted += handler;
        webclient.UploadStringAsync(endpoint, method, data);
    }
  2. Add a button’s markup for the “Unlike a Message” button using the following code in MainPage.xaml:
    <Button Name="btnunlikemsg" HorizontalAlignment="Center" Background="Black" VerticalAlignment="Top" Click="btnUnLikeMsgYammer_Click">
                            Unlike a Message
    </Button>
  3. Add an event handler for the unlike button to MainPage.xaml.cs:
    /// <summary>
            /// UnLike a Message Button event handler to Like a message specified by message_Id
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnUnLikeMsgYammer_Click(object sender, RoutedEventArgs e)
            {
                // Call this API to test if the auth token works
                var messageApiEndpoint = new Uri(Constants.ApiEndpoints.current + "?message_id=508402750", UriKind.Absolute);
                String data = "";

                OAuthUtils.PostMessage(messageApiEndpoint, "DELETE", data, onSuccess: response =>
                {
                    // we just dump the unformated json string response into a textbox
                    Dispatcher.BeginInvoke(() => txtResponses.Text = "Message Unliked");
                },
                  onErrorResponse: errorResponse =>
                  {
                      Dispatcher.BeginInvoke(() =>
                      {
                          MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                          txtResponses.Text = string.Empty;
                      });
                  },
                     onException: ex =>
                     {
                         Dispatcher.BeginInvoke(() =>
                         {
                             MessageBox.Show(ex.ToString(), "Unexpected exception!", MessageBoxButton.OK);
                             txtResponses.Text = string.Empty;
                         });
                     }
             );
                Dispatcher.BeginInvoke(() => txtResponses.Text = "Unliking…");

            }

    The previous event handler calls the same method that was called to like a message and post a message. The only difference is that the method type is DELETE instead of POST.

    Messages Management: Retrieve All Messages

    The Yammer REST API https://www.yammer.com/api/v1/messages.json enables developers to retrieve all messages for the current user. The Windows Phone SDK provides a method called GetJsonFromApi from the OAuthUtil class to retrieve all messages from Yammer and serialize the JSON to a .NET object. The following code snippet explains step-by-step how to call the SDK’s method. It uses a separate phone application page that contains a list view object to display returned records.

  4. Add a page to the Windows phone project. In Visual Studio’s Solution Explorer, right-click on the Windows Phone Project and choose Add image New Item.

    9781484209448_Fig08-17.jpg

    Figure 8-17. Add a new page using Add New Item

  5. You’ll be presented with the Add New Item screen, as shown in Figure 8-18.

    9781484209448_Fig08-18.jpg

    Figure 8-18. Add a new windows page

  6. Select Windows Phone Portrait Page and enter the ViewAllMessages name. Click Add.
  7. Since we’re using a ListView control to display the retrieved messages, use the App.xaml file to define the styles. The styles are very basic with the intension of demonstrating the Yammer REST APIs’ capabilities. Add the following code to the App.xaml file within the <Application.Resources> tags.
    <Style x:Key="MessagesList" TargetType="ListBox">
                <Setter Property="Margin" Value="5"/>
                <Setter Property="Grid.Row" Value="1"/>
                <Setter Property="Background" Value="White"/>
            </Style>
            <Style x:Key="SimpleBlock" TargetType="TextBlock">
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="FontSize" Value="18"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="Foreground" Value="YellowGreen"/>
                <Setter Property="TextAlignment" Value="Left"/>
                <Setter Property="VerticalAlignment" Value="Center"/>

            </Style>
            <Style x:Key="TitleBlock" TargetType="TextBlock">
                <Setter Property="FontSize" Value="18"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="Foreground" Value="WhiteSmoke"/>
                <Setter Property="TextAlignment" Value="Left"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>

    This example uses the Yammer REST APIs that return the JSON object. In order to convert JSON to a .NET object, define a class and all the serializable properties for the object.

  8. Add a new folder called Common, which will contain all common classes.

    9781484209448_Fig08-19.jpg

    Figure 8-19. Add a folder to the project

  9. Define a class for the message object and name it YammerMessage.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using Yammer.OAuthSDK.Utils;
    using SPDS UniversityWinPhoneApp.Common;

    namespace SPDS UniversityWinPhoneApp.Common
    {
        [DataContract]
        public class YammerMessage
        {
            [DataMember(Name = "id")]
            public string ID { get; set; }

            [DataMember(Name = "sender_id")]
            public string SenderID { get; set; }

            [DataMember(Name = "replied_to_id")]
            public string RepliedToID { get; set; }

            [DataMember(Name = "created_at")]
            public string CreatedAt { get; set; }

            [DataMember(Name = "network_id")]
            public string NetworkID { get; set; }

            [DataMember(Name = "message_type")]
            public string MessageType { get; set; }

            [DataMember(Name = "sender_type")]
            public string SenderType { get; set; }

            [DataMember(Name = "url")]
            public string Url { get; set; }

            [DataMember(Name = "web_url")]
            public string WebUrl { get; set; }

            [DataMember(Name = "group_id")]
            public string GroupId { get; set; }

            [DataMember(Name = "body")]
            public YammerMessageContent MessageContent { get; set; }

            [DataMember(Name = "rich")]
            public YammerMessageContent MessageContent1 { get; set; }

            [DataMember(Name = "thread_id")]
            public string ThreadID { get; set; }

            [DataMember(Name = "client_type")]
            public string ClientType { get; set; }

            [DataMember(Name = "client_url")]
            public string ClientUrl { get; set; }

            [DataMember(Name = "system_message")]
            public bool SystemMessage { get; set; }

            [DataMember(Name = "direct_message")]
            public bool DirectMessage { get; set; }

            [DataMember(Name = "chat_client_sequence")]
            public string ChatClientSequence { get; set; }

            [DataMember(Name = "content_excerpt")]
            public string ContentExcerpt { get; set; }

            [DataMember(Name = "language")]
            public string Language { get; set; }

            [DataMember(Name = "notified_user_ids")]
            public string notified_user_ids { get; set; }

            [DataMember(Name = "privacy")]
            public string privacy { get; set; }

            [DataMember(Name = "group_created_id")]
            public string group_created_id { get; set; }

            public YammerMessage()
            {

                this.MessageContent = new YammerMessageContent();
            }
        }

    }
  10. Define the YammerMessageContent class using the following code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using Yammer.OAuthSDK.Utils;
    using SPDS UniversityWinPhoneApp.Common;

    namespace SPDS UniversityWinPhoneApp.Common
    {
        [DataContract]
        public class YammerMessageContent
        {
            [DataMember(Name = "parsed")]
            public string ParsedText { get; set; }

            [DataMember(Name = "plain")]
            public string PlainText { get; set; }

            [DataMember(Name = "rich")]
            public string RichText { get; set; }

        }

    }
  11. Define a class for the messages collection object using the following code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using Yammer.OAuthSDK.Utils;
    using SPDS UniversityWinPhoneApp.Common;

    [DataContract]
    public class YammerMessages
    {
        [DataMember(Name = "messages")]
        public List<YammerMessage> Messages { get; set; }

        public YammerMessages()
        {
            this.Messages = new List<YammerMessage>();
        }
    }
  12. Add the following code to the newly added class file. First add references to the class libraries:
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using Yammer.OAuthSDK.Utils;
  13. Use the ViewAllMessages.xaml file to define the user interface to display messages retrieved from Yammer. To do this, use the following code snippet and add it to the <Grid x:Name="ContentPanel"> grid control:
    <ListBox x:Name="ListBoxAllMessage" ItemsSource="{Binding}" >
                    <ListBox.ItemTemplate>
                        <DataTemplate>

                            <StackPanel Orientation="Vertical">
                                <Line Stroke="White" X1="0" Y1="25" X2="800" Y2="25" />
                                <TextBlock Text="{Binding ID}" Style="{StaticResource SimpleBlock}" />
                                <TextBlock Text="{Binding MessageContent.PlainText}" Margin="5" Style="{StaticResource TitleBlock}" />
                                <Line Stroke="White" X1="0" Y1="25" X2="800" Y2="25" />

                            </StackPanel>

                        </DataTemplate>
                    </ListBox.ItemTemplate>

                </ListBox>

                <TextBlock x:Name="txtResponses" Text="" TextAlignment="Center" />

    The previous code uses a ListBox control with an item template. The item template defines a StackPanel to display a line, a text block for the message ID, a text block for the MessageContent.PlainText, and another line as a row separator. Define the appropriate binding as per the YammerMessage class definition.

    The code-behind file of ViewAllMessage.xaml implements the server-side code that calls the Yammer REST API using the SDK’s helper functions.

    private void Loaddata()
    {
        // Call this API to test if the auth token works
        var messageApiEndpoint = new Uri(Constants.ApiEndpoints.Message, UriKind.Absolute);

        OAuthUtils.GetJsonFromApi(messageApiEndpoint, onSuccess: response =>
        {
            byte[] byteArray = System.Text.UTF8Encoding.UTF8.GetBytes(response);
            MemoryStream res = new MemoryStream(byteArray);

            YammerMessages msgs = SerializationUtils.DeserializeJson<YammerMessages>(res);

            ListBoxAllMessage.DataContext = msgs.Messages;
            ListBoxAllMessage.ItemsSource = msgs.Messages;

            // we just dump the unformated json string response into a textbox
            Dispatcher.BeginInvoke(() => txtResponses.Text = "Messages Retrieved");
        },
          onErrorResponse: errorResponse =>
          {
              Dispatcher.BeginInvoke(() =>
              {
                  MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                  txtResponses.Text = string.Empty;
              });
          },
             onException: ex =>
             {
                 Dispatcher.BeginInvoke(() =>
                 {
                     MessageBox.Show(ex.ToString(), "Unexpected exception!", MessageBoxButton.OK);
                     txtResponses.Text = string.Empty;
                 });
             }
     );
        Dispatcher.BeginInvoke(() => txtResponses.Text = "Retrieving ...");
    }

    }

    The Loaddata method calls the Windows Phone SDK’s GetJsonFromApi method, which returns the JSON stream, which is then deserialized into a .NET object. Finally, the collection object called msgs of the YammerMessages class is assigned to ListBox as an ItemsSource property.

  14. Use the following code snippet to reference the namespaces that the ViewAllMessages.xaml page will be using frequently.
    using Yammer.OAuthSDK.Utils;
    using Yammer.OAuthSDK.Model;
    using Yammer.OAuthSDK.Utils;
    using System.IO;
    using System.Text;
  15. Modify the page’s Constructor method to call the Loaddata() method.
    public ViewAllMessages ()
            {
                InitializeComponent();
                Loaddata();
            }
  16. Now add a button control to the main windows phone page to allow users to navigate to the View All Messages page. Add the following code for a button control:
    <Button Name="ViewallMessage" Grid.Row="4"  HorizontalAlignment="Center" VerticalAlignment="Top" Click="ViewallMessage_Click">
                  View All Messages
    </Button>
  17. MainPage.xaml.cs: Add an event handler for the ViewAllMessage button.
    private void ViewallMessage_Click(object sender, RoutedEventArgs e)
    {
        NavigationService.Navigate(new Uri("/ViewAllMessages.xaml", UriKind.Relative));
    }

    User Management: Retrieve all Users

    In the previous section, you implemented code to retrieve all messages for the current user. Yammer is a social site and the most important actor on any social site are the users. We’ll see how to retrieve Yammer’s users using the REST APIs.

  18. Add a ViewAllUsers phone page. We’ll add another page to the existing project to display the users’ properties on a grid view control. To add a page to your solution, in Visual Studio’s Solution Explorer, right-click on the Windows Phone Project and then choose Add image New Item (Figure 8-20).

    9781484209448_Fig08-20.jpg

    Figure 8-20. Adding a page using Visual Studio Solution Explorer

  19. You’ll be presented with the Add New Item screen. Select Windows Phone Portrait Page and enter the name ViewAllMessages. Click Add.

    9781484209448_Fig08-21.jpg

    Figure 8-21. Adding new items using the Add New Item screen

  20. Add an endpoint in the Constants class. Define a constant property in Yammer.OAUthSDK’s Constants class.
    public const string allUsersUrl = "https://www.yammer.com/api/v1/users.json";
  21. Add a new class for the Yammer users’ data contract. The user object is very big in nature and it holds many properties that are stored in Yammer, like user’s first name, last name, full name, department, title, and so on. Along with those properties, Yammer also stores the user’s social graph like group members, followers, following, and so on. If you cannot use the class from this book directly, do not worry as the sample code is available for download.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using System.IO;
    using System.Diagnostics;

    namespace SPDS UniversityWinPhoneApp.Common
    {
        [DataContract]
        public class YammerUser
        {
            [DataMember(Name = "id")]
            public string UserID { get; set; }

            [DataMember(Name = "network_id")]
            public string NetworkID { get; set; }

            [DataMember(Name = "state")]
            public string AccountStatus { get; set; }

            [DataMember(Name = "job_title")]
            public string JobTitle { get; set; }

            [DataMember(Name = "expertise")]
            public string Expertise { get; set; }
            [DataMember(Name = "full_name")]
            public string FullName { get; set; }

            [DataMember(Name = "first_name")]
            public string FirstName { get; set; }

            [DataMember(Name = "last_name")]
            public string LastName { get; set; }

            [DataMember(Name = "url")]
            public string ApiUrl { get; set; }

            [DataMember(Name = "web_url")]
            public string WebUrl { get; set; }
            [DataMember(Name = "mugshot_url")]
            public string PhotoUrl { get; set; }

            [DataMember(Name = "mugshot_url_template")]
            public string PhotoTemplateUrl { get; set; }

            [DataMember(Name = "department")]
            public string Department { get; set; }

            [DataMember(Name = "contact")]
            public YammerContactInfo ContactInfo { get; set; }

            [DataMember(Name = "web_preferences")]
            public YammerSettingsAndFeedsAndGroups SettingsAndFeedsAndGroups { get; set; }

            [DataMember(Name = "previous_companies")]
            public List<YammerEmployer> PreviousEmployers { get; set; }

            [DataMember(Name = "schools")]
            public List<YammerSchool> Schools { get; set; }
            [DataMember(Name = "stats")]
            public YammerUserStats UserStats { get; set; }

            public YammerUser()
            {
                this.ContactInfo = new YammerContactInfo();
                this.SettingsAndFeedsAndGroups = new YammerSettingsAndFeedsAndGroups();
                this.PreviousEmployers = new List<YammerEmployer>();
                this.Schools = new List<YammerSchool>();
                this.UserStats = new YammerUserStats();
            }
        }

        [DataContract]
        public class YammerUserStats
        {
            [DataMember(Name = "followers")]
            public int Followers { get; set; }

            [DataMember(Name = "following")]
            public int Following { get; set; }
            [DataMember(Name = "updates")]
            public int Updates { get; set; }
        }

        [DataContract]
        public class YammerSchool
        {
            [DataMember(Name = "degree")]
            public string Degree { get; set; }

            [DataMember(Name = "description")]
            public string Description { get; set; }

            [DataMember(Name = "end_year")]
            public string EndYear { get; set; }

            [DataMember(Name = "start_year")]
            public string StartYear { get; set; }

            [DataMember(Name = "school")]
            public string School { get; set; }
        }

        [DataContract]
        public class YammerEmployer
        {
            [DataMember(Name = "description")]
            public string Description { get; set; }
            [DataMember(Name = "employer")]
            public string Employer { get; set; }

            [DataMember(Name = "end_year")]
            public string EndYear { get; set; }

            [DataMember(Name = "position")]
            public string Position { get; set; }

            [DataMember(Name = "start_year")]
            public string StartYear { get; set; }
        }

        [DataContract]
        public class YammerSettingsAndFeedsAndGroups
        {
            [DataMember(Name = "network_settings")]
            public YammerNetworkSettings NetworkSettings { get; set; }
            [DataMember(Name = "home_tabs")]
            public List<YammerGroupsAndFeeds> GroupsAndFeeds { get; set; }

            public YammerSettingsAndFeedsAndGroups()
            {
                this.NetworkSettings = new YammerNetworkSettings();
                this.GroupsAndFeeds = new List<YammerGroupsAndFeeds>();
            }
        }

        [DataContract]
        public class YammerGroupsAndFeeds
        {
            [DataMember(Name = "name")]
            public string Name { get; set; }

            [DataMember(Name = "select_name")]
            public string SelectName { get; set; }
            [DataMember(Name = "type")]
            public string Type { get; set; }

            [DataMember(Name = "feed_description")]
            public string Description { get; set; }

            [DataMember(Name = "ordering_index")]
            public int OrderingIndex { get; set; }

            [DataMember(Name = "url")]
            public string Url { get; set; }

            [DataMember(Name = "group_id")]
            public string GroupID { get; set; }

            [DataMember(Name = "private")]
            public bool IsPrivate { get; set; }
        }

        [DataContract]
        public class YammerNetworkSettings
        {
            [DataMember(Name = "message_prompt")]
            public string MessagePrompt { get; set; }

            [DataMember(Name = "allow_attachments")]
            public bool AllowAttachments { get; set; }
            [DataMember(Name = "show_communities_directory")]
            public bool ShowCommunitiesDirectory { get; set; }

            [DataMember(Name = "enable_groups")]
            public bool EnableGroups { get; set; }

            [DataMember(Name = "allow_yammer_apps")]
            public bool AllowYammerApps { get; set; }

            [DataMember(Name = "admin_can_delete_messages")]
            public bool AdminCanDeleteMessages { get; set; }

            [DataMember(Name = "allow_inline_document_view")]
            public bool AllowInlineDocumentView { get; set; }

            [DataMember(Name = "allow_inline_video")]
            public bool AllowInlineVideo { get; set; }

            [DataMember(Name = "enable_private_messages")]
            public bool EnablePrivateMessages { get; set; }
            [DataMember(Name = "allow_external_sharing")]
            public bool AllowExternalSharing { get; set; }

            [DataMember(Name = "enable_chat")]
            public bool EnableChat { get; set; }
        }

        [DataContract]
        public class YammerContactInfo
        {
            [DataMember(Name = "has_fake_email")]
            public bool HasFakeEmail { get; set; }

            [DataMember(Name = "email_addresses")]
            public List<YammerEmailAddresses> EmailAddresses { get; set; }

            [DataMember(Name = "phone_numbers")]
            public List<YammerPhoneNumbers> PhoneNumbers { get; set; }

            [DataMember(Name = "im")]
            public YammerIM IM { get; set; }
            public YammerContactInfo()
            {
                this.EmailAddresses = new List<YammerEmailAddresses>();
                this.PhoneNumbers = new List<YammerPhoneNumbers>();
                this.IM = new YammerIM();
            }
        }
        [DataContract]
        public class YammerEmailAddresses
        {
            [DataMember(Name = "address")]
            public string Address { get; set; }

            [DataMember(Name = "type")]
            public string Type { get; set; }

            public YammerEmailAddresses() { }
            public YammerEmailAddresses(string address, string type)
            {
                this.Address = address;
                this.Type = type;
            }
        }

        [DataContract]
        public class YammerPhoneNumbers
        {
            [DataMember(Name = "number")]
            public string PhoneNumber { get; set; }
            [DataMember(Name = "type")]
            public string Type { get; set; }
        }

        [DataContract]
        public class YammerIM
        {
            [DataMember(Name = "provider")]
            public string Provider { get; set; }
            [DataMember(Name = "username")]
            public string UserName { get; set; }
        }

    }
  22. MainPage.xaml: Add the following code for a button control to the main Windows phone page to allow users to navigate to the View All Users page.
    <Button Name="btnUsers" Grid.Row="5" HorizontalAlignment="Center" VerticalAlignment="Top" Click="btnAllUserYammer_Click">
    Get all Users
    </Button>
  23. MainPage.xaml.cs: Add the following code and the event handler for the “Get All User” button:
    private void btnAllUserYammer_Click(object sender, RoutedEventArgs e)
    {
        NavigationService.Navigate(new Uri("/ViewAllUsers.xaml", UriKind.Relative));
    }
  24. ViewAllUsers.xaml: Add the following code for the ListBox markup code:

    In the <Grid x:Name=“ContentPanel”> section, define the user interface to display messages retrieved from Yammer. To do this, use the following code snippet. Use the style properties you defined in previous sections of this chapter to “Retrieve All Messages”.

    <ListBox x:Name="ListBoxAllUsers" ItemsSource="{Binding}" >
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <Line Stroke="White" X1="0" Y1="25" X2="800" Y2="25" />
                                <TextBlock Text="{Binding ID}" Style="{StaticResource SimpleBlock}" />
                                <TextBlock Text="{Binding FullName}" Margin="5" Style="{StaticResource TitleBlock}" />
                                <Line Stroke="White" X1="0" Y1="25" X2="800" Y2="25" />
                            </StackPanel>

                        </DataTemplate>
                    </ListBox.ItemTemplate>

                </ListBox>

                <TextBlock x:Name="txtResponses" Text="" TextAlignment="Center" />

    The previous code snippet uses a ListBox control with an Item template. The Item template defines a StackPanel to display a line, a text block for the message ID, a text block for MessageContent.PlainText, and another line as a row separator. Define the appropriate binding as per the YammerUsers class definition.

  25. ViewAllUsers.xaml.cs: Add the following code for the LoadData method.

    The code-behind file of ViewAllUsers.xaml.cs implements the server-side code that calls the Yammer REST API using the SDK’s helper functions.

    private void Loaddata()
    {
        // Call this API to test if the auth token works
        var messageApiEndpoint = new Uri(Constants.ApiEndpoints.allUsersUrl, UriKind.Absolute);

        OAuthUtils.GetJsonFromApi(messageApiEndpoint, onSuccess: response =>
        {
            byte[] byteArray = System.Text.UTF8Encoding.UTF8.GetBytes(response);
            MemoryStream res = new MemoryStream(byteArray);

            List<YammerUser> users = SerializationUtils.DeserializeJson<List<YammerUser>>(res);

            ListBoxAllUsers.DataContext = users;
            ListBoxAllUsers.ItemsSource = users;

            // we just dump the unformated json string response into a textbox
            Dispatcher.BeginInvoke(() => txtResponses.Text = "Messages Retrieved");
        },
          onErrorResponse: errorResponse =>
          {
              Dispatcher.BeginInvoke(() =>
              {
                  MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                  txtResponses.Text = string.Empty;
              });
          },
             onException: ex =>
             {
                 Dispatcher.BeginInvoke(() =>
                 {
                     MessageBox.Show(ex.ToString(), "Unexpected exception!", MessageBoxButton.OK);
                     txtResponses.Text = string.Empty;
                 });
             }
     );
        Dispatcher.BeginInvoke(() => txtResponses.Text = "Retrieving ...");
    }

    The Loaddata method calls the Windows Phone SDK’s GetJsonFromApi method, which returns the JSON stream, which is then deserialized into a .NET object. The collection object messages of the YammerUsers class is then assigned to ListBox as an ItemsSource property.

  26. Accessing namespaces: Use the following code to reference the namespaces that the page will be using frequently.
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using SPDS UniversityWinPhoneApp.Common;
    using Yammer.OAuthSDK.Utils;
    using Yammer.OAuthSDK.Model;
    using System.IO;
    using System.Text;
  27. Modify page constructor method: Modify the page’s Constructor method to call the LoadData() method.
    public ViewAllUsers ()
            {
                InitializeComponent();
                Loaddata();
            }

User Management: View Data About the Current User

The Yammer REST API provides an endpoint https://www.yammer.com/api/v1/users/current.json to retrieve the current user’s information. It includes profile information like username, job title, department, and contact info (email address, phone number, IM, and so on). Once you have the right permissions or the user has authorized your Yammer app to use her data, you can retrieve any piece of information belonging to a user node.

  1. Add a page to the Windows phone project: In the sample application we are building, we’ll add a new Windows phone page to display the user’s information. To do that, add a new Windows phone page to your Windows phone project as you did in previous examples.
  2. Add an endpoint in the Constants class: Define a Constant property in the Yammer.OAUthSDK’s Constants class.
    public const string CurrentUserUrl = "https://www.yammer.com/api/v1/users/current.json";
  3. ViewUserInfo.xaml: Define the user interface to display user information retrieved from Yammer. To do this, use the following code snippet:
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <StackPanel Grid.Row="0" Margin="12,17,0,28">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="User Name:" Margin="9,0,2,5"  Style="{StaticResource InputLabel}" />
                        <TextBlock x:Name="tbUserName" Text="" Margin="9,-7,2,5" Style="{StaticResource InputLabel}"/>
                    </StackPanel>

                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="job_title:" Margin="9,-7,0,5" Style="{StaticResource InputLabel}" />
                        <TextBlock x:Name="tbjob_title" Text="" Margin="9,-7,0,5" Style="{StaticResource InputLabel}"/>
                    </StackPanel>

                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="Followers:" Margin="9,-7,0,2" Style="{StaticResource InputLabel}" />
                        <TextBlock x:Name="tbFollowers" Text="" Margin="9,-7,0,5" Style="{StaticResource InputLabel}" />
                    </StackPanel>

                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="Location:" Margin="9,-7,0,5" Style="{StaticResource InputLabel}" />
                        <TextBlock x:Name="tbLocation" Text="" Margin="9,-7,0,5" Style="{StaticResource InputLabel}" />
                    </StackPanel>

                    <TextBlock x:Name="txtResponses" Text="" TextAlignment="Center" />
                </StackPanel>
    </Grid>
  4. ViewUserInfo.xaml.cs: Loaddata method.

    In the code-behind of the ViewUserInfo.xaml.cs file, you can use the same code that was used to retrieve the user list. The only difference is to replace the List<YammerUser> collection object with the YammerUser object as the returned JSON object will hold only one user’s information. I also added a separator function called RenderUI by passing the deserialize JSON YammerUser object.

    private void Loaddata()
    {
        // Call this API to test if the auth token works
        var messageApiEndpoint = new Uri(Constants.ApiEndpoints.CurrentUserUrl, UriKind.Absolute);

        OAuthUtils.GetJsonFromApi(messageApiEndpoint, onSuccess: response =>
        {
            string s = response;
            byte[] byteArray = System.Text.UTF8Encoding.UTF8.GetBytes(response);
            MemoryStream res = new MemoryStream(byteArray);

            YammerUser YammerUser = SerializationUtils.DeserializeJson<YammerUser>(res);

            RenderUI(YammerUser);

            // we just dump the unformated json string response into a textbox
            Dispatcher.BeginInvoke(() => txtResponses.Text = "User Info Retrieved");
        },
          onErrorResponse: errorResponse =>
          {
              Dispatcher.BeginInvoke(() =>
              {
                  MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                  txtResponses.Text = string.Empty;
              });
          },
             onException: ex =>
             {
                 Dispatcher.BeginInvoke(() =>
                 {
                     MessageBox.Show(ex.ToString(), "Unexpected exception!", MessageBoxButton.OK);
                     txtResponses.Text = string.Empty;
                 });
             }
     );
        Dispatcher.BeginInvoke(() => txtResponses.Text = "Retrieving …");
    }
  5. RenderUI method: This is a very simple method that assigns the YammerUser’s properties to the UI object to display the user information.
    private void  RenderUI(YammerUser yammeruser)
    {
        tbUserName.Text = yammeruser.FullName;
        tbjob_title.Text = yammeruser.JobTitle;
        tbFollowers.Text = yammeruser.UserStats.Following.ToString();

    }

    That’s it! You can view the current user’s information. You can extend the code to display the other pieces of user information like user stats (followers, following, and so on), group membership details, and more.

  6. Accessing namespaces: Use the following code snippet to access namespaces that the page will be using frequently.
    using Yammer.OAuthSDK.Model;
    using Yammer.OAuthSDK.Utils;
    using YammerBook_Sample.Common;
    using System.IO;
    using System.Text;

    public ViewUserInfo ()
            {
                InitializeComponent();
                Loaddata();
            }
  7. MainPage.xaml: Now you need to integrate the newly added page with MainPage.xaml. To do that, add another button control as you did in previous examples and write the code-behind onClick event handler to navigate to the newly added page. First, add the “View Current User Info” markup to MainPage.xaml:
    <Button Name="btnViewUser" HorizontalAlignment="Center" Style="{StaticResource TabItemFirst}" VerticalAlignment="Top" Click="btnViewUserYammer_Click">
           View Current User Info
    </Button>
  8. MainPage.xaml.cs: You’ll need to implement a click event handler for the button you added to MainPage.xaml. To do this, open the MainPage.xaml.cs file and add the following code snippet.
    private void btnViewUserYammer_Click(object sender, RoutedEventArgs e)
    {
        NavigationService.Navigate(new Uri("/ViewUserInfo.xaml", UriKind.Relative));
    }

User Management Search by Email Address

The Yammer REST API provides an endpoint called https://www.yammer.com/api/v1/users/[:id].json to retrieve the current users’ information and it includes profile information like username, job title, department, and contact info (email addresses, phone number, IM, and so on). Once you have the right permission or the user has already authorized your Yammer app to use the user’s data, you can retrieve any piece of information belonging to a user node. This is very similar to the REST API to view the current user; the only difference is that this API needs the user ID to retrieve the other user’s data instead of the retrieving data for the logged-in user.

  1. Add a page to Windows phone project.

    In the sample application we are building, we’ll add a new Windows phone page to display the user’s information. For that, you need to add a new Windows phone page to your Windows phone project as you have done in previous examples. You can also use the same page used in the previous example, called ViewUserInfo.xaml, to display the other user data by using passing parameters between pages to decide on calling REST API for the current user or for other users. In this book, we are going to keep it simple and use another page to display other user information.

  2. Add an endpoint in the Constants class. Define a constant property in Yammer.OAUthSDK’s Constants class.
    public const string SearchUserByEmail= "https://www.yammer.com/api/v1/users/by_email.json?email=";
  3. Define the user interface to display user information retrieved from Yammer. For this, use the following code snippet.
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <StackPanel Grid.Row="0" Margin="12,17,0,28">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="User Name:" Margin="9,0,2,5"  Style="{StaticResource InputLabel}" />
                        <TextBlock x:Name="tbUserName" Text="" Margin="9,-7,2,5" Style="{StaticResource InputLabel}"/>
                    </StackPanel>

                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="job_title:" Margin="9,-7,0,5" Style="{StaticResource InputLabel}" />
                        <TextBlock x:Name="tbjob_title" Text="" Margin="9,-7,0,5" Style="{StaticResource InputLabel}"/>
                    </StackPanel>

                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="Followers:" Margin="9,-7,0,2" Style="{StaticResource InputLabel}" />
                        <TextBlock x:Name="tbFollowers" Text="" Margin="9,-7,0,5" Style="{StaticResource InputLabel}" />
                    </StackPanel>

                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="Location:" Margin="9,-7,0,5" Style="{StaticResource InputLabel}" />
                        <TextBlock x:Name="tbLocation" Text="" Margin="9,-7,0,5" Style="{StaticResource InputLabel}" />
                    </StackPanel>

                    <TextBlock x:Name="txtResponses" Text="" TextAlignment="Center" />
                </StackPanel>
    </Grid>
  4. SearchUserInfo.xaml.cs: Loaddata method.

    In the code-behind of the SearchUserInfo.xaml.cs file, you can use the same code that was used to retrieve the user list. The only difference is to replace the List<YammerUser> collection object with the YammerUser object as the returned JSON object will hold only one user’s information. I also added a separator function called RenderUI by passing the deserialize JSON YammerUser object.

    private void Loaddata()
    {
        // Call this API to test if the auth token works
        var emailaddress = "[email protected]";
        var messageApiEndpoint = new Uri(Constants.ApiEndpoints.SearchUserByEmail + emailaddress.ToString(), UriKind.Absolute);

        OAuthUtils.GetJsonFromApi(messageApiEndpoint, onSuccess: response =>
        {
            string s = response;
            byte[] byteArray = System.Text.UTF8Encoding.UTF8.GetBytes(response);
            MemoryStream res = new MemoryStream(byteArray);

            List<YammerUser> YammerUser = SerializationUtils.DeserializeJson<List<YammerUser>>(res);

            RenderUI(YammerUser[0]);

            // we just dump the unformated json string response into a textbox
            Dispatcher.BeginInvoke(() => txtResponses.Text = "User Info Retrieved");
        },
          onErrorResponse: errorResponse =>
          {
              Dispatcher.BeginInvoke(() =>
              {
                  MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                  txtResponses.Text = string.Empty;
              });
          },
             onException: ex =>
             {
                 Dispatcher.BeginInvoke(() =>
                 {
                     MessageBox.Show(ex.ToString(), "Unexpected exception!", MessageBoxButton.OK);
                     txtResponses.Text = string.Empty;
                 });
             }
     );
        Dispatcher.BeginInvoke(() => txtResponses.Text = "Retrieving …");
    }
  5. RenderUI method: This is very simple method that assigns the YammerUser’s properties to a UI object to display the user information.
    private void  RenderUI(YammerUser yammeruser)
    {
        tbUserName.Text = yammeruser.FullName;
        tbjob_title.Text = yammeruser.JobTitle;
        tbFollowers.Text = yammeruser.UserStats.Following.ToString();

    }

    That’s it. You can view the current user’s information. You can extend the code to display the other piece of user information like user stats (followers, following, and so on), group members, ship details, and so on.

  6. Accessing namespaces: Use the following code snippet to namespaces that the page will be using frequently.
    using Yammer.OAuthSDK.Model;
    using Yammer.OAuthSDK.Utils;
    using YammerBook_Sample.Common;
    using System.IO;
    using System.Text;
  7. Modify the page constructor method. Modify the page’s constructor method to call the LoadData() method
    public SearchUserInfo ()
            {
                InitializeComponent();
                Loaddata();
            }
  8. Now you need to integrate the newly added page with MainPage.xaml. To do that, you add another button control as you have done for previous examples and write the code-behind onClick event handler to navigate to the newly added page. First add the Search User Info markup to the MainPage.xaml file.
    <Button Name="btnSearchUser" HorizontalAlignment="Center" Style="{StaticResource TabItemFirst}" VerticalAlignment="Top" Click="btnSearchUserYammer_Click">
    Search User Info
    </Button>
  9. You need to implement a click event handler for the button you added to MainPage.xaml. To do this, open the MainPage.xaml.cs file and add the following code snippet:
    private void btnSearchUserYammer_Click(object sender, RoutedEventArgs e)
    {
        NavigationService.Navigate(new Uri("/SearchUserInfo.xaml", UriKind.Relative));
    }

    User Management” Retrieve All Users from a Group

    The Yammer REST API provides an endpoint called https://www.yammer.com/api/v1/users/in_group/[:id].json to retrieve all users who are members of a Yammer group in your Yammer network.

  10. Add a page to the Windows phone project.

    In the sample application we are building, we’ll add a new Windows phone page to display users who are member of a Yammer group. To do that, add a new Windows phone page to your Windows Phone project as you did in previous examples. You can also use the same page used in the ViewAllUsers.xaml example to display the user’s list by using passing parameters between pages to decide on calling REST API for the current user or for other users. In this book, we going to keep it simple and use another page to display other user information.

  11. Add an endpoint to the Constants class. Define a constant property to the Yammer.OAUthSDK’s Constants class.
    public const string ViewUserinGroup = "https://www.yammer.com/api/v1/users/in_group/";
  12. Define the user interface to display the users list retrieved from Yammer. To do this, use the following code snippet:
    <!--ContentPanel - place additional content here-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <ListBox x:Name="ListBoxAllUsers" ItemsSource="{Binding}" >
                    <ListBox.ItemTemplate>
                        <DataTemplate>

                            <StackPanel Orientation="Vertical">
                                <Line Stroke="White" X1="0" Y1="25" X2="800" Y2="25" />
                                <TextBlock Text="{Binding Department}" Style="{StaticResource SimpleBlock}" />
                                <TextBlock Text="{Binding FullName}" Margin="5" Style="{StaticResource TitleBlock}" />
                                <Line Stroke="White" X1="0" Y1="25" X2="800" Y2="25" />

                            </StackPanel>

                        </DataTemplate>
                    </ListBox.ItemTemplate>

                </ListBox>

                <TextBlock x:Name="txtResponses" Text="" TextAlignment="Center" />
            </Grid>
  13. ViewAllUserinaGroup.xaml.cs: LoadData method.

    In the code-behind of the ViewAllUserinaGroup.xaml.cs file, you can use the same code that was used to retrieve the user list. The only difference is the REST API endpoint.

    private void Loaddata()
    {
        // Call this API to test if the auth token works
        var GroupId = 4659506;
        var messageApiEndpoint = new Uri(Constants.ApiEndpoints.ViewUserinGroup + GroupId + ".json", UriKind.Absolute);

        OAuthUtils.GetJsonFromApi(messageApiEndpoint, onSuccess: response =>
        {
            byte[] byteArray = System.Text.UTF8Encoding.UTF8.GetBytes(response);
            MemoryStream res = new MemoryStream(byteArray);

            List<YammerUser> users = SerializationUtils.DeserializeJson<List<YammerUser>>(res);

            ListBoxAllUsers.DataContext = users;
            ListBoxAllUsers.ItemsSource = users;

            // we just dump the unformated json string response into a textbox
            Dispatcher.BeginInvoke(() => txtResponses.Text = "Users Retrieved");
        },
          onErrorResponse: errorResponse =>
          {
              Dispatcher.BeginInvoke(() =>
              {
                  MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                  txtResponses.Text = string.Empty;
              });
          },
             onException: ex =>
             {
                 Dispatcher.BeginInvoke(() =>
                 {
                     MessageBox.Show(ex.ToString(), "Unexpected exception!", MessageBoxButton.OK);
                     txtResponses.Text = string.Empty;
                 });
             }
     );
        Dispatcher.BeginInvoke(() => txtResponses.Text = "Retrieving …");
    }
  14. Accessing namespaces. Add the following code snippet to namespaces that the page will be using frequently:
    using Yammer.OAuthSDK.Model;
    using Yammer.OAuthSDK.Utils;
    using YammerBook_Sample.Common;
    using System.IO;
    using System.Text;
  15. Modify the page constructor method. Modify the page’s constructor method to call the Loaddata() method.
    public ViewAllUserinaGroup()
            {
                InitializeComponent();
                Loaddata();
            }
  16. Now you need to integrate the newly added page with MainPage.xaml. To do that, you add another button control as you did in previous examples and write the code-behind onClick event handler to navigate to the newly added page. First add the “View Users in a Group Info” markup in the MainPage.xaml:
    <Button Name="btnViewUserinGroup" HorizontalAlignment="Center" Style="{StaticResource TabItemFirst}" VerticalAlignment="Top" Click="btnViewUserinGroup_Click">
     View Users in a Group
    </Button>
  17. You need to implement a click event handler for the button you added to the MainPage.xaml file. To do this, open the MainPage.xaml.cs file and add the following code snippet:

    Code Snippet: Use the MainPage.xaml.cs to handle the click event, OnClick users will be redirected to “ViewAllUsersinaGroup.xaml” page

    private void btnViewUserinGroup_Click(object sender, RoutedEventArgs e)
    {
       NavigationService.Navigate(new Uri("/ViewAllUsersinaGroup.xaml", UriKind.Relative));
    }

    Run the Windows Phone App

  18. Build the solution and run the Windows phone app using the emulator (Figure 8-22).

    9781484209448_Fig08-22.jpg

    Figure 8-22. Run the Windows phone app using the emulator

  19. In Run mode, the home page will look like Figure 8-23.

    9781484209448_Fig08-23.jpg

    Figure 8-23. Run the Windows phone app using the emulator

  20. Now click on the “Sign In with Yammer” button, which will initiate the OAuth authentication flow that you’ve seen in previous steps. After successfully logging in, you will be redirected to this home page.
  21. To post a message on Yammer, click on “Post a Message”. Likewise you will be able to like a message and unlike a message using those buttons. Note that we have hard-coded the message_id in the previous scenarios; however, you can use the “View All message” button to retrieve the messages and then use like or unlike.
  22. To view all the messages on a separate Windows Phone page, click on the View All Messages button. You will be presented with the All messages view in a grid, as illustrated in Figure 8-24.

    9781484209448_Fig08-24.jpg

    Figure 8-24. View All Message page displays the message’s ID and body

In this exercise, you have learned how to integrate the Windows phone app with Yammer using the Yammer Windows Phone SDK.

Summary

By now you are familiar with the Yammer SDKs released by Yammer. In this chapter, you explored how to implement the “Sign In with Yammer” button using Yammer’s SDKs for Windows Phone App and then learned how to implement Yammer features into the Windows Phone by using the Windows Phone SDK.

We hope this book has helped you understand the value of Yammer and develop integrations with Yammer using existing integration features. As the Yammer team keeps adding new features, we recommend that you follow https://developer.yammer.com to get the latest updates on new features that you can use to develop integration with Yammer.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset