Proactive class

Provides methods for storing, retrieving, and managing conversation references to enable proactive messaging scenarios. Supports sending activities and continuing conversations outside the standard request/response flow using stored conversation references.

Remarks

Use the Proactive class to implement scenarios where an agent needs to initiate conversations or send messages to users without an incoming activity, such as notifications or scheduled alerts. Some operations require that conversation references be stored using storeConversation before they can be used.

Access via app.proactive after configuring proactive in AgentApplicationOptions.

Properties

ContinueConversationValueType

activity.valueType that indicates additional key/values for the ContinueConversation event.

Methods

continueConversation(BaseAdapter, Conversation, RouteHandler<TState>, string[], Partial<Activity>)

Continues an existing conversation by executing the given handler within the context of the provided Conversation reference. The handler receives a TurnContext and a freshly loaded TurnState scoped to the original conversation, enabling the agent to respond as if replying to an incoming activity.

Example

// Continue a conversation with a custom value payload
const conv = await app.proactive.getConversationOrThrow(convId)
await app.proactive.continueConversation(
  adapter,
  conv,
  async (ctx, state) => {
    const payload = ctx.activity.value as { alertType: string }
    await ctx.sendActivity(`Alert triggered: ${payload.alertType}`)
  },
  undefined,
  { value: { alertType: 'threshold-exceeded' }, valueType: Proactive.ContinueConversationValueType }
)
continueConversation(BaseAdapter, string, RouteHandler<TState>, string[], Partial<Activity>)

Continues a stored conversation by executing the given handler within the context of that conversation, looking it up by ID.

See the Conversation overload for full details.

Example

// Scheduled job: send a daily digest to all stored conversations
for (const convId of storedIds) {
  await app.proactive.continueConversation(adapter, convId, async (ctx, state) => {
    await ctx.sendActivity('Here is your daily digest...')
  })
}
createConversation(BaseAdapter, CreateConversationOptions, RouteHandler<TState>)

Creates a new conversation using the specified channel adapter and conversation options.

Example

// Initiate a new 1:1 conversation with a Teams user and send a welcome message
const opts = CreateConversationOptionsBuilder
  .create(process.env.APP_ID!, 'msteams')
  .withUser('user-aad-object-id')
  .withTenantId('tenant-id')
  .storeConversation(true)
  .build()

const conv = await app.proactive.createConversation(adapter, opts, async (ctx, state) => {
  await ctx.sendActivity('Hi! I have an update for you.')
})
console.log('New conversation ID:', conv.reference.conversation.id)
deleteConversation(string)

Deletes the stored conversation reference for the given conversation ID.

Example

// Clean up after a conversation has ended
app.onActivity('endOfConversation', async (ctx, state) => {
  await app.proactive.deleteConversation(ctx.activity.conversation.id)
})
getConversation(string)

Retrieves the stored Conversation associated with the given conversation ID.

Example

const conv = await app.proactive.getConversation(convId)
if (conv) {
  await app.proactive.sendActivity(adapter, conv, { text: 'Hello!' })
}
getConversationOrThrow(string)

Retrieves the stored Conversation for the given ID, throwing if no record is found.

Example

// Use when absence of the conversation should be treated as an error
const conv = await app.proactive.getConversationOrThrow(convId)
await app.proactive.sendActivity(adapter, conv, { text: 'Alert: your report is ready.' })
sendActivity(BaseAdapter, Conversation, Partial<Activity>)

Sends an activity to an existing conversation using the provided Conversation reference.

Example

// Build a Conversation from a stored reference and send a message
const conv = await app.proactive.getConversationOrThrow(convId)
const response = await app.proactive.sendActivity(adapter, conv, { text: 'Hello from the agent!' })
console.log('Sent activity ID:', response.id)
sendActivity(BaseAdapter, string, Partial<Activity>)

Sends an activity to a stored conversation, looking it up by ID.

Example

// Send a notification using a previously stored conversation ID
await app.proactive.sendActivity(adapter, storedConvId, { text: 'Your order has shipped!' })
storeConversation(Conversation)

Stores an explicit Conversation object in proactive storage.

Example

// Build a Conversation manually and store it
const conv = ConversationBuilder
  .create('my-app-id', 'msteams')
  .withUser('user-aad-id')
  .withConversationId('19:existing-thread-id@thread.tacv2')
  .build()
const convId = await app.proactive.storeConversation(conv)
storeConversation(TurnContext)

Stores the current conversation reference from a live TurnContext in proactive storage.

Example

// Inside an onMessage handler — save the conversation so we can message later
app.onActivity('message', async (ctx, state) => {
  const convId = await app.proactive.storeConversation(ctx)
  await ctx.sendActivity(`Conversation stored. ID: ${convId}`)
})

Constructor Details

Proactive<TState>(AgentApplication<TState>, ProactiveOptions)

new Proactive(app: AgentApplication<TState>, options: ProactiveOptions)

Parameters

app

AgentApplication<TState>

Property Details

ContinueConversationValueType

activity.valueType that indicates additional key/values for the ContinueConversation event.

static ContinueConversationValueType: "application/vnd.microsoft.activity.continueconversation+json" = "application/vnd.microsoft.activity.continueconversation+json"

Property Value

string

Method Details

continueConversation(BaseAdapter, Conversation, RouteHandler<TState>, string[], Partial<Activity>)

Continues an existing conversation by executing the given handler within the context of the provided Conversation reference. The handler receives a TurnContext and a freshly loaded TurnState scoped to the original conversation, enabling the agent to respond as if replying to an incoming activity.

Example

// Continue a conversation with a custom value payload
const conv = await app.proactive.getConversationOrThrow(convId)
await app.proactive.continueConversation(
  adapter,
  conv,
  async (ctx, state) => {
    const payload = ctx.activity.value as { alertType: string }
    await ctx.sendActivity(`Alert triggered: ${payload.alertType}`)
  },
  undefined,
  { value: { alertType: 'threshold-exceeded' }, valueType: Proactive.ContinueConversationValueType }
)
function continueConversation(adapter: BaseAdapter, conversation: Conversation, handler: RouteHandler<TState>, autoSignInHandlers?: string[], continuationActivity?: Partial<Activity>): Promise<void>

Parameters

adapter
BaseAdapter

The channel adapter used to continue the conversation.

conversation
Conversation

A Conversation instance created via its constructor or ConversationBuilder.

handler

RouteHandler<TState>

The route handler to execute within the continued conversation context.

autoSignInHandlers

string[]

Optional list of OAuth connection names whose tokens should be acquired before invoking the handler.

continuationActivity

Partial<Activity>

Optional activity fields merged into the continuation activity, making them available on ctx.activity inside the handler (e.g. value, valueType).

Returns

Promise<void>

Remarks

Exceptions thrown inside the handler are captured and re-thrown after the adapter callback completes, since the adapter would otherwise silently swallow them.

If autoSignInHandlers are supplied and the application has user authorization configured, tokens are acquired before the handler is called. If not all tokens are available and proactiveOptions.failOnUnsignedInConnections is not false, an error is thrown.

continueConversation(BaseAdapter, string, RouteHandler<TState>, string[], Partial<Activity>)

Continues a stored conversation by executing the given handler within the context of that conversation, looking it up by ID.

See the Conversation overload for full details.

Example

// Scheduled job: send a daily digest to all stored conversations
for (const convId of storedIds) {
  await app.proactive.continueConversation(adapter, convId, async (ctx, state) => {
    await ctx.sendActivity('Here is your daily digest...')
  })
}
function continueConversation(adapter: BaseAdapter, conversationId: string, handler: RouteHandler<TState>, autoSignInHandlers?: string[], continuationActivity?: Partial<Activity>): Promise<void>

Parameters

adapter
BaseAdapter

The channel adapter used to continue the conversation.

conversationId

string

The ID of a conversation previously stored via storeConversation.

handler

RouteHandler<TState>

The route handler to execute within the continued conversation context.

autoSignInHandlers

string[]

Optional list of OAuth connection names whose tokens should be acquired before invoking the handler.

continuationActivity

Partial<Activity>

Optional activity fields merged into the continuation activity, making them available on ctx.activity inside the handler (e.g. value, valueType).

Returns

Promise<void>

createConversation(BaseAdapter, CreateConversationOptions, RouteHandler<TState>)

Creates a new conversation using the specified channel adapter and conversation options.

Example

// Initiate a new 1:1 conversation with a Teams user and send a welcome message
const opts = CreateConversationOptionsBuilder
  .create(process.env.APP_ID!, 'msteams')
  .withUser('user-aad-object-id')
  .withTenantId('tenant-id')
  .storeConversation(true)
  .build()

const conv = await app.proactive.createConversation(adapter, opts, async (ctx, state) => {
  await ctx.sendActivity('Hi! I have an update for you.')
})
console.log('New conversation ID:', conv.reference.conversation.id)
function createConversation(adapter: BaseAdapter, createOptions: CreateConversationOptions, handler?: RouteHandler<TState>): Promise<Conversation>

Parameters

adapter
BaseAdapter

The channel adapter used to create the conversation. Must implement createConversationAsync() (i.e. a CloudAdapter instance).

createOptions
CreateConversationOptions

Details required to create the conversation, including identity, channel, service URL, OAuth scope, and ConversationParameters. Build with CreateConversationOptionsBuilder.

handler

RouteHandler<TState>

Optional route handler executed immediately after the conversation is created.

Returns

Promise<Conversation>

The newly created Conversation.

Remarks

This wraps CloudAdapter.createConversationAsync(), which requires real network connectivity and authentication. The provided adapter must implement createConversationAsync(); a TypeError is thrown if it does not.

If createOptions.storeConversation is true, the resulting Conversation is automatically stored via storeConversation so it can be retrieved by ID later.

If a handler is provided it is executed within the newly created conversation, giving the agent a chance to send an initial message or load state.

deleteConversation(string)

Deletes the stored conversation reference for the given conversation ID.

Example

// Clean up after a conversation has ended
app.onActivity('endOfConversation', async (ctx, state) => {
  await app.proactive.deleteConversation(ctx.activity.conversation.id)
})
function deleteConversation(conversationId: string): Promise<void>

Parameters

conversationId

string

The unique identifier of the conversation whose reference should be deleted.

Returns

Promise<void>

Remarks

If no record exists for the given ID, no action is taken.

getConversation(string)

Retrieves the stored Conversation associated with the given conversation ID.

Example

const conv = await app.proactive.getConversation(convId)
if (conv) {
  await app.proactive.sendActivity(adapter, conv, { text: 'Hello!' })
}
function getConversation(conversationId: string): Promise<undefined | Conversation>

Parameters

conversationId

string

The unique identifier of the conversation to retrieve.

Returns

Promise<undefined | Conversation>

The stored Conversation, or undefined if no record exists for that ID.

getConversationOrThrow(string)

Retrieves the stored Conversation for the given ID, throwing if no record is found.

Example

// Use when absence of the conversation should be treated as an error
const conv = await app.proactive.getConversationOrThrow(convId)
await app.proactive.sendActivity(adapter, conv, { text: 'Alert: your report is ready.' })
function getConversationOrThrow(conversationId: string): Promise<Conversation>

Parameters

conversationId

string

The unique identifier of the conversation to retrieve.

Returns

Promise<Conversation>

The stored Conversation.

sendActivity(BaseAdapter, Conversation, Partial<Activity>)

Sends an activity to an existing conversation using the provided Conversation reference.

Example

// Build a Conversation from a stored reference and send a message
const conv = await app.proactive.getConversationOrThrow(convId)
const response = await app.proactive.sendActivity(adapter, conv, { text: 'Hello from the agent!' })
console.log('Sent activity ID:', response.id)
function sendActivity(adapter: BaseAdapter, conversation: Conversation, activity: Partial<Activity>): Promise<ResourceResponse>

Parameters

adapter
BaseAdapter

The channel adapter used to send the activity.

conversation
Conversation

A Conversation instance created via its constructor or ConversationBuilder.

activity

Partial<Activity>

The activity to send. If type is not set it defaults to 'message'.

Returns

Promise<ResourceResponse>

A ResourceResponse with the ID of the sent activity.

sendActivity(BaseAdapter, string, Partial<Activity>)

Sends an activity to a stored conversation, looking it up by ID.

Example

// Send a notification using a previously stored conversation ID
await app.proactive.sendActivity(adapter, storedConvId, { text: 'Your order has shipped!' })
function sendActivity(adapter: BaseAdapter, conversationId: string, activity: Partial<Activity>): Promise<ResourceResponse>

Parameters

adapter
BaseAdapter

The channel adapter used to send the activity.

conversationId

string

The ID of a conversation previously stored via storeConversation.

activity

Partial<Activity>

The activity to send. If type is not set it defaults to 'message'.

Returns

Promise<ResourceResponse>

A ResourceResponse with the ID of the sent activity.

storeConversation(Conversation)

Stores an explicit Conversation object in proactive storage.

Example

// Build a Conversation manually and store it
const conv = ConversationBuilder
  .create('my-app-id', 'msteams')
  .withUser('user-aad-id')
  .withConversationId('19:existing-thread-id@thread.tacv2')
  .build()
const convId = await app.proactive.storeConversation(conv)
function storeConversation(conversation: Conversation): Promise<string>

Parameters

conversation
Conversation

The conversation reference record to store.

Returns

Promise<string>

The conversation ID that can be used to retrieve the reference in future operations.

storeConversation(TurnContext)

Stores the current conversation reference from a live TurnContext in proactive storage.

Example

// Inside an onMessage handler — save the conversation so we can message later
app.onActivity('message', async (ctx, state) => {
  const convId = await app.proactive.storeConversation(ctx)
  await ctx.sendActivity(`Conversation stored. ID: ${convId}`)
})
function storeConversation(context: TurnContext): Promise<string>

Parameters

context
TurnContext

The context object for the current turn, containing activity and conversation information.

Returns

Promise<string>

The conversation ID that can be used to retrieve the reference in future operations.