message parsing
This commit is contained in:
parent
7a69523b09
commit
6b5857d382
6 changed files with 257 additions and 28 deletions
|
@ -4,24 +4,30 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Cynosphere/comcord/state"
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
"github.com/fatih/color"
|
"github.com/mgutz/ansi"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const format string = " %s - %s%s"
|
||||||
|
|
||||||
func HelpCommand(session *discordgo.Session) {
|
func HelpCommand(session *discordgo.Session) {
|
||||||
|
noColor := state.HasNoColor()
|
||||||
|
|
||||||
fmt.Println("\r\nCOMcord (c)left 2023\n\r")
|
fmt.Println("\r\nCOMcord (c)left 2023\n\r")
|
||||||
|
|
||||||
index := 0
|
index := 0
|
||||||
for key, cmd := range GetAllCommands() {
|
for key, cmd := range GetAllCommands() {
|
||||||
str := fmt.Sprintf(" %s - %s", key, cmd.Description)
|
str := fmt.Sprintf(format, key, cmd.Description, "")
|
||||||
length := len(str)
|
length := len(str)
|
||||||
|
padding := strings.Repeat(" ", 25 - length)
|
||||||
|
|
||||||
fmt.Print(" ")
|
if noColor {
|
||||||
color.Set(color.FgYellow, color.Bold)
|
fmt.Printf(format, key, cmd.Description, padding)
|
||||||
fmt.Print(key)
|
} else {
|
||||||
color.Unset()
|
coloredKey := ansi.Color(key, "yellow+b")
|
||||||
fmt.Printf(" - %s", cmd.Description)
|
fmt.Printf(format, coloredKey, cmd.Description, padding)
|
||||||
fmt.Print(strings.Repeat(" ", 25 - length))
|
}
|
||||||
|
|
||||||
index++
|
index++
|
||||||
if index % 3 == 0 {
|
if index % 3 == 0 {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Cynosphere/comcord/lib"
|
||||||
"github.com/Cynosphere/comcord/state"
|
"github.com/Cynosphere/comcord/state"
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
"github.com/ergochat/readline"
|
"github.com/ergochat/readline"
|
||||||
|
@ -22,7 +23,10 @@ func SendMode(session *discordgo.Session) {
|
||||||
length := len(session.State.User.Username) + 2
|
length := len(session.State.User.Username) + 2
|
||||||
curLength := state.GetNameLength()
|
curLength := state.GetNameLength()
|
||||||
|
|
||||||
prompt := fmt.Sprintf("%s[%s]%s%s", ansi.ColorCode("cyan+b"), session.State.User.Username, strings.Repeat(" ", (curLength - length) + 1), ansi.ColorCode("reset"))
|
prompt := fmt.Sprintf("[%s]%s", session.State.User.Username, strings.Repeat(" ", (curLength - length) + 1))
|
||||||
|
if !state.HasNoColor() {
|
||||||
|
prompt = ansi.Color(prompt, "cyan+b")
|
||||||
|
}
|
||||||
|
|
||||||
input, _ := readline.NewFromConfig(&readline.Config{
|
input, _ := readline.NewFromConfig(&readline.Config{
|
||||||
Prompt: prompt,
|
Prompt: prompt,
|
||||||
|
@ -51,4 +55,5 @@ func SendMode(session *discordgo.Session) {
|
||||||
// TODO: update afk state
|
// TODO: update afk state
|
||||||
}
|
}
|
||||||
state.SetInPrompt(false)
|
state.SetInPrompt(false)
|
||||||
|
lib.ProcessQueue(session)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package events
|
package events
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/Cynosphere/comcord/lib"
|
||||||
"github.com/Cynosphere/comcord/state"
|
"github.com/Cynosphere/comcord/state"
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MessageCreate(session *discordgo.Session, msg *discordgo.MessageCreate) {
|
func MessageCreate(session *discordgo.Session, msg *discordgo.MessageCreate) {
|
||||||
if (msg.Author.ID == session.State.User.ID) {
|
if msg.Author.ID == session.State.User.ID {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,13 +16,15 @@ func MessageCreate(session *discordgo.Session, msg *discordgo.MessageCreate) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isDM := channel.Type == discordgo.ChannelTypeDM || channel.Type == discordgo.ChannelTypeGroupDM
|
||||||
|
|
||||||
if state.IsInPrompt() {
|
if state.IsInPrompt() {
|
||||||
state.AddMessageToQueue(*msg.Message)
|
state.AddMessageToQueue(msg.Message)
|
||||||
} else {
|
} else {
|
||||||
// TODO
|
lib.ProcessMessage(session, msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()})
|
||||||
}
|
}
|
||||||
|
|
||||||
if channel.Type == discordgo.ChannelTypeDM || channel.Type == discordgo.ChannelTypeGroupDM {
|
if isDM {
|
||||||
state.SetLastDM(msg.ChannelID)
|
state.SetLastDM(msg.ChannelID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,23 +9,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Ready(session *discordgo.Session, event *discordgo.Ready) {
|
func Ready(session *discordgo.Session, event *discordgo.Ready) {
|
||||||
fmt.Printf("\rLogged in as: %s%s (%s)%s\n\r", ansi.ColorCode("yellow"), session.State.User.Username, session.State.User.ID, ansi.ColorCode("reset"))
|
fmt.Printf("\rLogged in as: %s\n\r", ansi.Color(fmt.Sprintf("%s (%s)", session.State.User.Username, session.State.User.ID), "yellow"))
|
||||||
|
|
||||||
state.SetNameLength(len(session.State.User.Username) + 2)
|
state.SetNameLength(len(session.State.User.Username) + 2)
|
||||||
|
|
||||||
defaultGuild := state.GetConfigValue("defaultGuild")
|
defaultGuild := state.GetConfigValue("defaultGuild")
|
||||||
defaultChannel := state.GetConfigValue("defaultChannel")
|
defaultChannel := state.GetConfigValue("defaultChannel")
|
||||||
if defaultGuild != "" {
|
if defaultGuild != "" {
|
||||||
//var guild discordgo.Guild
|
_, err := session.State.Guild(defaultGuild)
|
||||||
hasGuild := false
|
if err == nil {
|
||||||
for _, g := range session.State.Guilds {
|
|
||||||
if g.ID == defaultGuild {
|
|
||||||
//guild = *g
|
|
||||||
hasGuild = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if hasGuild {
|
|
||||||
if defaultChannel != "" {
|
if defaultChannel != "" {
|
||||||
state.SetCurrentChannel(defaultChannel)
|
state.SetCurrentChannel(defaultChannel)
|
||||||
state.SetLastChannel(defaultGuild, defaultChannel)
|
state.SetLastChannel(defaultGuild, defaultChannel)
|
||||||
|
|
209
lib/messages.go
Normal file
209
lib/messages.go
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Cynosphere/comcord/state"
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
"github.com/mgutz/ansi"
|
||||||
|
)
|
||||||
|
|
||||||
|
var /*const*/ REGEX_CODEBLOCK = regexp.MustCompile(`(?i)\x60\x60\x60(?:([a-z0-9_+\-\.]+?)\n)?\n*([^\n].*?)\n*\x60\x60\x60`)
|
||||||
|
|
||||||
|
type MessageOptions struct {
|
||||||
|
Content string
|
||||||
|
Name string
|
||||||
|
Channel string
|
||||||
|
Bot bool
|
||||||
|
Attachments []*discordgo.MessageAttachment
|
||||||
|
Stickers []*discordgo.Sticker
|
||||||
|
Reply *discordgo.Message
|
||||||
|
Timestamp time.Time
|
||||||
|
IsMention bool
|
||||||
|
IsDM bool
|
||||||
|
IsJoin bool
|
||||||
|
IsPin bool
|
||||||
|
IsDump bool
|
||||||
|
NoColor bool
|
||||||
|
InHistory bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormatMessage(session *discordgo.Session, options MessageOptions) {
|
||||||
|
|
||||||
|
// TODO: timestamps for pin and join
|
||||||
|
|
||||||
|
// TODO: history lines
|
||||||
|
|
||||||
|
nameLength := len(options.Name) + 2
|
||||||
|
stateNameLength := state.GetNameLength()
|
||||||
|
if nameLength > stateNameLength {
|
||||||
|
state.SetNameLength(nameLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: replies
|
||||||
|
|
||||||
|
if options.IsDump {
|
||||||
|
if options.InHistory {
|
||||||
|
// TODO
|
||||||
|
} else {
|
||||||
|
wordCount := len(strings.Split(options.Content, " "))
|
||||||
|
lineCount := len(strings.Split(options.Content, "\n"))
|
||||||
|
wordsPlural := ""
|
||||||
|
linesPlural := ""
|
||||||
|
|
||||||
|
if wordCount > 1 {
|
||||||
|
wordsPlural = "s"
|
||||||
|
}
|
||||||
|
if lineCount > 1 {
|
||||||
|
linesPlural = "s"
|
||||||
|
}
|
||||||
|
|
||||||
|
str := fmt.Sprintf("<%s DUMPs in %d characters of %d word%s in %d line%s>", options.Name, len(options.Content), wordCount, wordsPlural, lineCount, linesPlural)
|
||||||
|
|
||||||
|
if options.NoColor {
|
||||||
|
fmt.Print(str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: markdown
|
||||||
|
|
||||||
|
if options.IsDM {
|
||||||
|
name := fmt.Sprintf("*%s*", options.Name)
|
||||||
|
if !options.NoColor {
|
||||||
|
name = ansi.Color(name, "red+b")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s %s\x07\n\r", name, options.Content)
|
||||||
|
} else if len(options.Content) > 1 &&
|
||||||
|
(strings.HasPrefix(options.Content, "*") && strings.HasSuffix(options.Content, "*") && !strings.HasPrefix(options.Content, "**") && !strings.HasSuffix(options.Content, "**")) ||
|
||||||
|
(strings.HasPrefix(options.Content, "_") && strings.HasSuffix(options.Content, "_") && !strings.HasPrefix(options.Content, "__") && !strings.HasSuffix(options.Content, "__")) {
|
||||||
|
str := fmt.Sprintf("<%s %s>", options.Name, options.Content[1:len(options.Content)-1])
|
||||||
|
|
||||||
|
if options.NoColor {
|
||||||
|
fmt.Print(str + "\n\r")
|
||||||
|
} else {
|
||||||
|
fmt.Print(ansi.Color(str, "green+b") + "\n\r")
|
||||||
|
}
|
||||||
|
} else if options.IsJoin {
|
||||||
|
// TODO
|
||||||
|
} else if options.IsPin {
|
||||||
|
// TODO
|
||||||
|
} else {
|
||||||
|
nameColor := "cyan+b"
|
||||||
|
if options.IsMention {
|
||||||
|
nameColor = "red+b"
|
||||||
|
} else if options.Bot {
|
||||||
|
nameColor = "yellow+b"
|
||||||
|
}
|
||||||
|
|
||||||
|
name := fmt.Sprintf("[%s]", options.Name)
|
||||||
|
if !options.NoColor {
|
||||||
|
name = ansi.Color(name, nameColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: where is this off by 4 actually from
|
||||||
|
padding := strings.Repeat(" ", int(math.Abs(float64(stateNameLength) - float64(nameLength) - 4)))
|
||||||
|
str := fmt.Sprintf("%s%s %s", name, padding, options.Content)
|
||||||
|
if options.IsMention {
|
||||||
|
str = str + "\x07"
|
||||||
|
}
|
||||||
|
fmt.Print(str + "\n\r")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: attachments
|
||||||
|
|
||||||
|
// TODO: stickers
|
||||||
|
|
||||||
|
// TODO: links
|
||||||
|
|
||||||
|
// TODO: embeds
|
||||||
|
|
||||||
|
// TODO: lines output for history
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options MessageOptions) {
|
||||||
|
channel, err := session.State.Channel(msg.ChannelID)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guild, err := session.State.Guild(channel.GuildID)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
selfMember, err := session.State.Member(guild.ID, session.State.User.ID)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hasMentionedRole := false
|
||||||
|
for _, role := range msg.MentionRoles {
|
||||||
|
for _, selfRole := range selfMember.Roles {
|
||||||
|
if role == selfRole {
|
||||||
|
hasMentionedRole = true
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isDirectlyMentioned := false
|
||||||
|
for _, user := range msg.Mentions {
|
||||||
|
if user.ID == session.State.User.ID {
|
||||||
|
isDirectlyMentioned = true
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isPing := msg.MentionEveryone || hasMentionedRole || isDirectlyMentioned
|
||||||
|
isDM := channel.Type == discordgo.ChannelTypeDM || channel.Type == discordgo.ChannelTypeGroupDM
|
||||||
|
|
||||||
|
currentChannel := state.GetCurrentChannel()
|
||||||
|
isCurrentChannel := currentChannel == msg.ChannelID
|
||||||
|
|
||||||
|
if !isCurrentChannel && !isDM && !isPing {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if isPing && !isCurrentChannel && !isDM {
|
||||||
|
str := fmt.Sprintf("**mentioned by %s in #%s in %s**", msg.Author.Username, channel.Name, guild.Name)
|
||||||
|
if options.NoColor {
|
||||||
|
fmt.Print(ansi.Color(str, "red+b"))
|
||||||
|
} else {
|
||||||
|
fmt.Print(str)
|
||||||
|
}
|
||||||
|
fmt.Print("\x07\n\r")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content, _ := msg.ContentWithMoreMentionsReplaced(session)
|
||||||
|
options.Content = content
|
||||||
|
options.Name = msg.Author.Username
|
||||||
|
options.Channel = msg.ChannelID
|
||||||
|
options.Bot = msg.Author.Bot
|
||||||
|
options.Attachments = msg.Attachments
|
||||||
|
options.Stickers = msg.StickerItems
|
||||||
|
options.Reply = msg.ReferencedMessage
|
||||||
|
options.IsMention = isPing
|
||||||
|
options.IsDM = isDM
|
||||||
|
options.IsJoin = msg.Type == discordgo.MessageTypeGuildMemberJoin
|
||||||
|
options.IsPin = msg.Type == discordgo.MessageTypeChannelPinnedMessage
|
||||||
|
options.IsDump = REGEX_CODEBLOCK.MatchString(content)
|
||||||
|
|
||||||
|
FormatMessage(session, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProcessQueue(session *discordgo.Session) {
|
||||||
|
queue := state.GetMessageQueue()
|
||||||
|
|
||||||
|
for _, msg := range queue {
|
||||||
|
ProcessMessage(session, msg, MessageOptions{NoColor: state.HasNoColor()})
|
||||||
|
}
|
||||||
|
|
||||||
|
state.EmptyMessageQueue()
|
||||||
|
}
|
|
@ -16,9 +16,10 @@ type ComcordState struct {
|
||||||
NameLength int
|
NameLength int
|
||||||
InPrompt bool
|
InPrompt bool
|
||||||
AFK bool
|
AFK bool
|
||||||
MessageQueue []discordgo.Message
|
MessageQueue []*discordgo.Message
|
||||||
LastChannel map[string]string
|
LastChannel map[string]string
|
||||||
LastDM string
|
LastDM string
|
||||||
|
NoColor bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var state ComcordState
|
var state ComcordState
|
||||||
|
@ -34,9 +35,10 @@ func Setup(config map[string]string) {
|
||||||
state.NameLength = 2
|
state.NameLength = 2
|
||||||
state.InPrompt = false
|
state.InPrompt = false
|
||||||
state.AFK = false
|
state.AFK = false
|
||||||
state.MessageQueue = make([]discordgo.Message, 0)
|
state.MessageQueue = make([]*discordgo.Message, 0)
|
||||||
state.LastChannel = make(map[string]string)
|
state.LastChannel = make(map[string]string)
|
||||||
state.LastDM = ""
|
state.LastDM = ""
|
||||||
|
state.NoColor = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsConnected() bool {
|
func IsConnected() bool {
|
||||||
|
@ -99,14 +101,18 @@ func SetAFK(value bool) {
|
||||||
state.AFK = value
|
state.AFK = value
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMessageQueue() []discordgo.Message {
|
func GetMessageQueue() []*discordgo.Message {
|
||||||
return state.MessageQueue
|
return state.MessageQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddMessageToQueue(msg discordgo.Message) {
|
func AddMessageToQueue(msg *discordgo.Message) {
|
||||||
state.MessageQueue = append(state.MessageQueue, msg)
|
state.MessageQueue = append(state.MessageQueue, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EmptyMessageQueue() {
|
||||||
|
state.MessageQueue = make([]*discordgo.Message, 0)
|
||||||
|
}
|
||||||
|
|
||||||
func SetLastChannel(guild string, channel string) {
|
func SetLastChannel(guild string, channel string) {
|
||||||
state.LastChannel[guild] = channel
|
state.LastChannel[guild] = channel
|
||||||
}
|
}
|
||||||
|
@ -138,3 +144,11 @@ func GetConfigValue(key string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetNoColor(value bool) {
|
||||||
|
state.NoColor = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func HasNoColor() bool {
|
||||||
|
return state.NoColor
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue