Functions
- SDK 2.0 (Legacy)
- SDK 2.1 (current)
Agents may want to expose REST APIs that client applications can call. SDK 2.0 provides the app.AddFunction() helper for this.
Agents may want to expose REST APIs that client applications can call. In SDK 2.1, implement these with standard ASP.NET endpoints (for example app.MapPost(...)) and protect them with authorization.
- SDK 2.0 (Legacy)
- SDK 2.1 (current)
app.AddFunction("do-something", context =>
{
// do something useful
});
This registers http://localhost:{PORT}/api/functions/do-something or https://{BOT_DOMAIN}/api/functions/do-something.
When called, SDK 2.0 validates the bearer token before invoking your callback. Missing or invalid tokens are rejected with HTTP 401.
Typed payload example:
public class ProcessMessageData
{
[JsonPropertyName("message")]
public required string Message { get; set; }
}
app.AddFunction<ProcessMessageData>("process-message", context =>
{
context.Log.Debug($"process-message with: {context.Data.Message}");
});
using Microsoft.Teams.Core.Hosting;
public class ProcessMessageData
{
public required string Message { get; set; }
}
var builder = WebApplication.CreateSlimBuilder(args);
builder.Services.AddBotAuthorization();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapPost("/api/functions/process-message", (ProcessMessageData data, ILogger<Program> logger) =>
{
logger.LogInformation("process-message with: {Message}", data.Message);
return Results.Ok(new { success = true });
})
.RequireAuthorization();
In SDK 2.1, token validation is handled by ASP.NET auth middleware plus .RequireAuthorization().
This SDK does not validate that function arguments are of the expected types or otherwise trustworthy. Always validate request payloads before using them.
- SDK 2.0 (Legacy)
- SDK 2.1 (current)
If desired, the function can return data to the caller.
app.AddFunction("get-random-number", () =>
{
return 4; // chosen by fair dice roll;
// guaranteed to be random
});
In SDK 2.1, return standard ASP.NET minimal API results:
app.MapPost("/api/functions/get-random-number", () =>
{
return Results.Ok(new { value = 4 });
})
.RequireAuthorization();
Function context
- SDK 2.0 (Legacy)
- SDK 2.1 (current)
The function callback receives a FunctionContext object with useful values from the app and caller.
SDK 2.1 function endpoints use standard ASP.NET handler parameters instead of a Teams FunctionContext.
- SDK 2.0 (Legacy)
- SDK 2.1 (current)
| Property | Source | Description |
|---|---|---|
Api | Agent | The API client. |
AppId | Agent | Unique identifier assigned to the app after deployment, ensuring correct app instance recognition across hosts. |
AppSessionId | Caller | Unique ID for the calling app's session, used to correlate telemetry data. |
AuthToken | Caller | The validated MSAL Entra token. |
ChannelId | Caller | Microsoft Teams ID for the channel associated with the content. |
ChatId | Caller | Microsoft Teams ID for the chat associated with the content. |
Data | Caller | The function payload. |
Log | Agent | The app logger instance. |
MeetingId | Caller | Meeting ID used by tab when running in meeting context. |
MessageId | Caller | ID of the parent message from which the task module was launched (only available in bot card-launched modules). |
PageId | Caller | Developer-defined unique ID for the page this content points to. |
Send | Agent | Sends an activity to the current conversation. |
SubPageId | Caller | Developer-defined unique ID for the sub-page this content points to. Used to restore specific state within a page. |
TeamId | Caller | Microsoft Teams ID for the team associated with the content. |
TenantId | Caller | Microsoft Entra tenant ID of the current user, extracted from the validated auth token. |
UserId | Caller | Microsoft Entra object ID of the current user, extracted from the validated auth token. |
UserName | Caller | Microsoft Entra name of the current user, extracted from the validated auth token. |
| Parameter / Source | Description |
|---|---|
ProcessMessageData data | Request body payload from caller |
ClaimsPrincipal user | Authenticated user claims |
HttpContext | Request context (headers, route data, services) |
ILogger<T> | Logging from DI |
| Other DI services | Any registered service needed by your endpoint |
- SDK 2.0 (Legacy)
- SDK 2.1 (current)
AuthToken is validated before the callback runs, and TenantId, UserId, and UserName are extracted from the validated token. Remaining caller values are not validated by the SDK.
Take care to validate caller-supplied values before using them. Don't assume the user has access to IDs passed in context.
In SDK 2.1, use .RequireAuthorization() so only authenticated callers reach the endpoint. You should still validate caller payload, route values, and business-level authorization.
Authentication is not authorization for specific business resources. Always enforce resource-level checks in your handler.
- SDK 2.0 (Legacy)
- SDK 2.1 (current)
To simplify common scenarios, SDK 2.0 FunctionContext provides Send.
Send posts to the current conversation ID determined from caller context (chatId/channelId). If neither is provided, it assumes the 1:1 chat between the bot and user.
Send does not validate that caller-provided chat or channel IDs are correct. Validate caller-provided conversation identifiers before use.
In SDK 2.1, implement helper behavior explicitly in your endpoint (for example, resolve target conversation, verify access, then send via ConversationClient).
Additional resources
- For the SDK 2.1 route-based example, see
core/samples/TabApp/Program.csin the Teams .NET repository. - For details on how tab apps invoke these functions, see the TypeScript Executing Functions in-depth guide.