All skills
microsoft avatar

/teams-app-developer

@0bef15b
by microsoftmicrosoft/skills3.1k stars
351

Builds, tests, and deploys Microsoft 365 apps and agents for Teams and Copilot. Includes sub-skills for project creation, local testing, cloud deployment, troubleshooting, and Slack-to-Teams migration. USE FOR: Teams agent, bot, tab, message extension, Declarative Agents, Custom Engine Agents, local testing, Agents Playground, Azure resource provision, remote deployment, Slack to Teams migration, cross-platform bot development, Block Kit to Adaptive Cards conversion. DO NOT USE FOR: general web development, non-bot/non-Teams projects.

Use this Skill: https://skilld.dev/gh/microsoft/skills/teams-app-developer

This session only. Nothing lands on disk.

docsmessaging-and-commands.md

≈1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Messaging & Commands

Message Handling

Aspect Slack Teams
Handler app.message(pattern, handler) app.on("message", handler)
Pattern matching String (substring), RegExp, or catch-all RegExp or manual text.match()
Reply to channel say(text) ctx.send(text)
Reply in thread say({ text, thread_ts }) ctx.reply(text)
Get message text message.text ctx.activity.text
Get sender message.user (Slack ID) ctx.activity.from.id (AAD ID)

Rating: GREEN — direct mapping in both directions.

Mitigation: Extract message handling into a platform-agnostic service layer that receives (text, userId, platform) and returns structured data. Each adapter converts to the platform's native format.


Slash Commands

Aspect Slack Teams
Invocation /command args No native equivalent
Handler app.command("/cmd", handler) app.on("message") with text pattern matching
Acknowledgement Must ack() within 3 seconds Automatic — no ack()
Default response Ephemeral (user-only) Visible to everyone
Modal trigger trigger_id from command → views.open() dialog.open handler or Adaptive Card form
Registration Slack app dashboard + commands scope Manifest commands[] array (bot commands, not slash)

Rating: YELLOW — functional equivalent exists but UX is fundamentally different.

Impact

  • Slash commands are a core Slack interaction pattern with no Teams counterpart
  • Teams bot commands appear in a command menu but don't use / prefix
  • Ephemeral responses don't exist in Teams

Mitigation Strategies

Strategy How Effort
Text commands (Recommended) Detect command-like patterns in app.on("message"). Accept both weather and /weather. 2–4 hrs
Manifest bot commands Add commands[] to manifest for discoverability in Teams command menu. Users type the command name. 1–2 hrs
Message extension Use composeExtensions for a richer command experience with search results or task modules. 8–12 hrs

Reverse Direction (Teams → Slack)

Teams bot commands map directly to Slack slash commands via app.command(). Add ack() calls (required in Slack, absent in Teams) and configure the command in the Slack app dashboard.


Events / Activities

Slack Event Teams Activity Notes
message message Direct mapping
app_mention message (in channel) Teams channels require @mention by default
member_joined_channel conversationUpdate (membersAdded) Different event shape
member_left_channel conversationUpdate (membersRemoved) Different event shape
reaction_added messageReaction Teams has only 6 fixed reactions
app_home_opened install.add (closest) No "opened" event in Teams
channel_created No equivalent Use Graph API subscription
team_join conversationUpdate (membersAdded) Same event, different context

Rating: GREEN for most events, RED for custom emoji reactions.

@Mention Behavior

Aspect Slack Teams
Channel messages Bot receives all messages in joined channels Bot only receives messages with @mention (default)
Override Default behavior Add ChannelMessage.Read.Group RSC permission to manifest
Mention stripping Not needed Set activity.mentions.stripText: true in App options

Mitigation: To receive all channel messages in Teams without @mention, add RSC permission to the manifest. This is a config-only change (1–2 hrs).


Threading

Aspect Slack Teams
Reply in thread say({ thread_ts: message.ts }) ctx.reply(text)
Thread broadcast say({ thread_ts, reply_broadcast: true }) Two API calls: reply() + send()
Get thread replies conversations.replies({ ts }) Graph API GET /messages/{id}/replies
Thread discovery Native API Requires ChannelMessage.Read.All Graph permission

Rating: GREEN for basic threading, YELLOW for broadcast and discovery.

Mitigation for Thread Broadcast

Slack's reply_broadcast posts in both the thread and the channel in one call. Teams requires two separate calls: reply() for the thread and send() for the channel. Wrap in a helper:

async function replyWithBroadcast(ctx, text: string): Promise<void> {
  await ctx.reply(text);  // Thread reply
  await ctx.send(text);   // Channel message
}

Effort: 1–2 hrs.

Source: SKILL.md on GitHub

1 alert3mo3 checks · Risk SAFE
  • Gen Agent Trust Hub3mo

    This skill provides a comprehensive developer guide for building Microsoft 365 agents and Teams applications. It includes several security considerations such as handling untrusted user input, using dynamic execution in examples, and reading sensitive local files for protocol requirements. These patterns are presented with appropriate security warnings and architectural mitigations. See detailed analysis for more context.

  • Socket3mo

    No alerts

  • Snyk3mo

    Risk: HIGH · 1 issue

Signed by skilld at 0bef15b. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 20 hours ago.

Activeupdated 3 months ago

README badge

README badge for microsoft/skills/teams-app-developer