사용자에게 자동 관리 알림 보내기Send proactive notifications to users

적용 대상: SDK v4APPLIES TO: SDK v4

일반적으로 봇은 사용자로부터 메시지를 받는 것에 대한 응답으로 사용자에게 직접 메시지를 보냅니다.Typically, a bot sends a message to a user directly in response to receiving a message from the user. 경우에 따라 봇은 사용자로부터 시작되지 않은 봇에 대한 응답으로 자동 관리 메시지인 을 보내야 할 수 있습니다.Occasionally, a bot might need to send a proactive message, a message in response to stimulus not originating from the user.

자동 관리 메시지는 다양한 시나리오에서 유용할 수 있습니다.Proactive messages can be useful in a variety of scenarios. 예를 들어, 사용자가 이전에 제품 가격을 모니터링할 것을 봇에게 요청한 경우 봇은 제품 가격이 20%까지 떨어질 경우 사용자에게 경고할 수 있습니다.For example, if the user has previously asked the bot to monitor the price of a product, the bot can alert the user if the price of the product has dropped by 20%. 또는 봇이 사용자 질문에 대한 응답을 컴파일할 시간이 필요한 경우 지연 사실을 알리고, 당분간 대화를 계속 진행할 수 있습니다.Or, if a bot requires some time to compile a response to the user's question, it may inform the user of the delay and allow the conversation to continue in the meantime. 봇이 질문에 대한 응답 컴파일을 완료하면 해당 정보를 사용자와 공유합니다.When the bot finishes compiling the response to the question, it will share that information with the user.

참고

이 문서에서는 일반적으로 봇에 대한 사전 대응 메시지에 대한 정보를 다룹니다.This article covers information about proactive messages for bots in general. Microsoft Teams의 자동 관리 메시지에 대한 자세한 내용은 다음을 참조하세요.For information about proactive messages in Microsoft Teams, see:

요구 사항Requirements

자동 관리 메시지를 보내려면 봇에 대화 참조 가 필요합니다.Before you can send a proactive message, your bot needs a conversation reference. 봇은 사용자로부터 받은 모든 활동에서 대화 참조를 검색할 수 있지만, 일반적으로 봇이 사전 대응 메시지를 보내기 전에 사용자가 적어도 한 번 이상 봇과 상호 작용해야 합니다.Your bot can retrieve the conversation reference from any activity it has received from the user, but this typically requires the user to interact with the bot at least once before the bot can send a proactive message.

많은 채널은 사용자가 봇에 한 번 이상 메시지를 보내지 않는 한 봇이 사용자에게 메시지를 보내지 못하도록 금지합니다.Many channels prohibit a bot from messaging a user unless the user has messaged the bot at least once. 일부 채널은 예외를 허용합니다.Some channels allow exceptions. 예를 들어 Teams 채널을 사용하면 봇이 봇을 포함하는 이미 설정된 그룹 대화의 개인에게 사전 대응(또는 1-on-1) 메시지를 보낼 수 있습니다.For instance, the Teams channel allows your bot to send a proactive (or 1-on-1) message to individuals in an already established group conversation that includes the bot.

필수 구성 요소Prerequisites

자동 관리 샘플 정보About the proactive sample

일반적으로 애플리케이션인 봇에는 다음과 같은 몇 가지 계층이 있습니다.In general, a bot as an application has a few layers:

  • HTTP 요청을 수락할 수 있고 특히 메시징 엔드포인트를 지원하는 웹 애플리케이션입니다.The web application that can accept HTTP requests and specifically supports a messaging endpoint.
  • 채널과의 연결을 처리하는 어댑터입니다.An adapter that handles connectivity with the channels.
  • 일반적으로 봇 앱에 대한 대화 추론을 처리하는 클래스에 캡슐화된 턴에 대한 처리기입니다.A handler for the turn, typically encapsulated in a bot class that handles the conversational reasoning for the bot app.

사용자 로부터 들어오는 메시지에 대 한 응답으로 앱은 어댑터의 process 활동 메서드를 호출 하 여 턴 및 턴 컨텍스트를 만들고 해당 미들웨어 파이프라인을 호출한 다음 봇의 턴 처리기를 호출 합니다.In response to an incoming message from the user, the app calls the adapter's process activity method, which creates a turn and turn context, calls its middleware pipeline, and then calls the bot's turn handler.

자동 관리 메시지를 시작 하려면 bot 응용 프로그램에서 추가 입력을 받을 수 있어야 합니다.To initiate a proactive message, the bot application needs to be able to receive additional input. 자동 관리 메시지를 시작 하기 위한 응용 프로그램 논리는 SDK의 범위를 벗어납니다.The application logic for initiating a proactive message is outside the scope of the SDK. 이 샘플에서는 표준 메시지 끝점 외에도 알림 끝점을 사용 하 여 자동 관리를 트리거합니다.For this sample, a notify endpoint, in addition to a standard messages endpoint, is used to trigger the proactive turn.

이 알림 끝점의 GET 요청에 대 한 응답으로 앱은 process activity 메서드와 비슷하게 동작 하는 어댑터의 continue 대화 메서드를 호출 합니다.In response to a GET request on this notify endpoint, the app calls the adapter's continue conversation method, which behaves similarly to the the process activity method. Continue 대화 방법:The continue conversation method:

  • 사용자에 대 한 적절 한 대화 참조 및 자동 관리에 사용할 콜백 메서드를 사용 합니다.Takes an appropriate conversation reference for the user and the callback method to use for the proactive turn.
  • 이벤트 활동을 만들고 자동 관리에 대 한 컨텍스트를 설정 합니다.Creates an event activity and turn context for the proactive turn.
  • 어댑터의 미들웨어 파이프라인을 호출 합니다.Calls the adapter's middleware pipeline.
  • 제공 된 콜백 메서드를 호출 합니다.Calls the provided callback method.
  • 턴 컨텍스트는 대화 참조를 사용 하 여 사용자에 게 메시지를 보냅니다.The turn context uses the conversation reference to send any messages to the user.

이 샘플에는 다음 그림에 표시 된 것 처럼 사용자에 게 자동 관리 메시지를 보내는 데 사용 되는 봇, 메시지 끝점 및 추가 알림 끝점이 있습니다.The sample has a bot, a messages endpoint, and an additional notify endpoint that is used to send proactive messages to the user, as shown in the following illustration.

자동 관리 봇

대화 참조 검색 및 저장Retrieve and store conversation reference

에뮬레이터가 봇에 연결 되 면 봇은 두 개의 대화 업데이트 활동을 받습니다.When the Emulator connects to the bot, the bot receives two conversation update activities. 봇의 대화 업데이트 작업 처리기에서는 아래와 같이 참조를 검색하고 사전에 저장합니다.In the bot's conversation update activity handler, the conversation reference is retrieved and stored in a dictionary as shown below.

Bots\ProactiveBot.csBots\ProactiveBot.cs

private void AddConversationReference(Activity activity)
{
    var conversationReference = activity.GetConversationReference();
    _conversationReferences.AddOrUpdate(conversationReference.User.Id, conversationReference, (key, newValue) => conversationReference);
}

protected override Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    AddConversationReference(turnContext.Activity as Activity);

    return base.OnConversationUpdateActivityAsync(turnContext, cancellationToken);
}

대화 참조에는 활동이 있는 대화를 설명 하는 대화 속성이 포함 되어 있습니다.The conversation reference includes a conversation property that describes the conversation in which the activity exists. 대화에는 대화에 참여 하는 사용자를 나열 하는 사용자 속성과 현재 작업에 대 한 회신이 전송 될 수 있는 위치를 나타내는 서비스 URL 속성이 포함 됩니다.The conversation includes a user property that lists the users participating in the conversation, and a service URL property that indicates where replies to the current activity may be sent. 사용자에게 자동 관리 메시지를 보내려면 유효한 대화 참조가 필요합니다.A valid conversation reference is needed to send proactive messages to users. 팀 채널의 경우 서비스 URL은 지역화 된 서버에 매핑됩니다.(For the Teams channel, the service URL maps to a regionalized server.)

참고

실제 시나리오에서는 메모리의 개체를 사용하는 대신 대화 참조를 데이터베이스에 유지할 것입니다.In a real-world scenario you would persist conversation references in a database instead of using an object in memory.

자동 관리 메시지 보내기Send proactive message

두 번째 컨트롤러인 알림 컨트롤러는 사용자에 게 자동 관리 메시지를 보냅니다.The second controller, the notify controller, is responsible for sending the proactive message to the user. 다음 단계를 사용 하 여 사전 메시지를 생성 합니다.It uses the following steps to generate a proactive message.

  1. 자동 관리 메시지를 보낼 대화에 대한 참조를 검색합니다.Retrieves the reference for the conversation to which to send the proactive message.
  2. 어댑터의 대화 계속 메서드를 호출하여 대화 참조 및 사용할 턴 처리기 대리자를 제공합니다.Calls the adapter's continue conversation method, providing the conversation reference and the turn handler delegate to use. 대화 계속 메서드는 참조된 대화에 대한 턴 컨텍스트를 생성한 다음 지정된 턴 처리기 대리자를 호출합니다.(The continue conversation method generates a turn context for the referenced conversation and then calls the specified turn handler delegate.)
  3. 대리자에서 는 턴 컨텍스트를 사용하여 자동 관리 메시지를 보냅니다.In the delegate, uses the turn context to send the proactive message. 여기서 대리자는 알림 컨트롤러에 정의되고 사용자에게 자동 관리 메시지를 보냅니다.Here, the delegate is defined on the notify controller, and it sends the proactive message to the user.

참고

각 채널은 안정적인 서비스 URL을 사용해야 하지만 URL은 시간이 지남에 따라 변경 될 수 있습니다.While each channel should use a stable service URL, the URL can change over time. 서비스 URL에 대한 자세한 내용은 Bot Framework 활동 스키마의 기본 활동 구조서비스 URL 섹션을 참조하세요.For more information about the service URL, see the Basic activity structure and Service URL sections of the Bot Framework Activity Schema.

서비스 URL이 변경되면 이전 대화 참조는 더 이상 유효하지 않으며 대화를 계속하기 위한 호출은 오류 또는 예외를 생성합니다.If the service URL changes, previous conversation references will no longer be valid and calls to continue conversation will generate an error or exception. 이 경우 봇은 사전 대응 메시지를 다시 보내기 전에 사용자에 대한 새 대화 참조를 획득해야 합니다.In this case, your bot will need to acquire a new conversation reference for the user before it can send proactive messages again.

Controllers\NotifyController.csControllers\NotifyController .cs

봇의 알림 페이지를 요청받을 때마다 알림 컨트롤러는 사전에서 대화 참조를 검색합니다.Each time the bot's notify page is requested, the notify controller retrieves the conversation references from the dictionary. 그런 다음, 컨트롤러는 ContinueConversationAsyncBotCallback 메서드를 사용하여 자동 관리 메시지를 보냅니다.The controller then uses the ContinueConversationAsync and BotCallback methods to send the proactive message.

[Route("api/notify")]
[ApiController]
public class NotifyController : ControllerBase
{
    private readonly IBotFrameworkHttpAdapter _adapter;
    private readonly string _appId;
    private readonly ConcurrentDictionary<string, ConversationReference> _conversationReferences;

    public NotifyController(IBotFrameworkHttpAdapter adapter, IConfiguration configuration, ConcurrentDictionary<string, ConversationReference> conversationReferences)
    {
        _adapter = adapter;
        _conversationReferences = conversationReferences;
        _appId = configuration["MicrosoftAppId"] ?? string.Empty;
    }

    public async Task<IActionResult> Get()
    {
        foreach (var conversationReference in _conversationReferences.Values)
        {
            await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, BotCallback, default(CancellationToken));
        }
        
        // Let the caller know proactive messages have been sent
        return new ContentResult()
        {
            Content = "<html><body><h1>Proactive messages have been sent.</h1></body></html>",
            ContentType = "text/html",
            StatusCode = (int)HttpStatusCode.OK,
        };
    }

    private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)
    {
        await turnContext.SendActivityAsync("proactive hello");
    }
}

어댑터가 자동 관리 메시지를 보내려면 봇에 대한 앱 ID가 필요합니다.To send a proactive message, the adapter requires an app ID for the bot. 프로덕션 환경에서는 봇의 앱 ID를 사용할 수 있습니다.In a production environment, you can use the bot's app ID. 에뮬레이터를 사용하여 로컬로 봇을 테스트하려면 빈 문자열("")을 사용할 수 있습니다.To test the bot locally with the Emulator, you can use the empty string ("").

봇 테스트Test your bot

  1. 아직 설치하지 않은 경우 Bot Framework Emulator를 설치합니다.If you have not done so already, install the Bot Framework Emulator.
  2. 샘플을 머신에서 로컬로 실행합니다.Run the sample locally on your machine.
  3. 에뮬레이터를 시작하고 봇에 연결합니다.Start the Emulator and connect to your bot.
  4. 봇의 api/notify 페이지를 로드합니다.Load to your bot's api/notify page. 그러면 에뮬레이터에서 자동 관리 메시지가 생성됩니다.This will generate a proactive message in the Emulator.

추가 정보Additional information

이 문서에 사용된 샘플 외에도 GitHub에서추가 샘플을 사용할 수 있습니다.Besides the sample used in this article, additional samples are available on GitHub.

설계 고려 사항Design considerations

봇에서 자동 관리 메시지를 구현하는 경우 짧은 시간 내에 여러 개의 자동 관리 메시지를 보내지 마십시오.When implementing proactive messages in your bot, don't send several proactive messages within a short amount of time. 일부 채널은 봇이 사용자에게 메시지를 보낼 수 있는 빈도를 제한하며, 해당 제한을 위반할 경우 봇을 사용하지 않도록 설정합니다.Some channels enforce restrictions on how frequently a bot can send messages to the user, and will disable the bot if it violates those restrictions.

임시 자동 관리 메시지는 가장 간단한 형식의 자동 관리 메시지입니다.An ad hoc proactive message is the simplest type of proactive message. 봇은 메시지가 트리거될 때마다 사용자가 현재 봇과 다른 주제의 대화에 참여하고 있으며 대화를 변경하지 않으려고 하는지 여부에 관계없이 메시지를 간단히 대화에 삽입합니다.The bot simply interjects the message into the conversation whenever it is triggered, without any regard for whether the user is currently engaged in a separate topic of conversation with the bot and will not attempt to change the conversation in any way.

알림을 더 원활하게 처리하려면 대화 상태에 플래그를 설정하거나 알림을 큐에 추가하는 것처럼 알림을 대화 흐름에 통합하는 다른 방법을 사용하는 것이 좋습니다.To handle notifications more smoothly, consider other ways to integrate the notification into the conversation flow, such as setting a flag in the conversation state or adding the notification to a queue.

자동 관리 턴 정보About the proactive turn

대화 계속 메서드는 대화 참조 및 턴 콜백 처리기를 사용하여 다음을 수행합니다.The continue conversation method uses the conversation reference and a turn callback handler to:

  1. 봇 애플리케이션이 자동 관리 메시지를 보낼 수 있는 턴을 만듭니다.Create a turn in which the bot application can send the proactive message. 어댑터는 event 이름이 "ContinueConversation"으로 설정된 이 턴에 대한 작업을 만듭니다.The adapter creates an event activity for this turn, with its name set to "ContinueConversation".
  2. 어댑터의 미들웨어 파이프라인을 통해 턴을 보냅니다.Send the turn through the adapter's middleware pipeline.
  3. 턴 콜백 처리기를 호출하여 사용자 지정 논리를 수행합니다.Call the turn callback handler to perform custom logic.

자동 관리 메시지 샘플에서 턴 콜백 처리기는 알림 컨트롤러에 정의되고 봇의 일반 턴 처리기를 통해 자동 관리 활동을 보내지 않고 메시지를 대화에 직접 보냅니다.In the proactive messages sample, the turn callback handler is defined in the notify controller and sends the message directly to the conversation, without sending the proactive activity through the bot's normal turn handler. 또한 샘플 코드는 자동 관리 턴에서 봇의 상태에 액세스하거나 업데이트하지 않습니다.The sample code also does not access or update the bot's state on the proactive turn.

많은 봇은 상태 비정상 상태이며 상태를 사용하여 여러 턴에 걸쳐 대화를 관리합니다.Many bots are stateful and use state to manage a conversation over multiple turns. 대화 계속 메서드가 턴 컨텍스트를 만들면 턴에 올바른 사용자 및 대화 상태가 연결되고 자동 관리 턴을 봇의 논리에 통합할 수 있습니다.When the continue conversation method creates a turn context, the turn will have the correct user and conversation state associated with it, and you can integrate proactive turns into your bot's logic. 봇 논리가 사전 대응 메시지를 인식해야 하는 경우 몇 가지 옵션을 사용할 수 있습니다.If you need the bot logic to be aware of the proactive message, you have a few options for doing so. 다음 작업을 수행할 수 있습니다.You can:

  • 봇의 턴 처리기를 턴 콜백 처리기로 제공합니다.Provide the bot's turn handler as the turn callback handler. 그러면 봇이 "ContinueConversation" 이벤트 활동을 받게 됩니다.The bot will then receive the "ContinueConversation" event activity.
  • 턴 콜백 처리기를 사용하여 먼저 턴 컨텍스트에 정보를 추가한 다음, 봇의 턴 처리기를 호출합니다.Use the turn callback handler to add information to the turn context first, and then call the bot's turn handler.

두 경우 모두 사전 대응 이벤트를 처리하도록 봇 논리를 디자인해야 합니다.In both of these cases, you will need to design your bot logic to handle the proactive event.

다음 단계Next steps