Skip to content
This repository has been archived by the owner on Dec 23, 2024. It is now read-only.

Commit

Permalink
refactor code (#11)
Browse files Browse the repository at this point in the history
* change argment type

* remove unused code

* fix regex pattern

* rewrite

* remove file

* move functions

* remove purge method
  • Loading branch information
aqyuki authored Jun 9, 2024
1 parent fc91e2d commit 5c10e30
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 160 deletions.
24 changes: 0 additions & 24 deletions config/store.go

This file was deleted.

128 changes: 118 additions & 10 deletions discord/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package discord
import (
"errors"
"fmt"
"regexp"
"strings"
"time"

"github.com/aqyuki/expand-bot/logging"
"github.com/bwmarrin/discordgo"
Expand All @@ -11,7 +14,7 @@ import (

// Bot provides features to interact with Discord.
type Bot struct {
config Config
token string
client *discordgo.Session
logger *zap.SugaredLogger
}
Expand All @@ -30,9 +33,9 @@ func WithLogger(logger *zap.SugaredLogger) Option {
}

// NewBot creates a new Bot instance.
func NewBot(config Config, opts ...Option) Bot {
func NewBot(token string, opts ...Option) Bot {
b := Bot{
config: config,
token: token,
client: nil,
logger: logging.DefaultLogger(),
}
Expand All @@ -48,12 +51,12 @@ func (b *Bot) Start() error {
return errors.New("bot is already running")
}

session, err := discordgo.New("Bot " + b.config.Token)
session, err := discordgo.New("Bot " + b.token)
if err != nil {
return fmt.Errorf("failed to create session to discord because %w", err)
}

session.AddHandler(newMessageCreateHandler(b.logger))
session.AddHandler(b.expandMessageLink)
if err := session.Open(); err != nil {
return fmt.Errorf("failed to open session to discord because %w", err)
}
Expand All @@ -67,16 +70,121 @@ func (b *Bot) Stop() error {
if b.client == nil {
return errors.New("bot is not running")
}

defer b.purge()
if err := b.client.Close(); err != nil {
return fmt.Errorf("failed to close session to discord because %w", err)
}
b.logger.Info("bot is stopped")
return nil
}

// purge cleans up the bot instance.
func (b *Bot) purge() {
b.client = nil
func (b *Bot) expandMessageLink(s *discordgo.Session, m *discordgo.MessageCreate) {
// Ignore all messages created by the bot itself
if m.Author.Bot {
b.logger.Info("skip message because it was created by the bot itself")
return
}

// if the message contains message link, expand it
links := extractMessageLinks(m.Content)
if len(links) == 0 {
b.logger.Info("skip message because it does not contain message links")
return
}

var embeds []*discordgo.MessageEmbed

for _, link := range links {
info, err := extractMessageInfo(link)
if err != nil {
b.logger.Error("failed to extract message info", zap.Error(err))
continue
}

// if the guild is not the same as the message, ignore it
if info.guild != m.GuildID {
b.logger.Info("skip message because the guild is not the same as the message")
continue
}

// if the channel is nsfw, ignore it
citationChannel, err := s.Channel(info.channel)
if err != nil {
b.logger.Error("failed to get channel", zap.Error(err))
continue
}
if citationChannel.NSFW {
b.logger.Info("skip message because the channel is nsfw")
continue
}

// get the message
citationMsg, err := s.ChannelMessage(info.channel, info.message)
if err != nil {
b.logger.Error("failed to get message", zap.Error(err))
continue
}

// if the message has attachment(image), use it as the thumbnail of the embed
var image *discordgo.MessageEmbedImage
if len(citationMsg.Attachments) > 0 {
image = &discordgo.MessageEmbedImage{
URL: citationMsg.Attachments[0].URL,
}
}

embed := &discordgo.MessageEmbed{
Image: image,
Author: &discordgo.MessageEmbedAuthor{
Name: citationMsg.Author.Username,
IconURL: citationMsg.Author.AvatarURL("64"),
},
Color: 0x7fffff,
Description: citationMsg.Content,
Timestamp: citationMsg.Timestamp.Format(time.RFC3339),
Footer: &discordgo.MessageEmbedFooter{
Text: citationChannel.Name,
},
}

embeds = append(embeds, embed)
b.logger.Debug("expanded message", zap.Any("embed", embed))
}
// expand the message
replyMsg := discordgo.MessageSend{
Embeds: embeds,
Reference: m.Reference(),
AllowedMentions: &discordgo.MessageAllowedMentions{
RepliedUser: true,
},
}
if _, err := s.ChannelMessageSendComplex(m.ChannelID, &replyMsg); err != nil {
b.logger.Error("failed to send message", zap.Error(err))
return
}
b.logger.Info("expanded message", zap.String("channel", m.ChannelID), zap.String("message", m.ID))
}

var rgx = regexp.MustCompile(`https://(?:ptb\.|canary\.)?discord(app)?\.com/channels/(\d+)/(\d+)/(\d+)`)

func extractMessageLinks(s string) []string {
return rgx.FindAllString(s, -1)
}

type message struct {
guild string
channel string
message string
}

// extractMessageInfo extracts the channel ID and message ID from the message link.
func extractMessageInfo(link string) (info message, err error) {
segments := strings.Split(link, "/")
if len(segments) < 4 {
return message{}, errors.New("invalid message link")
}
return message{
guild: segments[len(segments)-3],
channel: segments[len(segments)-2],
message: segments[len(segments)-1],
}, nil
}
122 changes: 0 additions & 122 deletions discord/hook.go

This file was deleted.

9 changes: 5 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"os"
"os/signal"

"github.com/aqyuki/expand-bot/config"
"github.com/aqyuki/expand-bot/discord"
"github.com/aqyuki/expand-bot/logging"
)
Expand All @@ -29,9 +28,7 @@ func main() {

func run(ctx context.Context) exitCode {
logger := logging.DefaultLogger()

store := config.NewStore()
bot := discord.NewBot(store.DiscordConfig(), discord.WithLogger(logger))
bot := discord.NewBot(loadTokenFromEnv(), discord.WithLogger(logger))

if err := bot.Start(); err != nil {
logger.Errorf("failed to start the bot\n\t%v\n", err)
Expand All @@ -51,3 +48,7 @@ func run(ctx context.Context) exitCode {
func exit[T ~int](code T) {
os.Exit(int(code))
}

func loadTokenFromEnv() string {
return os.Getenv("DISCORD_TOKEN")
}

0 comments on commit 5c10e30

Please sign in to comment.