From e8f52ce6381794f68eee9a5ed900ba6441d72798 Mon Sep 17 00:00:00 2001 From: gempir Date: Sun, 5 Mar 2017 16:26:24 +0100 Subject: [PATCH] redis client, first step of message parsing --- .gitignore | 3 +- config.example.json | 9 ++++ glide.yaml | 2 + main.go | 22 ++++++-- twitch/bot.go | 119 ++++++++++++++++++++++++++++++++++++++++++++ twitch/message.go | 15 ++++++ twitch/user.go | 18 +++++++ 7 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 config.example.json create mode 100644 twitch/bot.go create mode 100644 twitch/message.go create mode 100644 twitch/user.go diff --git a/.gitignore b/.gitignore index 874b087..1835df8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ gempbotgo vendor/ glide.lock -.idea/ \ No newline at end of file +.idea/ +config.json \ No newline at end of file diff --git a/config.example.json b/config.example.json new file mode 100644 index 0000000..5142619 --- /dev/null +++ b/config.example.json @@ -0,0 +1,9 @@ +{ + "irc_address": "irc.chat.twitch.tv:6667", + "irc_user": "gempbot", + "irc_token": "oauth:123123123", + "api_port": "8025", + "redis_address": "127.0.0.1:6379", + "redis_password": "asdasd", + "redis_database": 0 +} \ No newline at end of file diff --git a/glide.yaml b/glide.yaml index a44be57..1857108 100644 --- a/glide.yaml +++ b/glide.yaml @@ -2,3 +2,5 @@ package: github.com/gempir/gempbotgo import: - package: github.com/op/go-logging version: ^1.0.0 +- package: gopkg.in/redis.v5 + version: ^5.2.9 diff --git a/main.go b/main.go index c6d8e21..66310f0 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,8 @@ import ( "os" "github.com/op/go-logging" + "github.com/gempir/gempbotgo/twitch" + "gopkg.in/redis.v3" ) var ( @@ -15,9 +17,13 @@ var ( ) type config struct { - IrcAddress string `json:"irc_address"` - BrokerPass string `json:"broker_pass"` - APIPort string `json:"api_port"` + IrcAddress string `json:"irc_address"` + IrcUser string `json:"irc_user"` + IrcToken string `json:"irc_token"` + APIPort string `json:"api_port"` + RedisAddress string `json:"redis_address"` + RedisPassword string `json:"redis_password"` + RedisDatabase int64 `json:"redis_database"` } func main() { @@ -28,6 +34,14 @@ func main() { Log.Fatal(err) } + rClient := redis.NewClient(&redis.Options{ + Addr: cfg.RedisAddress, + Password: cfg.RedisPassword, + DB: cfg.RedisDatabase, + }) + + bot := twitch.NewBot(cfg.IrcAddress, cfg.IrcUser, cfg.IrcToken, Log, *rClient) + bot.CreateConnection() } func initLogger() logging.Logger { @@ -36,7 +50,7 @@ func initLogger() logging.Logger { backend := logging.NewLogBackend(os.Stdout, "", 0) format := logging.MustStringFormatter( - `%{color}%{time:2006-01-02 15:04:05.000} %{shortfile:-15s} %{level:.4s}%{color:reset} %{message}`, + `%{color}%{time:2006-01-02 15:04:05.000} %{level:.4s}%{color:reset} %{message}`, ) logging.SetFormatter(format) backendLeveled := logging.AddModuleLevel(backend) diff --git a/twitch/bot.go b/twitch/bot.go new file mode 100644 index 0000000..5995a07 --- /dev/null +++ b/twitch/bot.go @@ -0,0 +1,119 @@ +package twitch + +import ( + "bufio" + "fmt" + "github.com/op/go-logging" + "net" + "net/textproto" + "regexp" + "strings" + "gopkg.in/redis.v3" +) + +type bot struct { + messages chan message + ircAddress string + ircUser string + ircToken string + log logging.Logger + rClient redis.Client +} + +var ( + mainConn *net.Conn + userReg = regexp.MustCompile(`:\w+!\w+@\w+\.tmi\.twitch\.tv`) + channelReg = regexp.MustCompile(`#\w+\s:`) + actionReg = regexp.MustCompile(`^\x{0001}ACTION\s`) + actionReg2 = regexp.MustCompile(`([\x{0001}]+)`) +) + +func NewBot(ircAddress string, ircUser string, ircToken string, logger logging.Logger, rClient redis.Client) bot { + return bot{ + messages: make(chan message), + ircAddress: ircAddress, + ircUser: ircUser, + ircToken: ircToken, + log: logger, + rClient: rClient, + } +} + +func (bot *bot) CreateConnection() { + conn, err := net.Dial("tcp", bot.ircAddress) + mainConn = &conn + if err != nil { + bot.log.Error(err.Error()) + return + } + bot.log.Debugf("new connection %s", conn.RemoteAddr()) + fmt.Fprintf(conn, "PASS %s\r\n", bot.ircToken) + fmt.Fprintf(conn, "NICK %s\r\n", bot.ircUser) + fmt.Fprintf(conn, "JOIN %s\r\n", "#" + bot.ircUser) + bot.log.Debugf("PASS %s\r\n", bot.ircToken) + go bot.joinDefault() + + reader := bufio.NewReader(conn) + tp := textproto.NewReader(reader) + for { + line, err := tp.ReadLine() + if err != nil { + bot.log.Error(err.Error()) + break + } + messages := strings.Split(line, "\r\n") + if len(messages) == 0 { + continue + } + for _, msg := range messages { + go bot.parseMessage(msg) + } + } + defer bot.CreateConnection() +} + +func (bot *bot) joinDefault() { + val, err := bot.rClient.HGetAll("channels").Result() + if err != nil { + bot.log.Error(err.Error()) + } + for _, element := range val { + if element == "1" || element == "0" { + continue + } + go bot.join(element) + } +} + +func (bot *bot) parseMessage(msg string) { + bot.log.Debug(msg) + + if !strings.Contains(msg, ".tmi.twitch.tv PRIVMSG ") { + return + } + + fullUser := userReg.FindString(msg) + userIrc := strings.Split(fullUser, "!") + username := userIrc[0][1:len(userIrc[0])] + split2 := strings.Split(msg, ".tmi.twitch.tv PRIVMSG ") + split3 := channelReg.FindString(split2[1]) + channel := split3[0 : len(split3)-2] + split4 := strings.Split(split2[1], split3) + message := split4[1] + message = actionReg.ReplaceAllLiteralString(message, "") + message = actionReg2.ReplaceAllLiteralString(message, "") + + + bot.log.Debug("SPLIT" + split2[0]) + + //split5 := strings.Replace(split2[0], " :" + username + "!" + username + "@" + username, "", -1) + //tags := strings.Replace(split5, "@", "", 1) + + user := newUser(username) + bot.messages <- newMessage(message, user, "#" + channel) +} + +func (bot *bot) join(channel string) { + bot.log.Info("JOIN " + channel) + fmt.Fprintf(*mainConn, "JOIN %s\r\n", channel) +} \ No newline at end of file diff --git a/twitch/message.go b/twitch/message.go new file mode 100644 index 0000000..ff43956 --- /dev/null +++ b/twitch/message.go @@ -0,0 +1,15 @@ +package twitch + +type message struct { + Text string + User user + Channel string +} + +func newMessage(text string, user user, channel string) message { + return message{ + Text: text, + User: user, + Channel: channel, + } +} \ No newline at end of file diff --git a/twitch/user.go b/twitch/user.go new file mode 100644 index 0000000..7b888e6 --- /dev/null +++ b/twitch/user.go @@ -0,0 +1,18 @@ +package twitch + +type user struct { + Username string + UserId string + Color string + DisplayName string + Emotes map[string][]string + Mod bool + Subscriber bool + Turbo bool +} + +func newUser(username string) user { + return user{ + Username: username, + } +} \ No newline at end of file