Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions samples/TeamsSDK/bot-targeted-messages/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
launchSettings.json
appsettings.*.json
package-lock.json
.env
uv.lock
.venv/
172 changes: 172 additions & 0 deletions samples/TeamsSDK/bot-targeted-messages/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Bot Targeted Messages

This sample demonstrates how to use **targeted messaging** in Microsoft Teams. Targeted messages are private messages that appear in a shared channel or group chat but are **only visible to a specific user**. The sample implements a reminder bot where all bot responses — confirmations, reminder deliveries, active reminder lists, and snooze confirmations — are sent as targeted messages.

## Table of Contents

- [Included Features](#included-features)
- [Interaction with Bot](#interaction-with-bot)
- [Sample Implementations](#sample-implementations)
- [How to run these samples](#how-to-run-these-samples)
- [Run in the Teams Client](#run-in-the-teams-client)
- [Configure the new project to use the new Teams Bot Application](#configure-the-new-project-to-use-the-new-teams-bot-application)
- [Pro Tip: Read the configuration settings using the Azure CLI](#pro-tip-read-the-configuration-settings-using-the-azure-cli)
- [Troubleshooting](#troubleshooting)
- [Further Reading](#further-reading)

## Included Features

- Bots
- Targeted Messaging (`MessageActivity.withRecipient()`)
- Proactive Targeted Messaging (`app.send()`)
- Adaptive Cards with `Action.Execute`
- Mention Stripping (`stripMentionsText()`)

## Interaction with Bot

![Targeted Messages Bot](bot-targeted-messages.gif)

### Set a Reminder

- `remind me in 5 minutes to check email`
- `remind me in 1 hour meeting starts`
- `remind me in 30 seconds test`
- `remind @John in 10 minutes review PR`

### Supported Time Formats

- Seconds: `30 seconds`, `30 secs`, `30s`
- Minutes: `5 minutes`, `5 mins`, `5m`
- Hours: `1 hour`, `2 hrs`, `1h`

### Manage Reminders

- `my-reminders` — View your active reminders (targeted, only you see the list)
- `cancel-reminder [id]` — Cancel a specific reminder
- `reminder-help` — Show help information

### Where Targeted Messages Are Used

Every bot response in this sample is a targeted message — only the intended recipient can see it:

| Action | Recipient | How |
|---|---|---|
| Setting a reminder | The command sender | `send(new MessageActivity(...).withRecipient(creator, true))` |
| Reminder delivery | The reminder target | `app.send(conversationId, new MessageActivity(...).withRecipient(recipient, true))` |
| Viewing active reminders | The command sender | `send(new MessageActivity(...).withRecipient(sender, true))` |
| Snooze confirmation | The snoozing user | `send(new MessageActivity(...).withRecipient(recipient, true))` |

## Sample Implementations

| Language | Framework | Directory |
|----------|-----------|-----------|
| TypeScript | Node.js | [nodejs/bot-targeted-messages](nodejs/bot-targeted-messages/README.md) |

# How to run these samples

You can run these samples locally using:

1. In the Teams Client after you have provisioned the Teams Application and configured the application with your local DevTunnels URL.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 67-69 are difficult to understand. I see "You can run these samples locally using:" and expect a list but there is the sentence "In the teams client..."


## Run in the Teams Client

To run these samples in the Teams Client, you need to provision your app in a M365 Tenant, and configure the app to your DevTunnels URL.

1. Install the tool DevTunnels https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started
2. Get Access to a M365 Developer Tenant https://learn.microsoft.com/en-us/office/developer-program/microsoft-365-developer-program-get-started
3. Create a Teams App with the Bot Feature in the Teams Developer Portal (in your tenant) https://dev.teams.microsoft.com

### Configure DevTunnels

Create a persistent tunnel for the port 3978 with anonymous access

```
devtunnel create -a my-tunnel
devtunnel port create -p 3978 my-tunnel
devtunnel host my-tunnel
```

Take note of the URL shown after *Connect via browser:*

### Provisioning the Teams Application

Navigate to the Teams Developer Portal http://dev.teams.microsoft.com

#### Create a new Bot resource

1. Navigate to `Tools->Bot management`, and add a `New bot`
1. In Configure, paste the Endpoint address from devtunnels and append `/api/messages`
1. In Client secrets, create a new secret and save it for later

> Note. If you have access to an Azure Subscription in the same Tenant, you can also create the Azure Bot resource ([learn more](https://learn.microsoft.com/en-us/azure/bot-service/abs-quickstart?view=azure-bot-service-4.0&tabs=singletenant)).

#### Create a new Teams App

1. Navigate to `Apps` and create a `New App`
1. Fill the required values in Basic information (short and long name, short and long description and App URLs)
1. In `App features->Bot` select the bot you created previously
1. Select `Preview in Teams`

> Note. When using an Azure Bot resource, provide the ClientID instead of selecting an existing bot.

## Configure the new project to use the new Teams Bot Application

For NodeJS and Python you will need a `.env` file with the next fields

```
TENANT_ID=
CLIENT_ID=
CLIENT_SECRET=
```

For dotnet you need to add these values to `appsettings.json` or `launchSettings.json` using the next syntax.

appsettings.json


```json
"urls" : "http://localhost:3978",
"Teams": {
"ClientID": "",
"ClientSecret": "",
"TenantId": ""
},
```

Or to use Env Vars from the profile defined in `launchSettings.json` (using the Environment Configuration Provider)

```json
"teamsbot": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:3978",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"Teams__TenantId": "YOUR_TenantId",
"Teams__ClientID": "YOUR_ClientId",
"Teams__ClientSecret": "YOUR_ClientSecret"
}
}
```

## Pro Tip: Read the configuration settings using the Azure CLI

To obtain the TenantId, ClientId and ClientSecret you can use the Azure CLI with:

> Note. If you don't have access to an Azure Subscription you can still use the Azure CLI, make sure you login with `az login --allow-no-subscription`

```
az ad app credential reset --id $appId
```

## Troubleshooting

- If Teams cannot communicate with your bot, verify your DevTunnels URL is reachable.
- Ensure your .env or appsettings file is setup correctly.
- Use the Channels UI in Azure Bot Service in the Azure Portal to see detailed endpoint errors (not available in Teams Developer Portal).


## Further Reading

- [Microsoft Teams SDK Documentation](https://learn.microsoft.com/microsoftteams/platform/)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
TENANT_ID=
CLIENT_ID=
CLIENT_SECRET=
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Targeted Messages in Microsoft Teams - TypeScript

This sample demonstrates how to use **targeted messaging** in Microsoft Teams. Targeted messages are private messages that appear in a shared channel or group chat but are **only visible to a specific user**. The sample implements a reminder bot where all bot responses — confirmations, reminder deliveries, active reminder lists, and snooze confirmations — are sent as targeted messages.

## Included Features

- Bots
- Targeted Messaging (`MessageActivity.withRecipient()`)
- Proactive Targeted Messaging (`app.send()`)
- Adaptive Cards with `Action.Execute`
- Mention Stripping (`stripMentionsText()`)

## Prerequisites

- [Node.js](https://nodejs.org/) (LTS version recommended)

## Run the sample

1. Navigate to this directory:
```
cd targeted-messages/bot-targeted-messages/nodejs
```

2. Install dependencies:
```
npm install
```

3. Run the bot:
```
npm start
```

The bot will start listening on `http://localhost:3978`.

Refer to the main [README.md](../../README.md) to interact with your bot in the agentsplayground or in Teams.
Comment thread
AjayJ12-MSFT marked this conversation as resolved.

## Running the sample

Once installed, you can use the following commands in any **channel** or **group chat**:

### Set a Reminder

- `remind me in 5 minutes to check email`
- `remind me in 1 hour meeting starts`
- `remind me in 30 seconds test`
- `remind @John in 10 minutes review PR`

### Supported Time Formats

- Seconds: `30 seconds`, `30 secs`, `30s`
- Minutes: `5 minutes`, `5 mins`, `5m`
- Hours: `1 hour`, `2 hrs`, `1h`

### Manage Reminders

- `my-reminders` — View your active reminders (targeted, only you see the list)
- `cancel-reminder [id]` — Cancel a specific reminder
- `reminder-help` — Show help information

### Where Targeted Messages Are Used

Every bot response in this sample is a targeted message — only the intended recipient can see it:

| Action | Recipient | How |
|---|---|---|
| Setting a reminder | The command sender | `send(new MessageActivity(...).withRecipient(creator, true))` |
| Reminder delivery | The reminder target | `app.send(conversationId, new MessageActivity(...).withRecipient(recipient, true))` |
| Viewing active reminders | The command sender | `send(new MessageActivity(...).withRecipient(sender, true))` |
| Snooze confirmation | The snoozing user | `send(new MessageActivity(...).withRecipient(recipient, true))` |
Comment thread
AjayJ12-MSFT marked this conversation as resolved.

### How Targeted Messaging Works

The bot uses the Teams SDK (`@microsoft/teams.apps` / `@microsoft/teams.api`) to send targeted messages:

- **`MessageActivity.withRecipient(account, true)`** — marks the message as targeted for a specific user. The second parameter (`true`) sets `isTargeted`.
- **`app.send(conversationId, activity)`** — sends a proactive targeted message (e.g., delivering a reminder after a delay).
- **`stripMentionsText(activity, { accountId })`** — strips bot or user @mentions from incoming message text.
- **Adaptive Cards** with `Action.Execute` — provide interactive buttons (Cancel, Dismiss, Snooze) on targeted cards.

The message appears in the shared conversation thread but is **only visible to the specified recipient**.

## Further reading

- [Targeted Messages in Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages)
- [Send and receive messages with a bot](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/conversation-messages)
- [Adaptive Cards](https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference#adaptive-card)
- [Microsoft Teams SDK for Node.js](https://www.npmjs.com/package/@microsoft/teams.apps)
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
[
{
"name": "officedev-microsoft-teams-samples-targeted-messages-nodejs",
"source": "officeDev",
"title": "Targeted Messages",
"shortDescription": "This sample bot demonstrates how to use targeted messaging in Microsoft Teams to send private reminders, confirmations, and lists visible only to the intended recipient.",
"url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/TeamsSDK/bot-targeted-messages/nodejs/bot-targeted-messages",
"longDescription": [
"This sample demonstrates targeted messaging in Microsoft Teams using TypeScript. Targeted messages are private messages visible only to a specific user within a channel or group chat. The bot implements a reminder system where every response — reminder confirmations, deliveries, active reminder lists, and snooze confirmations — is sent as a targeted message using MessageActivity.withRecipient(). It also demonstrates proactive targeted messaging via app.send() and interactive Adaptive Cards with Action.Execute for dismiss, snooze, and cancel actions."
],
"creationDateTime": "2026-04-23",
"updateDateTime": "2026-04-23",
"products": [
"Teams"
],
"metadata": [
{
"key": "TEAMS-SAMPLE-SOURCE",
"value": "OfficeDev"
},
{
"key": "TEAMS-SERVER-LANGUAGE",
"value": "typescript"
},
{
"key": "TEAMS-SERVER-PLATFORM",
"value": "express"
},
{
"key": "TEAMS-FEATURES",
"value": "bot,targeted-messaging,proactive-messaging,adaptive-cards"
}
],
"thumbnails": [
{
"type": "Image",
"order": 100,
"url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/TeamsSDK/bot-targeted-messages/nodejs/bot-targeted-messages/assets/targeted-reminder-bot.gif",
"alt": "Targeted Reminder Bot showing reminder delivery with snooze and dismiss options"
}
],
"authors": [
{
"gitHubAccount": "OfficeDev",
"pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4",
"name": "OfficeDev"
}
],
"references": [
{
"name": "Teams developer documentation",
"url": "https://aka.ms/TeamsPlatformDocs"
},
{
"name": "Teams developer questions",
"url": "https://aka.ms/TeamsPlatformFeedback"
},
{
"name": "Teams development videos from Microsoft",
"url": "https://aka.ms/sample-ref-teams-vids-from-microsoft"
},
{
"name": "Teams development videos from the community",
"url": "https://aka.ms/community/videos/m365powerplatform"
}
]
}
]
Loading