-
Notifications
You must be signed in to change notification settings - Fork 67
feat: adds da-foodbank-friend sample #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
leeford
wants to merge
2
commits into
pnp:main
Choose a base branch
from
leeford:da-foodbank-friend
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # TeamsFx files | ||
| env/.env.*.user | ||
| env/.env.local | ||
| .localConfigs | ||
| appPackage/build | ||
|
|
||
| # dependencies | ||
| node_modules/ | ||
|
|
||
| # misc | ||
| .env | ||
| env/.env.* | ||
| .deployment | ||
| .DS_Store | ||
|
|
||
| # generated files | ||
| appPackage/.generated | ||
|
|
||
| # Allow example env files to be committed | ||
| !env/.env.*.example |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "recommendations": [ | ||
| "TeamsDevApp.ms-teams-vscode-extension" | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| { | ||
| "version": "0.2.0", | ||
| "configurations": [ | ||
| { | ||
| "name": "Preview in Copilot (Edge)", | ||
| "type": "msedge", | ||
| "request": "launch", | ||
| "url": "https://m365.cloud.microsoft/chat/entity1-d870f6cd-4aa5-4d42-9626-ab690c041429/${agent-hint}?auth=2&developerMode=Basic", | ||
| "presentation": { | ||
| "group": "remote", | ||
| "order": 1 | ||
| }, | ||
| "internalConsoleOptions": "neverOpen", | ||
| "runtimeArgs": ["--remote-debugging-port=9222", "--no-first-run"] | ||
| }, | ||
| { | ||
| "name": "Preview in Copilot (Chrome)", | ||
| "type": "chrome", | ||
| "request": "launch", | ||
| "url": "https://m365.cloud.microsoft/chat/entity1-d870f6cd-4aa5-4d42-9626-ab690c041429/${agent-hint}?auth=2&developerMode=Basic", | ||
| "presentation": { | ||
| "group": "remote", | ||
| "order": 2 | ||
| }, | ||
| "internalConsoleOptions": "neverOpen", | ||
| "runtimeArgs": ["--remote-debugging-port=9223", "--no-first-run"] | ||
| } | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "debug.onTaskErrors": "abort", | ||
| "json.schemas": [ | ||
| { | ||
| "fileMatch": ["/aad.*.json"], | ||
| "schema": {} | ||
| } | ||
| ], | ||
| "files.readonlyInclude": { | ||
| "appPackage/.generated/**/*": true | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| # Declarative Agent - Foodbank Friend | ||
|
|
||
|  | ||
|
|
||
| ## Summary | ||
|
|
||
| This repository contains a declarative agent that helps users in the UK find local food banks, see what items they need, and schedule volunteer donation visits. The agent connects to the [GiveFood API](https://www.givefood.org.uk/api/) to search for nearby food banks and their current needs, then coordinates the scheduling process by creating Outlook calendar appointments and tracking volunteer commitments in SharePoint. A key point of emphasis on this agent was combining multiple action types - **Remote MCP Servers** for Microsoft 365 services (Outlook Calendar and SharePoint Lists) alongside a traditional **OpenAPI** connector for the external GiveFood API. The agent is built using the Microsoft 365 Agents Toolkit. | ||
|
|
||
|  | ||
|
|
||
| ## Contributors | ||
|
|
||
| * [Lee Ford](https://github.com/leeford) - M365 Development MVP | ||
|
|
||
| ## Version history | ||
|
|
||
| Version|Date|Comments | ||
| -------|----|-------- | ||
| 1.0 | March 25, 2026 | Initial solution | ||
|
|
||
| > **Prerequisites** | ||
| > | ||
| > To run this app template from your local dev machine, you will need: | ||
| > | ||
| > * A [Microsoft 365 account for development](https://docs.microsoft.com/microsoftteams/platform/toolkit/accounts) | ||
| > * [Microsoft 365 Agents Toolkit Visual Studio Code Extension](https://aka.ms/teams-toolkit) | ||
| > * [Microsoft 365 Copilot license](https://learn.microsoft.com/microsoft-365-copilot/extensibility/prerequisites#prerequisites) | ||
| > * A SharePoint site with a custom list for tracking volunteer commitments (see setup instructions below) | ||
|
|
||
| ## Minimal path to awesome | ||
|
|
||
| 1. Clone this repository | ||
|
|
||
| 2. Register an Entra ID application in Azure: | ||
|
|
||
| 1. Go to [Azure portal](https://portal.azure.com/) | ||
| 2. Select **Microsoft Entra ID** > **Manage** > **App registrations** > **New registration** | ||
| 3. Enter a name for the app (e.g., Foodbank Friend) | ||
| 4. Select **Accounts in this organizational directory only** | ||
| 5. Under **Redirect URI**, select **Web** and enter `https://teams.microsoft.com/api/platform/v1.0/oAuthRedirect` | ||
| 6. Select **Register** | ||
| 7. In the app registration, go to **Certificates & secrets** and create a new client secret | ||
| 8. Copy the client secret value | ||
| 9. In the app registration, go to **API permissions** and add the following permissions: | ||
| * **agent365.svc.cloud.microsoft** > **Delegated permissions** > `McpServers.Calendar.All`, `McpServers.SharepointLists.All` | ||
| 10. Select **Grant admin consent for <your organization>** to grant the permissions | ||
|
|
||
| 3. Create a SharePoint list for tracking volunteer commitments: | ||
|
|
||
| 1. Go to your SharePoint site | ||
| 2. Create a new list named **Volunteer Commitments** with the following columns: | ||
| * **Title** (Single line of text) - Default column | ||
| * **VolunteerName** (Single line of text) | ||
| * **FoodBankName** (Single line of text) | ||
| * **FoodBankAddress** (Multiple lines of text) | ||
| * **AppointmentDate** (Date and Time) | ||
| * **ItemsCommitted** (Multiple lines of text) | ||
| * **Status** (Choice: Scheduled, Completed, Cancelled) | ||
| * **CreatedDate** (Date and Time) | ||
| 3. Note down the **Site ID** and **List ID** (you can find these in the list settings URL or via Graph Explorer) | ||
|
|
||
| 4. In the [Teams developer portal](https://dev.teams.microsoft.com/) under **Tools**, create a new **OAuth client registration** with the following information (replace `<your-tenant-id>` with your own tenant ID): | ||
|
|
||
| **App settings** | ||
|
|
||
| * **Registration name**: Foodbank Friend | ||
| * **Base URL**: `https://agent365.svc.cloud.microsoft` | ||
| * **Restrict usage by org**: My organization only | ||
| * **Restrict usage by app**: Any Teams app (when agent is deployed, use the Teams app ID) | ||
|
|
||
| **OAuth settings** | ||
| * **Client ID**: <Entra ID App registration client ID> | ||
| * **Client secret**: <Entra ID App registration client secret> | ||
| * **Authorization endpoint**: `https://login.microsoftonline.com/<your-tenant-id>/oauth2/v2.0/authorize` | ||
| * **Token endpoint**: `https://login.microsoftonline.com/<your-tenant-id>/oauth2/v2.0/token` | ||
| * **Refresh endpoint**: `https://login.microsoftonline.com/<your-tenant-id>/oauth2/v2.0/token` | ||
| * **Scope**: `ea9ffc3e-8a23-4a7d-836d-234d7c7565c1/.default` | ||
|
|
||
| Save the information. A new **OAuth client registration key** will be generated. Copy the key. | ||
|
|
||
| 5. Copy `env/.env.dev.example` to `env/.env.dev` and fill in the following values: | ||
|
|
||
| ```bash | ||
| # Generated during provision by Microsoft 365 Agents Toolkit | ||
| TEAMS_APP_ID=<your-teams-app-id> | ||
| TEAMS_APP_TENANT_ID=<your-tenant-id> | ||
|
|
||
| # SharePoint Configuration | ||
| # Format: hostname,siteCollectionId,siteId (e.g., contoso.sharepoint.com,12345678-...,abcdef...) | ||
| SHAREPOINT_SITE_ID=<your-sharepoint-site-id> | ||
| SHAREPOINT_LIST_ID=<your-sharepoint-list-id> | ||
|
|
||
| # OAuth Plugin Vault Reference ID - from Teams Developer Portal OAuth client registration | ||
| OAUTH_REFERENCE_ID=<oauth-client-registration-id-from-teams-developer-portal> | ||
| ``` | ||
|
|
||
| 6. From Microsoft 365 Agents Toolkit, sign-in to your Microsoft 365 account. | ||
| 7. From Microsoft 365 Agents Toolkit, provision the solution to create the Teams app. | ||
| 8. Go to [https://www.office.com/chat?auth=2](https://www.office.com/chat?auth=2) URL and enable the developer mode by using the `-developer on` prompt. | ||
| 9. Use one of the conversation starters to start the agent. | ||
|
|
||
| ## Features | ||
|
|
||
| The following sample demonstrates the following concepts: | ||
|
|
||
| * **Find Local Food Banks** - Query the GiveFood UK API to search for food banks near any UK location, displaying distance, address, and current needs | ||
| * **View Donation Needs** - Show detailed information about what items each food bank currently needs and what they have excess of | ||
| * **Schedule Volunteer Visits** - Create Outlook calendar appointments with full details including location, items to bring, and other needed items | ||
| * **Track Commitments** - Store volunteer commitments in a SharePoint list for record-keeping and history | ||
| * **View History** - Query SharePoint to show the user their past and upcoming volunteer commitments | ||
|
|
||
| ### APIs & Services Used | ||
|
|
||
| | Service | Type | Purpose | | ||
| |---------|------|---------| | ||
| | [GiveFood UK API](https://www.givefood.org.uk/api/) | OpenAPI | Search for UK food banks and retrieve current donation needs | | ||
| | Outlook Calendar | Remote MCP Server | Create calendar appointments for volunteer visits | | ||
| | SharePoint Lists | Remote MCP Server | Track and query volunteer commitment records | | ||
|
|
||
| ## Help | ||
|
|
||
| We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues. | ||
|
|
||
| You can try looking at [issues related to this sample](https://github.com/pnp/copilot-pro-dev-samples/issues?q=label%3A%22sample%3A%20da-foodbank-friend%22) to see if anybody else is having the same issues. | ||
|
|
||
| If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/copilot-pro-dev-samples/issues/new). | ||
|
|
||
| Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/copilot-pro-dev-samples/issues/new). | ||
|
|
||
| ## Disclaimer | ||
|
|
||
| **THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** | ||
|
|
||
|  |
28 changes: 28 additions & 0 deletions
28
samples/da-foodbank-friend/appPackage/ai-plugin-givefood.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| { | ||
| "$schema": "https://developer.microsoft.com/json-schemas/copilot/plugin/v2.4/schema.json", | ||
| "schema_version": "v2.4", | ||
| "name_for_human": "GiveFood UK API", | ||
| "description_for_human": "Search UK food banks and their current needs", | ||
| "description_for_model": "Search for UK food banks by location and retrieve their current donation needs using the GiveFood API", | ||
| "namespace": "givefood", | ||
| "functions": [ | ||
| { | ||
| "name": "searchFoodBanks", | ||
| "description": "Search for food banks near a UK location using address, postcode, or place name." | ||
| } | ||
| ], | ||
| "runtimes": [ | ||
| { | ||
| "type": "OpenApi", | ||
| "auth": { | ||
| "type": "None" | ||
| }, | ||
| "spec": { | ||
| "url": "apiSpecificationFile/givefood-openapi.yaml" | ||
| }, | ||
| "run_for_functions": [ | ||
| "searchFoodBanks" | ||
| ] | ||
| } | ||
| ] | ||
| } |
72 changes: 72 additions & 0 deletions
72
samples/da-foodbank-friend/appPackage/ai-plugin-outlook.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| { | ||
| "$schema": "https://developer.microsoft.com/json-schemas/copilot/plugin/v2.4/schema.json", | ||
| "schema_version": "v2.4", | ||
| "name_for_human": "Outlook Calendar", | ||
| "description_for_human": "Create and manage Outlook calendar events", | ||
| "description_for_model": "Create Outlook calendar appointments for volunteer food bank visits", | ||
| "namespace": "outlook", | ||
| "functions": [ | ||
| { | ||
| "name": "createEvent", | ||
| "description": "Create a calendar appointment for the volunteer's food bank visit", | ||
| "parameters": { | ||
| "type": "object", | ||
| "properties": { | ||
| "subject": { | ||
| "type": "string", | ||
| "description": "The subject/title of the calendar event" | ||
| }, | ||
| "startDateTime": { | ||
| "type": "string", | ||
| "description": "Start timestamp in ISO 8601 format YYYY-MM-DDTHH:MM:SS with timezone offset. MUST use this exact format, e.g. 2026-03-29T10:00:00+01:00" | ||
| }, | ||
| "endDateTime": { | ||
| "type": "string", | ||
| "description": "End timestamp in ISO 8601 format YYYY-MM-DDTHH:MM:SS with timezone offset. MUST use this exact format, e.g. 2026-03-29T11:00:00+01:00" | ||
| }, | ||
| "location": { | ||
| "type": "string", | ||
| "description": "The plain text address of the location, e.g. \"Sutton Coldfield Baptist Church, Trinity Hill, Sutton Coldfield, West Midlands, B72 1TA\"" | ||
| }, | ||
| "isOnlineMeeting": { | ||
| "type": "boolean", | ||
| "description": "Whether to create a Teams online meeting. MUST be set to false for in-person food bank visits." | ||
| }, | ||
| "body": { | ||
| "type": "string", | ||
| "description": "JSON string representing the event body with contentType and content properties. contentType MUST be \"HTML\". Example: {\"contentType\": \"HTML\", \"content\": \"<p>Event details</p>\"}" | ||
| }, | ||
| "attendeeEmails": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "string" | ||
| }, | ||
| "description": "Array of attendee email addresses. Pass an empty array [] as the organiser is already added automatically." | ||
| } | ||
| }, | ||
| "required": [ | ||
| "subject", | ||
| "startDateTime", | ||
| "endDateTime", | ||
| "attendeeEmails", | ||
| "isOnlineMeeting" | ||
| ] | ||
| } | ||
| } | ||
| ], | ||
| "runtimes": [ | ||
| { | ||
| "type": "RemoteMCPServer", | ||
| "auth": { | ||
| "type": "OAuthPluginVault", | ||
| "reference_id": "${{OAUTH_REFERENCE_ID}}" | ||
| }, | ||
| "spec": { | ||
| "url": "https://agent365.svc.cloud.microsoft/agents/servers/mcp_CalendarTools" | ||
| }, | ||
| "run_for_functions": [ | ||
| "createEvent" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createEventdefineslocationandbodyparameters (and the agent instructions require both), but they are not listed in therequiredarray. This makes it easy for calls to pass validation without including the address/details, resulting in incomplete calendar entries. Consider addinglocationandbodytorequiredso the contract matches the intended workflow.