0

In MessagesController.cs in my code I added a part to save userlog data like userid,username, channel, date, messages...I want to save also the answer of the bot ? but I don't know how to do. The database is in azure.

This is the code : MessagesController.cs

    using System.Net.Http;
   using System.Threading.Tasks;
     using System.Web.Http;
  using Microsoft.Bot.Builder.Dialogs;
 using Microsoft.Bot.Connector;
 using System;
 using System.Net;

 namespace QnABot
 {
[BotAuthentication]
public class MessagesController : ApiController
{
    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {

        #region Set CurrentBaseURL and ChannelAccount
        // Get the base URL that this service is running at
        // This is used to show images
        string CurrentBaseURL =

     this.Url.Request.RequestUri.AbsoluteUri.Replace(@"api/messages", "");

        // Create an instance of BotData to store data
        BotData objBotData = new BotData();

        // Instantiate a StateClient to save BotData            
        StateClient stateClient = activity.GetStateClient();

        // Use stateClient to get current userData
        BotData userData = await stateClient.BotState.GetUserDataAsync(
            activity.ChannelId, activity.From.Id);

        // Update userData by setting CurrentBaseURL and Recipient
        userData.SetProperty<string>("CurrentBaseURL", CurrentBaseURL);

        // Save changes to userData
        await stateClient.BotState.SetUserDataAsync(
            activity.ChannelId, activity.From.Id, userData);
        #endregion

        if (activity.Type == ActivityTypes.Message)
        {



            //*************************
            //Log to Database
            // *************************

            //// Instantiate the BotData dbContext
            Model.qnamakerentitiesEntities DB = new 
           Model.qnamakerentitiesEntities();
            // Create a new UserLog object
            Model.UserLog NewUserLog = new Model.UserLog();

            // Set the properties on the UserLog object
            NewUserLog.Channel = activity.ChannelId;
            NewUserLog.UserID = activity.From.Id;
            NewUserLog.UserName = activity.From.Name;
            NewUserLog.created = DateTime.UtcNow;
            NewUserLog.Message = activity.Text.Truncate(500);
            //   NewUserLog.Response = activity.AsMessageActivity()?.Text;



            // Add the UserLog object to UserLogs
            DB.UserLogs.Add(NewUserLog);
            // Save the changes to the database
            DB.SaveChanges();


            await Conversation.SendAsync(activity, () => new 
        Dialogs.QnADialog());
        }
        else
        {
            await HandleSystemMessage(activity);
        }
        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }

    private async Task<Activity> HandleSystemMessage(Activity message)
    {
        if (message.Type == ActivityTypes.DeleteUserData)
        {
            // Implement user deletion here
            // If we handle user deletion, return a real message
        }
        else if (message.Type == ActivityTypes.ConversationUpdate)
        {
            IConversationUpdateActivity iConversationUpdated = message as 
       IConversationUpdateActivity;
            if (iConversationUpdated != null)
            {
            }
        }
        else if (message.Type == ActivityTypes.ContactRelationUpdate)
        {
            // Handle add/remove from contact lists
            // Activity.From + Activity.Action represent what happened
        }
        else if (message.Type == ActivityTypes.Typing)
        {
            // Handle knowing tha the user is typing
        }
        else if (message.Type == ActivityTypes.Ping)
        {
        }

        return null;
         }
       }
     }

RootDialog.cs is like this :

  using System;
  using System.Threading.Tasks;
  using Microsoft.Bot.Builder.Dialogs;
  using Microsoft.Bot.Connector;
  using QnABot.API;
  using Microsoft.Bot.Builder.Dialogs.Internals;

  namespace QnABot.Dialogs
  {
  [Serializable]
  public class RootDialog : IDialog<object>
   {
    public Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);

        return Task.CompletedTask;
    }

    private async Task MessageReceivedAsync(IDialogContext context, 
     IAwaitable<object> result)
    {
        //var activity = await result as Activity;

        //// Prompt text
        //await context.PostAsync("Welcome Feel free to ask me ");

        //var privateData = context.PrivateConversationData;
        //var privateConversationInfo = IncrementInfoCount(privateData, 
   BotStoreType.BotPrivateConversationData.ToString());
        //var conversationData = context.ConversationData;
        //var conversationInfo = IncrementInfoCount(conversationData, 
   BotStoreType.BotConversationData.ToString());
        //var userData = context.UserData;
        //var userInfo = IncrementInfoCount(userData, 
     BotStoreType.BotUserData.ToString());
        //context.Wait(QnADialog);



  //privateData.SetValue(BotStoreType.BotPrivateConversationData.ToString(), 
      privateConversationInfo);

   //conversationData.SetValue(BotStoreType.BotConversationData.ToString(), conversationInfo);
        //userData.SetValue(BotStoreType.BotUserData.ToString(), userInfo);
        Activity replyToConversation = (Activity)context.MakeMessage();
        replyToConversation.Recipient = replyToConversation.Recipient;
        replyToConversation.Type = "message";
    }

    private async Task QnADialog(IDialogContext context, IAwaitable<object> 
    result)
    {
        var activityResult = await result as Activity;
        var query = activityResult.Text;
        var reply = activityResult.CreateReply();

        var qnaResult = QnaApi.GetFirstQnaAnswer(query);
        string message = "";

        if (qnaResult == null)
        {
             message = $"Sorry, I did not understand . Please reformulate 
        your question";

        }
        else
        {
            message = qnaResult.answers[0].answer;
        }



        // *************************
        // Log to Database
        // *************************
        Activity replyToConversation = (Activity)context.MakeMessage();
        // Instantiate the BotData dbContext
        Model.qnamakerentitiesEntities DB = new 
        Model.qnamakerentitiesEntities();
        // Create a new UserLog object
        Model.UserLog NewUserLog = new Model.UserLog();

        // Set the properties on the UserLog object
        NewUserLog.Channel = replyToConversation.ChannelId;
        NewUserLog.UserID = replyToConversation.From.Id;
        NewUserLog.UserName = replyToConversation.From.Name;
        NewUserLog.created = DateTime.UtcNow;
        // This logs the message being sent to the user
        NewUserLog.Message = qnaResult.answers[0].answer;
        //  NewUserLog.Response= qnaResult.answers[0].answer;

        // Add the UserLog object to UserLogs
        DB.UserLogs.Add(NewUserLog);
        // Save the changes to the database
        DB.SaveChanges();

        await context.PostAsync(replyToConversation);
        context.Wait(MessageReceivedAsync);
    }
    public class BotDataInfo
    {
        public int Count { get; set; }
    }

    private BotDataInfo IncrementInfoCount(IBotDataBag botdata, string key)
    {
        BotDataInfo info = null;
        if (botdata.ContainsKey(key))
        {
            info = botdata.GetValue<BotDataInfo>(key);
            info.Count++;
        }
        else
            info = new BotDataInfo() { Count = 1 };

        return info;
    }
}
}

I tried to follow your instructions but still have problems. I can store in database Id, UserId, ChannelID, created, message but not the response ( response in null in all my tests ) .

Can you help me what can i do ?

1 Answers1

1

One way to go here is implementing an IActivityLogger to inspect incoming and outgoing messages. In the core-Middleware sample you will see an example on how to do it.

public class DebugActivityLogger : IActivityLogger
    {
        public async Task LogAsync(IActivity activity)
        {
            Debug.WriteLine($"From:{activity.From.Id} - To:{activity.Recipient.Id} - Message:{activity.AsMessageActivity()?.Text}");
        }
    }

Also, you might hit the issue of knowing when the message is from the bot. In that case, I recommend you to read Know if IActivity is from bot or user in IActivityLogger.

Ezequiel Jadib
  • 14,767
  • 2
  • 38
  • 43
  • where are store this data ? in the database ? –  Aug 24 '17 at 11:05
  • That will depend on your use case, but yes could be saved anywhere. – Ezequiel Jadib Aug 24 '17 at 11:10
  • @Ezequiuel I want to store response of the bot also ...not only what a user has write . –  Nov 03 '17 at 13:01
  • As I explained in the answer the IActivityLogger will be triggered for both incoming and outcoming messages; so you will get the response from the bot too. – Ezequiel Jadib Nov 03 '17 at 14:06
  • Please help me with the code which show the response of the bot : {activity.From.Id} - To:{activity.Recipient.Id} - Message:{activity.AsMessageActivity()?.Text} here isn't :( –  Nov 03 '17 at 14:16
  • That code will show both; sometimes the recipient id will be bot sometimes it will be user. What's the bot is responding? – Ezequiel Jadib Nov 03 '17 at 14:41
  • mmm my problem maybe but i'm still confused :( i want to store in a table : userid, username , message_of_user and response of bot . Till now i can store all except response of bot . I don't know how to catch the response and to store this . For example user send a message : hello response of bot : welcome to my bot ! –  Nov 03 '17 at 14:56
  • It will go through the activity logger! you want to correlate the user message with the response to store in the same row? – Ezequiel Jadib Nov 03 '17 at 18:25
  • i try to update with recently code my questions ...please if you have time help me to find a solutions –  Nov 09 '17 at 13:27
  • no the question is still the same ...how to save response of the qnamaker in my bot –  Nov 10 '17 at 08:33