Skip to content

Commit

Permalink
Feature: Ignore messages containing matching text (qaisjp#92)
Browse files Browse the repository at this point in the history
This feature allows for when a message matches from Discord towards IRC
or the other way around for the matching message to be dropped
(filtered).

lets say there is an urban dictionary bot on xyz side of the bridge. Now it also does other useful things, but we know that urban dictionary can be floody for say "the longest definition on urbandictionary" query. Luck has it that whoever made the bot decided each line of urban dictionary related output should be prefixed "[ud]" so we can filter on this and keep the remainder of useful things. It also conveniently works for ignoring users that are behind a relay when a channel runs multiple kinds of relays
  • Loading branch information
llmII authored Mar 4, 2021
1 parent d7d9a07 commit e120d9a
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 39 deletions.
56 changes: 29 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,33 +66,35 @@ The binary takes three flags:

The config file is a yaml formatted file with the following fields:

| name | requires restart | default | optional | description |
| -------------------------------| ---------------- | ---------------------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `avatar_url` | No | `https://ui-avatars.com/api/?name=${USERNAME}` | Yes | The URL for the API to use to tell Discord what Avatar to use for a User when the user's avatar cannot be found at Discord already. |
| `discord_token` | Yes | | No | [The bot user token](https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token) |
| `irc_server` | Yes | | No | IRC server address |
| `irc_server_name` | Yes | | No | Used as a reference when PMing from Discord to IRC. Try to use short, simple one-word names like `freenode` or `swift` |
| `channel_mappings` | No | | No | a dict with irc channel as key (prefixed with `#`) and Discord channel ID as value |
| `guild_id` | No | | No | the Discord guild (server) id |
| `irc_pass` | Yes | | Yes | password for connecting to the IRC server |
| `suffix` | No | `~d` | Yes | appended to each Discord user's nickname when they are connected to IRC. If set to `_d2`, if the name will be `bob_d2` |
| `separator` | No | `_` | Yes | used in fallback situations. If set to `-`, the **fallback name** will be like `bob-7247_d2` (where `7247` is the discord user's discriminator, and `_d2` is the suffix) |
| `irc_listener_name` | Yes | `~d` | The name of the irc listener | |
| `ignored_discord_ids` | Sometimes | | Yes | A list of Discord IDs to not relay to IRC |
| `puppet_username` | No | username of discord account being puppeted | Yes | username to connect to irc with |
| `webirc_pass` | No | | Yes | optional, but recommended for regular (non-simple) usage. this must be obtained by the IRC sysops |
| `irc_listener_prejoin_commands`| Yes | | Yes | list of commands for the listener IRC connection to execute (right before joining channels) |
| `irc_puppet_prejoin_commands` | Yes | | Yes | list of commands for each Puppet IRC connection to execute (right before joining channels) |
| `debug` | Yes | false | Yes | debug mode |
| `insecure`, | Yes | false | Yes | TLS will skip verification (but still uses TLS) |
| `no_tls`, | Yes | false | Yes | turns off TLS |
| `webhook_prefix`, | Yes | | No | a prefix for webhooks, so we know which ones to keep and which ones to delete |
| `nickserv_identify` | No | | Yes | on connect this message will be sent: `PRIVMSG nickserv IDENTIFY <value>`, you can provide both a username and password if your ircd supports it |
| `cooldown_duration` | No | 86400 (24 hours) | Yes | time in seconds for a discord user to be offline before it's puppet disconnects from irc |
| `show_joinquit` | No | false | yes | displays JOIN, PART, QUIT, KICK on discord |
| `max_nick_length` | No | 30 | yes | Maximum allowed nick length |
| `ignored_irc_hostmasks` | No | | Yes | A list of IRC users identified by hostmask to not relay to Discord, uses matching syntax as in [glob](https://github.com/gobwas/glob) |
| `connection_limit` | Yes | 0 | Yes | How many connections to IRC (including our listener) to spawn (limit of 0 or less means unlimited) |
| name | requires restart | default | optional | description |
| ------------------------------- | ---------------- | ---------------------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `avatar_url` | No | `https://ui-avatars.com/api/?name=${USERNAME}` | Yes | The URL for the API to use to tell Discord what Avatar to use for a User when the user's avatar cannot be found at Discord already. |
| `discord_token` | Yes | | No | [The bot user token](https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token) |
| `discord_message_filter` | No | | Yes | Filters messages from Discord to IRC when they match. |
| `irc_message_filter` | No | | Yes | Filters messages from IRC to Discord when they match. |
| `irc_server` | Yes | | No | IRC server address |
| `irc_server_name` | Yes | | No | Used as a reference when PMing from Discord to IRC. Try to use short, simple one-word names like `freenode` or `swift` |
| `channel_mappings` | No | | No | a dict with irc channel as key (prefixed with `#`) and Discord channel ID as value |
| `guild_id` | No | | No | the Discord guild (server) id |
| `irc_pass` | Yes | | Yes | password for connecting to the IRC server |
| `suffix` | No | `~d` | Yes | appended to each Discord user's nickname when they are connected to IRC. If set to `_d2`, if the name will be `bob_d2` |
| `separator` | No | `_` | Yes | used in fallback situations. If set to `-`, the **fallback name** will be like `bob-7247_d2` (where `7247` is the discord user's discriminator, and `_d2` is the suffix) |
| `irc_listener_name` | Yes | `~d` | The name of the irc listener | |
| `ignored_discord_ids` | Sometimes | | Yes | A list of Discord IDs to not relay to IRC |
| `puppet_username` | No | username of discord account being puppeted | Yes | username to connect to irc with |
| `webirc_pass` | No | | Yes | optional, but recommended for regular (non-simple) usage. this must be obtained by the IRC sysops |
| `irc_listener_prejoin_commands` | Yes | | Yes | list of commands for the listener IRC connection to execute (right before joining channels) |
| `irc_puppet_prejoin_commands` | Yes | | Yes | list of commands for each Puppet IRC connection to execute (right before joining channels) |
| `debug` | Yes | false | Yes | debug mode |
| `insecure`, | Yes | false | Yes | TLS will skip verification (but still uses TLS) |
| `no_tls`, | Yes | false | Yes | turns off TLS |
| `webhook_prefix`, | Yes | | No | a prefix for webhooks, so we know which ones to keep and which ones to delete |
| `nickserv_identify` | No | | Yes | on connect this message will be sent: `PRIVMSG nickserv IDENTIFY <value>`, you can provide both a username and password if your ircd supports it |
| `cooldown_duration` | No | 86400 (24 hours) | Yes | time in seconds for a discord user to be offline before it's puppet disconnects from irc |
| `show_joinquit` | No | false | yes | displays JOIN, PART, QUIT, KICK on discord |
| `max_nick_length` | No | 30 | yes | Maximum allowed nick length |
| `ignored_irc_hostmasks` | No | | Yes | A list of IRC users identified by hostmask to not relay to Discord, uses matching syntax as in [glob](https://github.com/gobwas/glob) |
| `connection_limit` | Yes | 0 | Yes | How many connections to IRC (including our listener) to spawn (limit of 0 or less means unlimited) |

**The filename.yaml file is continuously read from and many changes will
automatically update on the bridge. This means you can add or remove channels
Expand Down
4 changes: 4 additions & 0 deletions bridge/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ type Config struct {
IRCPuppetPrejoinCommands []string
IRCListenerPrejoinCommands []string

// filters
IRCFilteredMessages []glob.Glob
DiscordFilteredMessages []glob.Glob

// NoTLS constrols whether to use TLS at all when connecting to the IRC server
NoTLS bool

Expand Down
16 changes: 4 additions & 12 deletions bridge/irc_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,18 +218,10 @@ func (i *ircListener) OnPrivateMessage(e *irc.Event) {
return
}

// Discord doesn't accept an empty message
if strings.TrimSpace(e.Message()) == "" {
return
}

// Ignore messages from Discord bots
if i.isPuppetNick(e.Nick) {
return
}

// Ignored hostmasks
if i.bridge.ircManager.isIgnoredHostmask(e.Source) {
if strings.TrimSpace(e.Message()) == "" || // Discord doesn't accept an empty message
i.isPuppetNick(e.Nick) || // ignore msg's from our puppets
i.bridge.ircManager.isIgnoredHostmask(e.Source) || //ignored hostmasks
i.bridge.ircManager.isFilteredIRCMessage(e.Message()) { // filtered
return
}

Expand Down
22 changes: 22 additions & 0 deletions bridge/irc_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,10 @@ func (m *IRCManager) SendMessage(channel string, msg *DiscordMessage) {
ircMessage.Message = line[4:]
}

if m.isFilteredDiscordMessage(line) {
continue
}

select {
// Try to send the message immediately
case con.messages <- ircMessage:
Expand Down Expand Up @@ -440,6 +444,24 @@ func (m *IRCManager) isIgnoredHostmask(mask string) bool {
return false
}

func (m *IRCManager) isFilteredIRCMessage(txt string) bool {
for _, ban := range m.bridge.Config.IRCFilteredMessages {
if ban.Match(txt) {
return true
}
}
return false
}

func (m *IRCManager) isFilteredDiscordMessage(txt string) bool {
for _, ban := range m.bridge.Config.DiscordFilteredMessages {
if ban.Match(txt) {
return true
}
}
return false
}

func (m *IRCManager) generateUsername(discordUser DiscordUser) string {
if len(m.bridge.Config.PuppetUsername) > 0 {
return m.bridge.Config.PuppetUsername
Expand Down
Loading

0 comments on commit e120d9a

Please sign in to comment.