0

Is there a way to use the Conversation so that the IMessageActivity to be sent to the user is returned to the caller instead of sent back to the user uri?
What I want to accomplish is to handle myself the incoming and outgoing messages, and while I can create an activity to be supplied to the Conversation object I cannot read and use the IMessageActivity reply.

To be more specific I'm wondering if I can substitute

Conversation.SendAsync(IMessageActivity, Func<IDialog<object>>);

With something that will let me handle the reply.

Thank you.

Ezequiel Jadib
  • 14,767
  • 2
  • 38
  • 43
Matteo Saporiti
  • 164
  • 1
  • 8

1 Answers1

0

The reply should be handled by the dialog passed to the SendAsync method.

In the dialog, you will usually have a method that receives the context and the message sent by the user. For example:

public async virtual Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
   var message = await result;
}

In the StartAsync method of the dialog you will have to set this method as the one that will be called once the user sends a message to the bot

public async Task StartAsync(IDialogContext context)
{
    context.Wait(this.MessageReceivedAsync);
}

Then, is up to you to decide what to do after receiving the message.

Do you want to use a PromptDialog, e.g. the Confirm one? You can, just instantiate the dialog, call it and get the result in the ResumeAfter<bool> method.

PromptDialog.Confirm(context, ResumeAfterPrompt, "prompt dialogue", "retry dialog", 3);

private async Task ResumeAfterPrompt(IDialogContext context, IAwaitable<bool> result)
{
    try
    {
        // try get user response
        bool response = await result;

        await context.PostAsync($"You said: {result}");
    }
    catch (TooManyAttemptsException)
    {
        // handle error
    }

   // wait for another message from the user. Could be the same method or a new one following the same signature.
   context.Wait(this.MessageReceivedAsync);
}

Do you want to use a FormFlow? You also, just instantiate the FormDialog and get the result in the ResumeAfter<T> method you define.

It's always the same pattern when working with multi dialogs (Prompts and Forms are dialogs!): call the dialog, get the result in the ResumeAfter method and wait for a new user message.

All this concepts are well explained and also demonstrated in the Multi-Dialogs sample. Go through the readme and the codebase and you will understand what I explained. That sample shows prompts, a FormFlow, custom dialogs, etc. Here there are a few more details.

Community
  • 1
  • 1
Ezequiel Jadib
  • 14,767
  • 2
  • 38
  • 43
  • I probably didn't explain exactly what I wanted to get. I know it's easy to get the result from the user, what I want to intercept is the content that the Dialog send to the user so something like `{ "type": "message", "channelId": "emulator", "from": { "id": "56800324", "name": "Bot1" }, "recipient": { "id": "2c1c7fa3", "name": "User1" }, "text": "Reply from the bot", "replyToId": "ba2f5b31398f48348b0f99427bed2e57" }` Because I want to send my reply to the client and not let the Connector send its own. – Matteo Saporiti Feb 07 '17 at 15:12
  • OK, use IActivityLogger to intercept the message. It won't prevent the Conversation to send it though – Ezequiel Jadib Feb 07 '17 at 15:50
  • Minor question, what's your client? Explain a bit more your scenario; you a bot and a custom client? – Ezequiel Jadib Feb 08 '17 at 12:32