Merge pull request 'ImplMessageMonitor' (#1) from ImplMessageMonitor into main
Reviewed-on: #1
This commit is contained in:
commit
f7550228b7
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
config.toml
|
29
README.md
29
README.md
@ -0,0 +1,29 @@
|
|||||||
|
# Discord Regex Monitor
|
||||||
|
|
||||||
|
### Example Config
|
||||||
|
```toml
|
||||||
|
[DISCORD]
|
||||||
|
BOT_TOKEN = ""
|
||||||
|
|
||||||
|
[[SERVERS]]
|
||||||
|
SERVER_ID = "1050204101826334999"
|
||||||
|
OUTPUT_CHANNEL_ID = "1250585834726621999"
|
||||||
|
PREFIX_ENABLED = true
|
||||||
|
ALLOW_DUPLICATES = false
|
||||||
|
[SERVERS.COIN_REGEXES]
|
||||||
|
Bitcoin = "[13][a-km-zA-HJ-NP-Z1-9]{25,34}"
|
||||||
|
Ethereum = "0x[a-fA-F0-9]{40}"
|
||||||
|
[SERVERS.CHANNEL_BLACKLIST]
|
||||||
|
CHANNELS = ["1250537334550827078"]
|
||||||
|
|
||||||
|
[[SERVERS]]
|
||||||
|
SERVER_ID = "1250885747062345999"
|
||||||
|
OUTPUT_CHANNEL_ID = "1250585834726621999"
|
||||||
|
PREFIX_ENABLED = true
|
||||||
|
ALLOW_DUPLICATES = false
|
||||||
|
[SERVERS.COIN_REGEXES]
|
||||||
|
Ethereum = "0x[a-fA-F0-9]{40}"
|
||||||
|
Solana = "[1-9A-HJ-NP-Za-km-z]{32,44}"
|
||||||
|
[SERVERS.CHANNEL_BLACKLIST]
|
||||||
|
CHANNELS = []
|
||||||
|
```
|
24
config.toml.example
Normal file
24
config.toml.example
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[DISCORD]
|
||||||
|
BOT_TOKEN = ""
|
||||||
|
|
||||||
|
[[SERVERS]]
|
||||||
|
SERVER_ID = ""
|
||||||
|
OUTPUT_CHANNEL_ID = ""
|
||||||
|
PREFIX_ENABLED = true
|
||||||
|
[SERVERS.COIN_REGEXES]
|
||||||
|
Bitcoin = "[13][a-km-zA-HJ-NP-Z1-9]{25,34}"
|
||||||
|
Ethereum = "0x[a-fA-F0-9]{40}"
|
||||||
|
[SERVERS.CHANNEL_BLACKLIST]
|
||||||
|
CHANNELS = [""]
|
||||||
|
|
||||||
|
[[SERVERS]]
|
||||||
|
SERVER_ID = ""
|
||||||
|
OUTPUT_CHANNEL_ID = ""
|
||||||
|
PREFIX_ENABLED = false
|
||||||
|
[SERVERS.COIN_REGEXES]
|
||||||
|
Ethereum = "0x[a-fA-F0-9]{40}"
|
||||||
|
Solana = "[1-9A-HJ-NP-Za-km-z]{32,44}"
|
||||||
|
[SERVERS.CHANNEL_BLACKLIST]
|
||||||
|
CHANNELS = []
|
||||||
|
|
||||||
|
|
6
go.mod
6
go.mod
@ -2,7 +2,11 @@ module git.directme.in/Joren/SolMonitor
|
|||||||
|
|
||||||
go 1.22.4
|
go 1.22.4
|
||||||
|
|
||||||
require github.com/bwmarrin/discordgo v0.28.1
|
require (
|
||||||
|
git.directme.in/Joren/SmsHook v1.0.2
|
||||||
|
github.com/BurntSushi/toml v1.4.0
|
||||||
|
github.com/bwmarrin/discordgo v0.28.1
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gorilla/websocket v1.4.2 // indirect
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
|
139
main.go
139
main.go
@ -3,19 +3,66 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
|
"git.directme.in/Joren/SmsHook/ringbuffer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Token string
|
Token string
|
||||||
|
Servers []ServerConfig
|
||||||
|
CoinRegexes map[string]*regexp.Regexp
|
||||||
|
ChannelBlacklist map[string][]string
|
||||||
|
MessageHistory map[string]*ringbuffer.RingBuffer
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ServerConfig struct {
|
||||||
|
ServerID string `toml:"SERVER_ID"`
|
||||||
|
OutputChannelID string `toml:"OUTPUT_CHANNEL_ID"`
|
||||||
|
CoinRegexes map[string]string `toml:"COIN_REGEXES"`
|
||||||
|
ChannelBlacklist struct {
|
||||||
|
Channels []string `toml:"CHANNELS"`
|
||||||
|
} `toml:"CHANNEL_BLACKLIST"`
|
||||||
|
PrefixEnabled bool `toml:"PREFIX_ENABLED"`
|
||||||
|
AllowDuplicates bool `toml:"ALLOW_DUPLICATES"`
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Token = os.Getenv("DISCORD_BOT_TOKEN")
|
var config struct {
|
||||||
|
Discord struct {
|
||||||
|
BotToken string `toml:"BOT_TOKEN"`
|
||||||
|
} `toml:"DISCORD"`
|
||||||
|
Servers []ServerConfig `toml:"SERVERS"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := toml.DecodeFile("config.toml", &config); err != nil {
|
||||||
|
fmt.Println("Error loading config:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
Token = config.Discord.BotToken
|
||||||
|
Servers = config.Servers
|
||||||
|
|
||||||
|
CoinRegexes = make(map[string]*regexp.Regexp)
|
||||||
|
ChannelBlacklist = make(map[string][]string)
|
||||||
|
MessageHistory = make(map[string]*ringbuffer.RingBuffer)
|
||||||
|
|
||||||
|
for _, server := range Servers {
|
||||||
|
for coin, regex := range server.CoinRegexes {
|
||||||
|
fullRegex := fmt.Sprintf(`\b%s\b`, regex)
|
||||||
|
CoinRegexes[coin] = regexp.MustCompile(fullRegex)
|
||||||
|
}
|
||||||
|
ChannelBlacklist[server.ServerID] = server.ChannelBlacklist.Channels
|
||||||
|
|
||||||
|
MessageHistory[server.ServerID] = ringbuffer.NewRingBuffer(4096)
|
||||||
|
}
|
||||||
|
|
||||||
if Token == "" {
|
if Token == "" {
|
||||||
fmt.Println("No token provided. Please set DISCORD_BOT_TOKEN environment variable.")
|
fmt.Println("No token provided in config.toml.")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,8 +75,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dg.AddHandler(ready)
|
dg.AddHandler(ready)
|
||||||
|
dg.AddHandler(messageCreate)
|
||||||
|
|
||||||
dg.Identify.Intents = discordgo.IntentsGuilds | discordgo.IntentsGuildMessages
|
dg.Identify.Intents = discordgo.IntentsGuilds | discordgo.IntentsGuildMessages | discordgo.IntentMessageContent
|
||||||
|
|
||||||
err = dg.Open()
|
err = dg.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -42,6 +90,89 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ready(s *discordgo.Session, event *discordgo.Ready) {
|
func ready(s *discordgo.Session, event *discordgo.Ready) {
|
||||||
s.UpdateGameStatus(0, "Monitoring addresses")
|
s.UpdateGameStatus(0, "Monitoring messages")
|
||||||
|
}
|
||||||
|
|
||||||
|
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||||
|
if m.Author.ID == s.State.User.ID {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, server := range Servers {
|
||||||
|
if m.GuildID == server.ServerID {
|
||||||
|
channel, err := s.State.Channel(m.ChannelID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error getting channel:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if isChannelBlacklisted(server.ServerID, channel.ID) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
checkMessageContent(s, server, m)
|
||||||
|
checkEmbeds(s, server, m)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkMessageContent(s *discordgo.Session, server ServerConfig, m *discordgo.MessageCreate) {
|
||||||
|
for coin, regex := range CoinRegexes {
|
||||||
|
match := regex.FindStringSubmatch(m.Content)
|
||||||
|
if len(match) > 0 {
|
||||||
|
matchedAddress := match[0]
|
||||||
|
message := formatMessage(server, coin, m.Author.Username, matchedAddress)
|
||||||
|
|
||||||
|
if !server.AllowDuplicates && MessageHistory[server.ServerID].ContainsItem(message) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.ChannelMessageSend(server.OutputChannelID, message)
|
||||||
|
MessageHistory[server.ServerID].Add(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkEmbeds(s *discordgo.Session, server ServerConfig, m *discordgo.MessageCreate) {
|
||||||
|
for _, embed := range m.Message.Embeds {
|
||||||
|
if embed.Type == "rich" && embed.Description != "" {
|
||||||
|
for coin, regex := range CoinRegexes {
|
||||||
|
match := regex.FindStringSubmatch(embed.Description)
|
||||||
|
if len(match) > 0 {
|
||||||
|
matchedAddress := match[0]
|
||||||
|
message := formatMessage(server, coin, m.Author.Username, matchedAddress)
|
||||||
|
|
||||||
|
if !server.AllowDuplicates && MessageHistory[server.ServerID].ContainsItem(message) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.ChannelMessageSend(server.OutputChannelID, message)
|
||||||
|
MessageHistory[server.ServerID].Add(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatMessage(server ServerConfig, coin, username, address string) string {
|
||||||
|
if server.PrefixEnabled {
|
||||||
|
return fmt.Sprintf("%s: %s", coin, address)
|
||||||
|
}
|
||||||
|
return address
|
||||||
|
}
|
||||||
|
|
||||||
|
func isChannelBlacklisted(serverID, channelID string) bool {
|
||||||
|
blacklistedChannels, ok := ChannelBlacklist[serverID]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, id := range blacklistedChannels {
|
||||||
|
if id == channelID {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user