Beispiel #1
0
        public static async Task <IBotData> GetBotDataAsync(IAddress userAddress, IBotDataStore <BotData> botDataStore, CancellationToken cancellationToken)
        {
            var botData = new JObjectBotData(userAddress, botDataStore);
            await botData.LoadAsync(cancellationToken);

            return(botData);
        }
Beispiel #2
0
        private async Task HandleUserData(Activity activity)
        {
            using (ILifetimeScope scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
            {
                IAddress address = Address.FromActivity(activity);
                IBotDataStore <BotData> botDataStore = scope.Resolve <IBotDataStore <BotData> >();
                BotData userData = await botDataStore.LoadAsync(address, BotStoreType.BotUserData, CancellationToken.None);

                User user = userData.GetProperty <User>("User");

                if (user == null)
                {
                    IUserService  userService = scope.Resolve <IUserService>();
                    UserCondition condition   = new UserCondition()
                    {
                        LineUserId = activity.From.Id,
                        UserName   = activity.From.Name
                    };
                    user = userService.GetOrCreate(condition);

                    userData.SetProperty("User", user);
                    await botDataStore.SaveAsync(address, BotStoreType.BotUserData, userData, CancellationToken.None);

                    await botDataStore.FlushAsync(address, CancellationToken.None);
                }
            }
        }
 /// <summary>
 /// Constructs a new <see cref="V3V4Storage"/>
 /// </summary>
 /// <param name="v3DataStore">A Bot Builder SDK V3 <see cref="IBotDataStore"/> (required)</param>
 /// <param name="botStoreType">THe Type of Data Storage (UserData, ConversationData, PrivateConversationData)
 /// <see cref="BotStoreType"/>Type of storage</param>
 /// <param name="statePropertyName">This is only relavent in code.  The name of the BotState property,
 /// retrieved and accessed through a property accessor created from an instance of <see cref="V3V4State"/>.</param>
 public V3V4Storage(IBotDataStore <BotData> v3DataStore,
                    BotStoreType botStoreType = BotStoreType.BotUserData,
                    string statePropertyName  = "V3State")
 {
     _v3DataStore       = v3DataStore ?? throw new ArgumentNullException(nameof(v3DataStore));
     _botStoreType      = botStoreType;
     _statePropertyName = statePropertyName;
 }
Beispiel #4
0
        private async Task <bool> isNewUser(string userId, Microsoft.Bot.Connector.Activity message, TableBotDataStore botStateStore)
        {
            IBotDataStore <BotData> dataStore     = botStateStore;
            pigLatinBotUserData     addedUserData = new pigLatinBotUserData();
            BotData botData = new BotData();

            try
            {
                botData = (BotData)await dataStore.LoadAsync(new Address(message.Recipient.Id, message.ChannelId, userId, message.Conversation.Id, message.ServiceUrl), BotStoreType.BotUserData, default(CancellationToken));
            }
            catch (Exception e)
            {
                if (e.Message == "Resource not found")
                {
                }
                else
                {
                    throw e;
                }
            }

            if (botData.Data == null)
            {
                botData = new BotData(eTag: "*");
            }

            addedUserData = botData.GetProperty <pigLatinBotUserData>("v1") ?? new pigLatinBotUserData();

            if (addedUserData.isNewUser == true)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #5
0
        public virtual async Task <HttpResponseMessage> Post([FromBody] Microsoft.Bot.Connector.Activity message)
        {
            ConnectorClient connector = new ConnectorClient(new Uri(message.ServiceUrl));

            IBotDataStore <BotData> dataStore = botStateStore;

            storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("piglatinbotsjameslew_AzureStorageConnectionString"));
            botStateStore  = new TableBotDataStore(storageAccount, "botdata");

            Microsoft.Bot.Connector.Activity replyMessage = message.CreateReply();
            replyMessage.Locale     = "en-Us";
            replyMessage.TextFormat = TextFormatTypes.Plain;

            if (message.GetActivityType() != ActivityTypes.Message)
            {
                replyMessage = await handleSystemMessagesAsync(message, connector, botStateStore);

                if (replyMessage != null)
                {
                    var reply = await connector.Conversations.ReplyToActivityAsync(replyMessage);
                }
            }
            else
            {
                if (message.Text.Contains("MessageTypesTest"))
                {
                    Microsoft.Bot.Connector.Activity mtResult = await messageTypesTest(message, connector);

                    await connector.Conversations.ReplyToActivityAsync(mtResult);
                }
                else if (message.Text.Contains("DataTypesTest"))
                {
                    Microsoft.Bot.Connector.Activity dtResult = await dataTypesTest(message, connector, botStateStore);

                    await connector.Conversations.ReplyToActivityAsync(dtResult);
                }
                else if (message.Text.Contains("CardTypesTest"))
                {
                    Microsoft.Bot.Connector.Activity ctResult = await cardTypesTest(message, connector);

                    await connector.Conversations.ReplyToActivityAsync(ctResult);
                }

                try
                {
                    if (await isNewUser(message.From.Id, message, botStateStore))
                    {
                        Microsoft.Bot.Connector.Activity introMessage = message.CreateReply();
                        introMessage.Locale     = "en-Us";
                        introMessage.TextFormat = TextFormatTypes.Plain;
                        introMessage.InputHint  = InputHints.IgnoringInput;

                        introMessage.Text = string.Format(translateToPigLatin("Hey there, I'm PigLatinBot. I make intelligible text unintelligible.  Ask me how by typing 'Help', and for terms and info, click ") + "[erehay](http://www.piglatinbot.com)", message.From.Name);
                        var reply = await connector.Conversations.ReplyToActivityAsync(introMessage);
                    }
                    replyMessage.InputHint = InputHints.AcceptingInput;
                    replyMessage.Speak     = message.Text;
                    replyMessage.Text      = translateToPigLatin(message.Text);
                    var httpResponse = await connector.Conversations.ReplyToActivityAsync(replyMessage);
                }
                catch (HttpResponseException e)
                {
                    Trace.WriteLine(e.Message);
                    var Response = Request.CreateResponse(HttpStatusCode.InternalServerError);
                    return(Response);
                }
            }
            var responseOtherwise = Request.CreateResponse(HttpStatusCode.OK);

            return(responseOtherwise);
        }
Beispiel #6
0
        private async Task <Microsoft.Bot.Connector.Activity> handleSystemMessagesAsync(Microsoft.Bot.Connector.Activity message, ConnectorClient connector, TableBotDataStore botStateStore)
        {
            Microsoft.Bot.Connector.Activity replyMessage = message.CreateReply();
            message.Locale = "en";
            IBotDataStore <BotData> dataStore = botStateStore;

            switch (message.GetActivityType())
            {
            case ActivityTypes.DeleteUserData:
                //In this case the DeleteUserData message comes from the user so we can clear the data and set it back directly

                BotData currentBotData = (BotData)await dataStore.LoadAsync(new Address(message.Recipient.Id, message.ChannelId, message.From.Id, message.Conversation.Id, message.ServiceUrl), BotStoreType.BotUserData, default(CancellationToken));

                pigLatinBotUserData deleteUserData = new pigLatinBotUserData();
                currentBotData.SetProperty("v1", deleteUserData);
                await dataStore.SaveAsync(new Address(message.Recipient.Id, message.ChannelId, message.From.Id, message.Conversation.Id, message.ServiceUrl), BotStoreType.BotUserData, currentBotData, default(CancellationToken));

                replyMessage.Text = translateToPigLatin("I have deleted your data oh masterful one");
                Trace.TraceInformation("Clearing user's BotUserData");
                return(replyMessage);

            //if they're new or haven't seen the updated legal documents, send them a message
            //use the incoming message to set up the outgoing message
            case ActivityTypes.ConversationUpdate:

                foreach (ChannelAccount added in message.MembersAdded)
                {
                    Microsoft.Bot.Connector.Activity addedMessage = message.CreateReply();

                    bool needToSendWelcomeText        = false;
                    pigLatinBotUserData addedUserData = new pigLatinBotUserData();
                    BotData             botData       = new BotData();

                    // is the added member me?
                    if (added.Id == message.Recipient.Id)
                    {
                        addedMessage.Text = string.Format(translateToPigLatin("Hey there, I'm PigLatinBot. I make intelligible text unintelligible.  Ask me how by typing 'Help', and for terms and info, click ") + "[erehay](http://www.piglatinbot.com)", added.Name);
                        var reply = await connector.Conversations.ReplyToActivityAsync(addedMessage);

                        continue;
                    }

                    if (await isNewUser(added.Id, message, botStateStore))
                    {
                        addedUserData.isNewUser = false;
                        needToSendWelcomeText   = true;
                    }

                    if (addedUserData.lastReadLegalese < lastModifiedPolicies)
                    {
                        addedUserData.lastReadLegalese = DateTime.UtcNow;
                        needToSendWelcomeText          = true;
                    }
                    if (needToSendWelcomeText)
                    {
                        addedMessage.Text         = string.Format(translateToPigLatin("Welcome to the chat") + " {0}, " + translateToPigLatin("I'm PigLatinBot. I make intelligible text unintelligible.  Ask me how by typing 'Help', and for terms and info, click ") + "[erehay](http://www.piglatinbot.com)", added.Name);
                        addedMessage.Recipient    = added;
                        addedMessage.Conversation = null;

                        try
                        {
                            botData.SetProperty("v1", addedUserData);
                            await dataStore.SaveAsync(new Address(message.Recipient.Id, message.ChannelId, added.Id, message.Conversation.Id, message.ServiceUrl), BotStoreType.BotUserData, botData, default(CancellationToken));
                        }
                        catch (Exception e)
                        {
                            Trace.WriteLine(e.Message);
                        }

                        var ConversationId = await connector.Conversations.CreateDirectConversationAsync(message.Recipient, message.From);

                        addedMessage.Conversation = new ConversationAccount(id: ConversationId.Id);
                        var reply = await connector.Conversations.SendToConversationAsync(addedMessage);
                    }
                }

                //maybe someone got removed
                foreach (ChannelAccount removed in message.MembersRemoved)
                {
                    Microsoft.Bot.Connector.Activity removedMessage = message.CreateReply();
                    removedMessage.Locale = "en";

                    removedMessage.Text = string.Format("{0}", removed.Name) + translateToPigLatin(" has Left the building");
                    var reply = await connector.Conversations.ReplyToActivityAsync(removedMessage);
                }

                return(null);

            default:
                return(null);
            }
        }
        private static async Task TestStoreType(BotStoreType storeType, int iterations, IBotDataStore <BotData> sourceStore, IBotDataStore <BotData> targetStore)
        {
            Random rnd = new Random();

            // fill source store
            for (int i = 0; i < iterations; i++)
            {
                await sourceStore.SaveAsync(CreateAddress(i), storeType, new BotData(eTag : "*", data : new TestData()
                {
                    Store = "source", Value = i
                }), CancellationToken.None);
            }

            var bridgeStore = (IBotDataStore <BotData>) new BotDataStoreBridge(sourceStore, targetStore);

            for (int i = 0; i < iterations; i++)
            {
                // every object should be readable from source
                var result = await bridgeStore.LoadAsync(CreateAddress(i), storeType, CancellationToken.None);

                Assert.IsNotNull(result.Data);
                Assert.IsTrue(!String.IsNullOrEmpty(result.ETag));

                // every object should not be in target
                var result2 = await targetStore.LoadAsync(CreateAddress(i), storeType, CancellationToken.None);

                Assert.IsNull(result2.Data);
                Assert.IsTrue(String.IsNullOrEmpty(result2.ETag));
            }

            // Save new object should work
            try
            {
                await bridgeStore.SaveAsync(new TestAddress()
                {
                    BotId          = "MyFunctionBot",
                    ChannelId      = "test",
                    ConversationId = "ACONVERATION",
                    UserId         = "AUSER"
                }, storeType, new BotData(eTag : "*", data : new TestData()
                {
                    Store = "target", Value = int.MaxValue
                }), CancellationToken.None);
            }
            catch (Exception err)
            {
                Assert.Fail($"Failed to write new record to bridge store:{err.Message}\n{err.ToString()}");
            }

            for (int i = 0; i < iterations; i++)
            {
                var address = CreateAddress(i);
                // Every object should be still be loadable
                BotData botData = await bridgeStore.LoadAsync(address, storeType, CancellationToken.None);

                // change object and save
                var data = ((JObject)botData.Data).ToObject <TestData>();
                data.Store   = "target";
                botData.Data = data;

                // Every change should be saved to targetStore
                await bridgeStore.SaveAsync(address, storeType, botData, CancellationToken.None);
            }

            // verify write with ETag and precondition failure
            for (int i = 0; i < iterations; i++)
            {
                try
                {
                    var address = CreateAddress(i);
                    var result  = await bridgeStore.LoadAsync(address, storeType, CancellationToken.None);

                    // set Value2 to good
                    await bridgeStore.SaveAsync(address, storeType, new BotData(eTag : result.ETag, data : new TestData()
                    {
                        Store = "target", Value = i, Value2 = "good"
                    }), CancellationToken.None);

                    // bad attempt to set Value2 to bad
                    await bridgeStore.SaveAsync(address, storeType, new BotData(eTag : result.ETag, data : new TestData()
                    {
                        Store = "target", Value = i, Value2 = "bad"
                    }), CancellationToken.None);

                    Assert.Fail("Should throw HttpException with precondition failure");
                }
                catch (HttpException err)
                {
                    Assert.AreEqual(412, err.GetHttpCode(), "Expected precondition failure");
                }
            }

            // every object should now be in targetStore
            for (int i = 0; i < iterations; i++)
            {
                var address = CreateAddress(i);

                BotData result1 = await sourceStore.LoadAsync(address, storeType, CancellationToken.None);

                BotData result2 = await targetStore.LoadAsync(address, storeType, CancellationToken.None);

                var data1 = ((JObject)result1.Data).ToObject <TestData>();
                var data2 = ((JObject)result2.Data).ToObject <TestData>();

                Assert.IsNotNull(result1.Data, "Every object should be loadable from source store");
                Assert.IsNotNull(result2.Data, "Every object should be loadable from target store");

                Assert.AreEqual(data1.Value, data2.Value, "values should be the same");

                Assert.AreEqual(data1.Store, "source", "source record should be source");
                Assert.AreEqual(data2.Store, "target", "target record should be target");

                Assert.AreEqual(data2.Value2, "good", "target record value2 should be good");

                Assert.AreNotEqual(result1.ETag, result2.ETag, "ETags should be different");
            }
        }
Beispiel #8
0
        static async Task <BotData> GetConversationData(IBotDataStore <BotData> botDataStore, Address key)
        {
            var botData = await botDataStore.LoadAsync(key, BotStoreType.BotConversationData, CancellationToken.None);

            return(botData);
        }
Beispiel #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BotDataFactory"/> class.
        /// </summary>
        /// <param name="store">The <see cref="IBotDataStore{T}"/></param>
        public BotDataFactory(IBotDataStore <BotData> store)
        {
            store.ThrowIfNull(nameof(store));

            this.store = store;
        }