Skip to content

Latest commit

 

History

History
214 lines (160 loc) · 8.29 KB

File metadata and controls

214 lines (160 loc) · 8.29 KB

Exercise 5: Calling the Microsoft Graph

In this exercise, you'll add code to the solution which posts a message in the Teams channel when a new map point is added. The completed solution is in the "Exercise 5" branch of this repo.

If you don't have developer tools, grab the map-view.sppkg file from the Exercise 5 folder and skip to Step 3.

Step 1: Modify the code

a. Ensure you have downloaded or cloned this repository, and open the Solution/MapViewer folder in your code editor.

The src/webparts/mapViewer/services/GraphService folder contains the Microsoft Graph code for the solution. Open IGraphService.ts and add a function to the IGraphService interface:

sendToChannel(message: string): Promise<void | string>;

The completed file is here.

b. In the GraphService.ts file, import a reference to the Teams JavaScript SDK at the top of the file.

import * as microsoftTeams from "@microsoft/teams-js";

Then add a function to get the Teams context from the Teams JavaScript SDK.

private async getTeamsContext(): Promise<any> {

    return new Promise<any> ((resolve, reject) => {
        if (microsoftTeams) {
            microsoftTeams.getContext((context) => {
                resolve(context);
            });
        } else {
            reject ("Error: Teams context not found");
        }    
    });
}

Finally, add a function to send a message to the current Teams channel using the Microsoft Graph.

public async sendToChannel(message: string): Promise<void | string> {

    const teamsContext = await this.getTeamsContext();
    const teamId = teamsContext.groupId;
    const channelId = teamsContext.channelId;

    return new Promise<void | string>((resolve, reject) => {
        this.serviceProps.graphClient.api(
            `/teams/${teamId}/channels/${channelId}/messages`)
            .post({
                body: {
                    content: message,
                    contentType: "text"
                }
            }, ((err, res) => {
                if (!err) {
                    resolve();
                } else {
                    reject(err);
                }
            }));
    });
}

The completed file is here.

c. The src/webparts/mapViewer/services/MapDataService folder contains the code that reads and updates map points using the Graph service and the Bing Maps service. Modify MapDataService.ts to add a call to the new sendToChannel() function. Add it to the getMapPoints() function where you see the comment,

/* 
 * Add the call to sendToChannel() here 
 */

Here is the snippet of code to add:

await this.serviceProps.graphService.sendToChannel(
    `New point ${p.title} added at ${p.latitude}, ${p.longitude}`
);

The updated getMapPoints() function should look like this:

public async getMapPoints(geocode: boolean): Promise<ILocation[]> {

    const locationMapper = new LocationMapper();

    let listId: string;
    try {
        listId = await this.serviceProps.graphService.getListId(
            this.serviceProps.siteId, this.serviceProps.listName
        );    
    }
    catch (error) {
        if (error.statusCode === 404) {
            listId = await this.serviceProps.graphService.createList(
                this.serviceProps.siteId, this.serviceProps.listName,
                locationMapper
            );
        } else throw(error);
    }

    const points = await this.serviceProps.graphService.getListItems<ILocation>(
        this.serviceProps.siteId, listId, locationMapper
    );

    if (geocode) {
        for (let p of points) {
            if ((!p.latitude || !p.longitude) &&
                    (p.address || p.city || p.stateProvince || p.country)) {
                
                // If here, we're missing the geo-coordinates for an item and have
                // address or other info. Try to geocode it.
                let coordinates = await this.serviceProps.bingMapsService.geoCode(
                    p.country, p.stateProvince, p.city, p.address
                );

                if (typeof coordinates === 'object') {
                    // If here, the geocode was succesful - update the item
                    p.latitude = coordinates.latitude;
                    p.longitude = coordinates.longitude;
                    await this.serviceProps.graphService.updateListItem(
                        this.serviceProps.siteId, listId, locationMapper, p.id,
                        {
                            latitude: p.latitude,
                            longitude: p.longitude
                        }
                    );
                    await this.serviceProps.graphService.sendToChannel(
                        `New point ${p.title} added at ${p.latitude}, ${p.longitude}`
                    );
                }
            }
        }
    }

    return (points);
}

The completed file is here.

d. We're going to need permission to use the Graph API to post in the Teams channel. To request this, edit the config/package-solution.json and add a new item in the webApiPermissionRequests array:

      {
        "resource": "Microsoft Graph",
        "scope": "ChannelMessage.Send"
      }

The completed file is here.

Step 2: Rebuild the SharePoint solution package

This assumes you already built the package as explained in Exercise 4 Step 1.

a. If you're running locally, you can make simple code changes without re-deploying the SharePoint solution package, but in this case we added a permission request so it's time to rebuild the package.

Return to the command line to rebuild the solution package. If you're running locally,

gulp bundle
gulp package-solution

If you want to deploy the JavaScript bundle to the SharePoint CDN,

gulp bundle --ship
gulp package-solution --ship

Step 3: Re-deploy the SharePoint solution package and approve permissions

You need to repeat steps 2 and 3 of Exercise 4 to update your work in SharePoint.

a. Return to the SharePoint App catalog and upload the map-viewer.sppkg file again.

Part4

b. Return to the API Access screen; you should see the new permission . Select it 1️⃣ and use Approve 2️⃣.

Part4

Step 4: Test the change

a. If you're running locally (you chose Option 1 in Exercise 4), ensure your local web server is running in the terminal window. If not, start it again.

gulp serve --nobrowser

a. Return to Microsoft Teams and refresh the Map View tab. Add a new point to the map; a notification should appear in the channel.

Part4

Congratulations, you've completed all 5 parts of the workshop! Please check out these resources and thanks for your interest in Microsoft 365 development!