Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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

The bot works in **channels** and **group chats** and supports the following commands:

### 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/)
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