Skip to content

Commit

Permalink
Make responses trigger when the current user name appears in chat text.
Browse files Browse the repository at this point in the history
At the moment, the bot is hardcoded to respond when it detects the string
"Derpy" in a text channel. This is suboptimal, as server administrators may
wish to change the name to something else. To improve usability, make
responses trigger on detection of the bot's displayed user name instead.

This will fix #7.
  • Loading branch information
rarcher committed Apr 10, 2018
1 parent 4fb9633 commit 4413438
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 14 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Derpy Bot

Derpy is a simple chatbot for Discord. She replies whenever someone says her name in a channel she can access, using
Markov chains to generate novel responses from old chat logs. When deployed in a channel with a substantial chat
Derpy is a simple chatbot for Discord. She replies whenever someone says her user name in a channel she can access,
using Markov chains to generate novel responses from old chat logs. When deployed in a channel with a substantial chat
history, her responses can get *quite* amusing.

## Running the Bot
Expand Down
14 changes: 7 additions & 7 deletions src.java/codes/soloware/derpybot/ChatResponder.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package codes.soloware.derpybot;

import java.util.Random;
import java.util.regex.Pattern;

import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.core.hooks.EventListener;
Expand All @@ -29,18 +30,14 @@ public class ChatResponder extends ListenerAdapter
{
private static final float randomResponseChance=0.01f;
private final Random randomNumbers;
private final String responseTrigger;
private final TextGenerator responseGenerator;

public ChatResponder(final String responseTrigger, final TextGenerator responseGenerator)
public ChatResponder(final TextGenerator responseGenerator)
{
if (responseTrigger==null)
throw new NullPointerException("Given response trigger keyword is null.");
if (responseGenerator==null)
throw new NullPointerException("Given response generator implementation is null.");
this.randomNumbers=new Random();
this.randomNumbers.setSeed(System.currentTimeMillis());
this.responseTrigger=responseTrigger;
this.responseGenerator=responseGenerator;
}

Expand All @@ -49,8 +46,11 @@ public void onGuildMessageReceived(final GuildMessageReceivedEvent event)
{
if (event.getAuthor().equals(event.getJDA().getSelfUser()))
return;
if (event.getChannel().canTalk()&&(event.getMessage().getContentDisplay().contains(responseTrigger)||
(randomNumbers.nextFloat()<=randomResponseChance)))
if (event.getChannel().canTalk()&&((randomNumbers.nextFloat()<=randomResponseChance)||
(Pattern.compile(
Pattern.quote(event.getGuild().getMember(event.getJDA().getSelfUser()).getEffectiveName()),
Pattern.CASE_INSENSITIVE)
.matcher(event.getMessage().getContentDisplay()).find())))
{
event.getChannel().sendMessage(responseGenerator.respond(event.getMessage().getContentDisplay())).complete();
}
Expand Down
2 changes: 1 addition & 1 deletion src.java/codes/soloware/derpybot/Derpy.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static void main(final String[] args)
{
final JDABuilder builder=new JDABuilder(AccountType.BOT);
final TextGenerator engine=new LinkIgnoringTextGenerator(new EmoteIgnoringTextGenerator(new MarkovChain()));
builder.addEventListener(new ChatResponder("Derpy", engine));
builder.addEventListener(new ChatResponder(engine));
builder.addEventListener(new NewMemberGreeter());
builder.addEventListener(new LeavingMemberFarewellGenerator());

Expand Down
23 changes: 19 additions & 4 deletions test.java/codes/soloware/derpybot/ChatResponderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.entities.SelfUser;
import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.User;
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
Expand All @@ -37,13 +40,16 @@
@RunWith(MockitoJUnitRunner.StrictStubs.class)
public class ChatResponderTest
{
private static final String testResponseTrigger=" should ";
private static final String selfEffectiveName=" should ";
private static final String responseTriggeringMockMessageContent="The testee should respond to this.";
private static final String nonResponseTriggeringMockMessageContent="The testee shouldn't respond to this.";
private static final String mockResponse="This is the response string.";
private Message mockMessage;
private MessageAction mockMessageAction;
private User mockAuthor;
private SelfUser mockSelfUser;
private Member mockSelfMember;
private Guild mockGuild;
private TextChannel mockChannel;
private JDA mockJDA;
private GuildMessageReceivedEvent mockEvent;
Expand All @@ -59,17 +65,26 @@ public void setup()

mockAuthor=Mockito.mock(User.class);

mockSelfUser=Mockito.mock(SelfUser.class);

mockSelfMember=Mockito.mock(Member.class);
Mockito.when(mockSelfMember.getEffectiveName()).thenReturn(selfEffectiveName);

mockGuild=Mockito.mock(Guild.class);
Mockito.when(mockGuild.getMember(mockSelfUser)).thenReturn(mockSelfMember);

mockChannel=Mockito.mock(TextChannel.class);
Mockito.when(mockChannel.canTalk()).thenReturn(true);
Mockito.when(mockChannel.sendMessage(ArgumentMatchers.anyString())).thenReturn(mockMessageAction);

mockJDA=Mockito.mock(JDA.class);
Mockito.when(mockJDA.getAccountType()).thenReturn(AccountType.BOT);
Mockito.when(mockJDA.getSelfUser()).thenReturn(null);
Mockito.when(mockJDA.getSelfUser()).thenReturn(mockSelfUser);

mockEvent=Mockito.mock(GuildMessageReceivedEvent.class);
Mockito.when(mockEvent.getMessage()).thenReturn(mockMessage);
Mockito.when(mockEvent.getAuthor()).thenReturn(mockAuthor);
Mockito.when(mockEvent.getGuild()).thenReturn(mockGuild);
Mockito.when(mockEvent.getChannel()).thenReturn(mockChannel);
Mockito.when(mockEvent.getJDA()).thenReturn(mockJDA);

Expand All @@ -82,7 +97,7 @@ public void listen()
{
Mockito.when(mockMessage.getContentDisplay()).thenReturn(nonResponseTriggeringMockMessageContent);

new ChatResponder(testResponseTrigger, mockGenerator).onEvent(mockEvent);
new ChatResponder(mockGenerator).onEvent(mockEvent);
Mockito.verify(mockGenerator).listen(nonResponseTriggeringMockMessageContent);
}

Expand All @@ -91,7 +106,7 @@ public void respond()
{
Mockito.when(mockMessage.getContentDisplay()).thenReturn(responseTriggeringMockMessageContent);

new ChatResponder(testResponseTrigger, mockGenerator).onEvent(mockEvent);
new ChatResponder(mockGenerator).onEvent(mockEvent);
Mockito.verify(mockGenerator).respond(responseTriggeringMockMessageContent);
Mockito.verify(mockChannel).sendMessage(mockResponse);
}
Expand Down

0 comments on commit 4413438

Please sign in to comment.