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"); } }
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"); } }
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"); } }
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"); } }
async Task InitBotAsync(string token, LoggerFactory loggerFactory) { _bot = await SlackBot.InitializeAsync(token, config => { config.LoggerFactory = loggerFactory; config.OnSendMessageFailure = OnSendMessageFailure; }); }
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)); }
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); }
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; }); }
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()); }
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)); }
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); }
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"); } }
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"); } }
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"); } }
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}"); }
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"); }