示例#1
0
        public async Task ExceptionInMatcher_TriggersOnExceptionCallback()
        {
            var bot = await SlackBot.InitializeAsync(this.driver, this.bus);

            this.state.AddUser("1", "user");
            this.state.AddHub("1", "", HubType.DirectMessage);

            var evt = new AutoResetEvent(false);

            bot
            .When(new ExceptionThrowingMatcher(() => new Exception("exception message")), c => Task.CompletedTask)
            .OnException((msg, ex) =>
            {
                Assert.Equal("exception message", ex.Message);
                evt.Set();
            });

            this.bus.Publish(new Message
            {
                Channel = "1",
                User    = "******",
                Text    = "hello"
            });

            if (!evt.WaitOne(100))
            {
                Assert.True(false, "When handler never fired");
            }
        }
示例#2
0
        public async Task DirectMessage_DoesNotRequireAddressingBotByName()
        {
            var bot = await SlackBot.InitializeAsync(this.driver, this.bus);

            this.state.AddUser("1", "user");
            this.state.AddHub("1", "test hub", HubType.DirectMessage);

            var evt = new AutoResetEvent(false);

            bot.When(Matches.Text("hello"), c =>
            {
                evt.Set();
                return(Task.CompletedTask);
            });

            this.bus.Publish(new Message
            {
                Channel = "1",
                User    = "******",
                Text    = "hello"
            });

            if (!evt.WaitOne(100))
            {
                Assert.True(false, "When handler never fired");
            }
        }
示例#3
0
        public async Task ChannelMessage_RespondsWhenAddressingBotByName(string message)
        {
            var bot = await SlackBot.InitializeAsync(this.driver, this.bus);

            this.state.AddUser("1", "user");
            this.state.AddHub("1", "test hub", HubType.Channel);

            var evt = new AutoResetEvent(false);

            bot.When(Matches.Text("hello"), c =>
            {
                evt.Set();
                return(Task.CompletedTask);
            });

            this.bus.Publish(new Message
            {
                Channel = "1",
                User    = "******",
                Text    = string.Format(message, this.state.BotUsername)
            });

            if (!evt.WaitOne(100))
            {
                Assert.True(false, "When handler never fired");
            }
        }
示例#4
0
        public async Task ChannelMessage_BotRespondWhenNotAddressedByName_WhenConfiguredToListenToAllMessages()
        {
            var bot = await SlackBot.InitializeAsync(this.driver, this.bus);

            this.state.AddUser("1", "user");
            this.state.AddHub("1", "test hub", HubType.Channel);

            var evt = new AutoResetEvent(false);

            bot.When(
                Matches.Text("hello"),
                HubType.Channel, Modes.ObserveAllMessages,
                c =>
            {
                evt.Set();
                return(Task.CompletedTask);
            });

            this.bus.Publish(new Message
            {
                Channel = "1",
                User    = "******",
                Text    = "hello"
            });

            if (!evt.WaitOne(100))
            {
                Assert.True(false, "When handler should have been fired since the message didn't address the bot");
            }
        }
示例#5
0
 async Task InitBotAsync(string token, LoggerFactory loggerFactory)
 {
     _bot = await SlackBot.InitializeAsync(token, config => {
         config.LoggerFactory        = loggerFactory;
         config.OnSendMessageFailure = OnSendMessageFailure;
     });
 }
示例#6
0
        public async Task OutgoingMessages_LimitedToOnePerSecond()
        {
            var evt    = new CountdownEvent(3);
            var driver = new CountdownDriver(evt);

            var bot = await SlackBot.InitializeAsync(driver, this.bus);

            await bot.SendAsync("test", "test", false, null);

            await bot.SendAsync("test", "test", false, null);

            await bot.SendAsync("test", "test", false, null);

            if (!evt.Wait(TimeSpan.FromSeconds(4)))
            {
                Assert.True(false, "3 messages were not recorded as being sent");
            }

            Assert.Equal(3, driver.RecordedTimings.Count);

            TimeSpan TimeBetween(int p1, int p2)
            => driver
            .RecordedTimings[Math.Max(p1, p2)]
            .Subtract(
                driver
                .RecordedTimings[Math.Min(p1, p2)]);

            Assert.True(TimeBetween(0, 1) > TimeSpan.FromSeconds(1));
            Assert.True(TimeBetween(1, 2) > TimeSpan.FromSeconds(1));
        }
示例#7
0
        public async Task InitializeAsync()
        {
            this.state  = SlackBotState.Initialize("1", "testbot");
            this.config = new TestConfig();

            this.driver = new TestDriver(this.state);
            this.bus    = new RxMessageBus();

            this.bot = await SlackBot.InitializeAsync(this.driver, this.bus);
        }
示例#8
0
    static async Task MainAsync()
    {
        var loggerFactory = new LoggerFactory();

        loggerFactory.AddProvider(new ConsoleLoggerProvider((s, level) => true, true));

        var bot = await SlackBot.InitializeAsync("token", cfg =>
        {
            cfg.LoggerFactory = loggerFactory;
        });
    }
示例#9
0
        public async Task <IActionResult> StanLeeBot(HttpRequest req)
        {
            var slackApiToken = Environment.GetEnvironmentVariable("SLACK_API_TOKEN", EnvironmentVariableTarget.Process);

            var bot = await SlackBot.InitializeAsync(slackApiToken);

            bot.When(Matches.Text("hello"), HubType.DirectMessage | HubType.Channel | HubType.Group, async conv =>
            {
                await conv.PostMessage($"Hi {conv.From.Username}!");
            });

            return(new OkResult());
        }
示例#10
0
        public async Task HubRemovedFromState_WhenBotLeavesHub(Func <IHubLeft> generator)
        {
            var bot = await SlackBot.InitializeAsync(this.driver, this.bus);

            var msg = generator();

            msg.Channel = Guid.NewGuid().ToString();

            this.state.AddHub(msg.Channel, msg.Channel, msg.HubType);

            bot.WaitForMessageToBeReceived <IHubLeft>(
                m => m.Channel == msg.Channel,
                () => this.bus.Publish(msg));

            Assert.Null(this.state.GetHubById(msg.Channel));
        }
示例#11
0
        public async Task HubAddedToState_WhenBotJoinsHub(Func <IHubJoined> generator)
        {
            var bot = await SlackBot.InitializeAsync(this.driver, this.bus);

            var msg = generator();

            msg.Channel = new Channel
            {
                Id   = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString()
            };

            bot.WaitForMessageToBeReceived <IHubJoined>(
                m => m.Channel.Id == msg.Channel.Id,
                () => this.bus.Publish(msg));

            var hub = this.state.GetHubById(msg.Channel.Id);

            Assert.NotNull(hub);

            Assert.Equal(hub.Id, msg.Channel.Id);
            Assert.Contains(msg.Channel.Name, hub.Name);
            Assert.Equal(hub.HubType, msg.HubType);
        }
示例#12
0
        public async Task MatchMode_AllMatches()
        {
            var bot = await SlackBot.InitializeAsync(this.driver, this.bus, cfg =>
            {
                cfg.WhenHandlerMatchMode = WhenHandlerMatchMode.AllMatches;
            });

            this.state.AddUser("1", "user");
            this.state.AddHub("1", "test hub", HubType.DirectMessage);

            var evt = new CountdownEvent(2);

            bot.When(Matches.Text("test"), cv =>
            {
                evt.Signal();
                return(Task.CompletedTask);
            });

            bot.When(Matches.Text("test"), cv =>
            {
                evt.Signal();
                return(Task.CompletedTask);
            });

            this.bus.Publish(new Message
            {
                Channel = "1",
                User    = "******",
                Text    = "test"
            });

            if (!evt.Wait(100))
            {
                Assert.True(false, "Both handlers were not fired");
            }
        }
示例#13
0
        public async Task MatchMode_FirstMatch()
        {
            var bot = await SlackBot.InitializeAsync(this.driver, this.bus, cfg =>
            {
                cfg.WhenHandlerMatchMode = WhenHandlerMatchMode.FirstMatch;
            });

            this.state.AddUser("1", "user");
            this.state.AddHub("1", "test hub", HubType.DirectMessage);

            var evt = new AutoResetEvent(false);

            bot.When(Matches.Text("test"), cv =>
            {
                evt.Set();
                return(Task.CompletedTask);
            });

            bot.When(Matches.Text("test"), cv =>
            {
                Assert.True(false, "Second handler should not be fired");
                return(Task.CompletedTask);
            });

            this.bus.Publish(new Message
            {
                Channel = "1",
                User    = "******",
                Text    = "test"
            });

            if (!evt.WaitOne(100))
            {
                Assert.True(false, "First handler never fired");
            }
        }
示例#14
0
        public async Task MatchMode_BestMatch()
        {
            var bot = await SlackBot.InitializeAsync(this.driver, this.bus, cfg =>
            {
                cfg.WhenHandlerMatchMode = WhenHandlerMatchMode.BestMatch;
            });

            this.state.AddUser("1", "user");
            this.state.AddHub("1", "test hub", HubType.DirectMessage);

            var evt = new AutoResetEvent(false);

            bot.When(new FixedScoreMatcher(1), cv =>
            {
                Assert.True(false, "Low score handler should not have been fired");
                return(Task.CompletedTask);
            });

            bot.When(new FixedScoreMatcher(2), cv =>
            {
                evt.Set();
                return(Task.CompletedTask);
            });

            this.bus.Publish(new Message
            {
                Channel = "1",
                User    = "******",
                Text    = "test"
            });

            if (!evt.WaitOne(100))
            {
                Assert.True(false, "High score handler was not fired");
            }
        }
示例#15
0
        public async Task OutgoingMessages_LimitedToOnePerSecond()
        {
            var evt    = new CountdownEvent(3);
            var driver = new CountdownDriver(evt);

            var bot = await SlackBot.InitializeAsync(driver, this.bus);

            await bot.SendAsync("test", "test", false, null);

            await bot.SendAsync("test", "test", false, null);

            await bot.SendAsync("test", "test", false, null);

            if (!evt.Wait(TimeSpan.FromSeconds(6)))
            {
                Assert.True(false, "3 messages were not recorded as being sent");
            }

            Assert.Equal(3, driver.RecordedTimings.Count);

            TimeSpan TimeBetween(int p1, int p2)
            => driver
            .RecordedTimings[Math.Max(p1, p2)]
            .Subtract(
                driver
                .RecordedTimings[Math.Min(p1, p2)]);

            var first  = TimeBetween(0, 1);
            var second = TimeBetween(1, 2);

            // allow some wiggle room with timing
            var measure = TimeSpan.FromSeconds(0.92);

            Assert.True(TimeBetween(0, 1) >= measure, $"Expected {first} >= {measure}");
            Assert.True(TimeBetween(1, 2) >= measure, $"Expected {second} >= {measure}");
        }
示例#16
0
        private async Task StanLeeBotWork()
        {
            while (!_stopping)
            {
                _logger.LogInformation("StanLee getting connected!");

                var bot = await SlackBot.InitializeAsync(_appSettings.Slack.ApiToken,
                                                         cfg =>
                {
                    cfg.LoggerFactory        = _loggerFactory;
                    cfg.WhenHandlerMatchMode = WhenHandlerMatchMode.FirstMatch;

                    cfg.OnSendMessageFailure = async(queue, msg, logger, e) =>
                    {
                        if (msg.SendAttempts <= 5)
                        {
                            logger?.LogWarning($"Failed to send message {msg.Text}. Tried {msg.SendAttempts} times");
                            await Task.Delay(1000 * msg.SendAttempts);
                            queue.Enqueue(msg);
                            return;
                        }

                        logger?.LogError($"Gave up trying to send message {msg.Text}");
                    };
                    _stopping = true;
                });

                bot.When(MatchFactory.Matches.Text("hello"), async conv =>
                {
                    await conv.PostMessage("Hi!");
                })
                .OnException((msg, ex) =>
                {
                    _logger.LogError(ex, $"Stan Lee had an error! It's {ex}");
                });

                bot.When(MatchFactory.Matches.Text("whois"), async conv =>
                {
                    const string toBeSearched = "whois";
                    var marvelCharacterStr    = conv.Text.StripAscii()
                                                .Substring(conv.Text.IndexOf(toBeSearched, StringComparison.Ordinal) + toBeSearched.Length)
                                                .TrimPunctuation()
                                                .Trim();

                    _logger.LogInformation($"Request by  {conv.From.Username}");

                    var marvelCharacter = await _marvelService.GetCharacter(marvelCharacterStr);

                    var response = string.Empty;

                    if (marvelCharacter != null)
                    {
                        _logger.LogInformation($"Found information for {marvelCharacterStr}. Marvel Character ID: {marvelCharacter.Id}");

                        response  = $"Excelsior! I found {marvelCharacter.Name} :star-struck:! {marvelCharacter.Description}.{Environment.NewLine}{Environment.NewLine}";
                        response += $"{Environment.NewLine}{Environment.NewLine}";
                        response += $"{marvelCharacter.Name} has appeared in {marvelCharacter.Comics.Available} comics!";
                        response += $"{Environment.NewLine}{Environment.NewLine}";
                        response += $"Learn more here: {marvelCharacter.Urls.FirstOrDefault(x => x.Type == "detail")?.Value ?? "... or not."}";
                    }
                    else
                    {
                        _logger.LogInformation($"Character not found: {marvelCharacterStr}.");

                        response = $"I wasn't able to find anything about {marvelCharacterStr}...";
                    }

                    _logger.LogInformation($"Sending information to Slack for {marvelCharacterStr} to {conv.From.Username}.");

                    await conv.PostMessage(response);
                })
                .OnException((msg, ex) =>
                {
                    _logger.LogError(ex, $"Stan Lee had an error! It's {ex}");
                });
            }

            _logger.LogInformation("StanLeeBot is stopping");
        }