about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--cmd/bot/main.go39
-rw-r--r--go.mod5
-rw-r--r--go.sum32
-rw-r--r--log/.gitkeep0
-rw-r--r--pkg/bot/bot.go57
-rw-r--r--pkg/discord/discord.go20
7 files changed, 118 insertions, 38 deletions
diff --git a/.gitignore b/.gitignore
index 286f9e9..f1f93af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,7 @@
 .DS_STORE
 
 /build/
+/log/*
 .env
+
+!*.gitkeep
\ No newline at end of file
diff --git a/cmd/bot/main.go b/cmd/bot/main.go
index 0f241c9..512b60b 100644
--- a/cmd/bot/main.go
+++ b/cmd/bot/main.go
@@ -1,31 +1,56 @@
 package main
 
 import (
+	"fmt"
 	"jinx/pkg/bot"
-	"log"
 	"os"
 	"os/signal"
 	"syscall"
+	"time"
+
+	"github.com/rs/zerolog"
 )
 
 func main() {
+	logger, err := createLogger()
+	if err != nil {
+		panic(err)
+	}
+
 	token := os.Getenv("BOT_TOKEN")
 	if token == "" {
-		log.Fatal("`BOT_TOKEN` is not set.")
+		logger.Fatal().Msg("`BOT_TOKEN` is not set.")
 	}
 
-	b, err := bot.Start(token)
-	if err != nil {
-		panic(err)
+	logger.Info().Msg("starting jinx!")
+
+	b := bot.NewBot(token, logger)
+
+	if err := b.Start(); err != nil {
+		logger.Fatal().Err(err).Msg("error starting jinx")
 	}
 
 	c := make(chan os.Signal, 2)
 	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
 
 	s := <-c
-	log.Printf("received signal: %s! stopping...", s)
+	logger.Info().Msgf("received signal: %s! stopping...", s)
 
 	if err := b.Stop(); err != nil {
-		panic(err)
+		logger.Fatal().Err(err).Msg("error stopping jinx")
+	}
+}
+
+func createLogger() (*zerolog.Logger, error) {
+	timestamp := time.Now().Format(time.RFC3339)
+	logFileName := fmt.Sprintf("log/jinx-%s.log", timestamp)
+	logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+	if err != nil {
+		return nil, err
 	}
+
+	stdout := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}
+
+	logger := zerolog.New(zerolog.MultiLevelWriter(stdout, logFile)).With().Timestamp().Logger()
+	return &logger, nil
 }
diff --git a/go.mod b/go.mod
index 3e15bef..e4906d7 100644
--- a/go.mod
+++ b/go.mod
@@ -2,4 +2,7 @@ module jinx
 
 go 1.18
 
-require github.com/gorilla/websocket v1.5.0
+require (
+	github.com/gorilla/websocket v1.5.0
+	github.com/rs/zerolog v1.26.1
+)
diff --git a/go.sum b/go.sum
index e5a03d4..5532888 100644
--- a/go.sum
+++ b/go.sum
@@ -1,2 +1,34 @@
+github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
 github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
+github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
+github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
+github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/log/.gitkeep b/log/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/log/.gitkeep
diff --git a/pkg/bot/bot.go b/pkg/bot/bot.go
index 9095d7c..add3e56 100644
--- a/pkg/bot/bot.go
+++ b/pkg/bot/bot.go
@@ -2,49 +2,64 @@ package bot
 
 import (
 	"context"
-	"fmt"
+	"errors"
 	"jinx/pkg/discord"
-	"log"
+
+	"github.com/rs/zerolog"
 )
 
 type Bot struct {
-	Client        *discord.Discord
+	client        *discord.Discord
+	logger        *zerolog.Logger
 	cancelContext context.CancelFunc
 }
 
-func Start(token string) (*Bot, error) {
-	fmt.Println("hi..!")
+func NewBot(token string, logger *zerolog.Logger) *Bot {
+	return &Bot{
+		client:        discord.NewClient(token, logger),
+		logger:        logger,
+		cancelContext: nil,
+	}
+}
 
-	client := discord.NewClient(token)
+func (b *Bot) Start() error {
+	var err error
+	ctx, cancel := context.WithCancel(context.Background())
+	b.cancelContext = cancel
 
-	client.AddEventHandler(discord.DISCORD_EVENT_READY, func(_ any) {
-		log.Println("bot is ready!")
+	defer func() {
+		if err != nil {
+			cancel()
+		}
+	}()
+
+	b.client.AddEventHandler(discord.DISCORD_EVENT_READY, func(_ any) {
+		b.logger.Info().Msg("ready!")
 	})
 
-	client.AddEventHandler(discord.DISCORD_EVENT_MESSAGE, func(m any) {
+	b.client.AddEventHandler(discord.DISCORD_EVENT_MESSAGE, func(m any) {
 		msg := m.(discord.GatewayMessageCreateEvent)
-		log.Printf("message: %s", msg.Content)
+		b.logger.Debug().Msgf("message: %s", msg.Content)
 
 		if msg.Content == "ping" {
-			if err := client.SendMessage(msg.ChannelID, "pong"); err != nil {
-				log.Printf("error sending message: %s", err)
+			if err := b.client.SendMessage(msg.ChannelID, "pong"); err != nil {
+				b.logger.Error().Err(err).Msg("error sending message")
 			}
 		}
 	})
 
-	ctx, cancel := context.WithCancel(context.Background())
-	if err := client.Connect(ctx); err != nil {
-		cancel()
-		return nil, err
+	if err := b.client.Connect(ctx); err != nil {
+		return err
 	}
 
-	return &Bot{
-		Client:        client,
-		cancelContext: cancel,
-	}, nil
+	return nil
 }
 
 func (b *Bot) Stop() error {
+	if b.cancelContext == nil {
+		return errors.New("bot has no context")
+	}
+
 	b.cancelContext()
-	return b.Client.Disconnect()
+	return b.client.Disconnect()
 }
diff --git a/pkg/discord/discord.go b/pkg/discord/discord.go
index fd60edd..bd8a7f7 100644
--- a/pkg/discord/discord.go
+++ b/pkg/discord/discord.go
@@ -5,26 +5,28 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"log"
 	"math/rand"
 	"net/http"
 	"time"
 
 	"github.com/gorilla/websocket"
+	"github.com/rs/zerolog"
 )
 
 type Discord struct {
 	token        string
+	logger       *zerolog.Logger
 	conn         *websocket.Conn
 	eventHandler *EventHandlerImpl
 	rest         REST
 }
 
-func NewClient(token string) *Discord {
+func NewClient(token string, logger *zerolog.Logger) *Discord {
 	token = "Bot " + token
 
 	return &Discord{
 		token:        token,
+		logger:       logger,
 		conn:         nil,
 		eventHandler: NewEventHandler(),
 		rest:         NewREST(token),
@@ -87,14 +89,14 @@ func (d *Discord) heartbeat(ctx context.Context, interval uint64) {
 		case <-ctx.Done():
 			return
 		case <-ticker.C:
-			fmt.Println("sending heartbeat.")
+			d.logger.Debug().Msg("sending heartbeat")
 
 			msg := GatewayPayload[any]{
 				Op: GATEWAY_OP_HEARTBEAT,
 			}
 
 			if err := d.conn.WriteJSON(msg); err != nil {
-				log.Fatalf("error sending heartbeat: %s\n", err)
+				d.logger.Error().Err(err).Msg("error sending heartbeat")
 			}
 		}
 	}
@@ -124,7 +126,7 @@ func (d *Discord) identify() error {
 		return err
 	}
 
-	fmt.Printf("identify response payload: %+v\n", res)
+	d.logger.Debug().Msgf("identify response payload: %+v", res)
 
 	if res.Op != GATEWAY_OP_DISPATCH {
 		return fmt.Errorf("expected opcode %d, got %d", GATEWAY_OP_DISPATCH, res.Op)
@@ -141,7 +143,7 @@ func (d *Discord) listen(ctx context.Context) {
 	for {
 		var msg GatewayPayload[json.RawMessage]
 		if err := d.conn.ReadJSON(&msg); err != nil {
-			log.Fatalf("error reading message: %s\n", err)
+			d.logger.Error().Err(err).Msg("error reading message")
 		}
 
 		select {
@@ -156,13 +158,13 @@ func (d *Discord) listen(ctx context.Context) {
 func (d *Discord) onEvent(msg GatewayPayload[json.RawMessage]) error {
 	switch msg.Op {
 	case GATEWAY_OP_HEARTBEAT_ACK:
-		fmt.Println("received heartbeat ack.")
+		d.logger.Debug().Msg("received heartbeat ack.")
 	case GATEWAY_OP_HEARTBEAT:
 		return errors.New("on demand heartbeat not implemented")
 	case GATEWAY_OP_DISPATCH:
 		return d.onDispatch(msg.EventName, msg.Data)
 	default:
-		fmt.Printf("received unknown opcode: %d\n", msg.Op)
+		d.logger.Warn().Msgf("received unknown opcode: %d", msg.Op)
 	}
 
 	return nil
@@ -178,7 +180,7 @@ func (d *Discord) onDispatch(eventName string, body json.RawMessage) error {
 
 		d.eventHandler.Fire(DISCORD_EVENT_MESSAGE, payload)
 	default:
-		fmt.Println("received unknown event:", eventName)
+		d.logger.Warn().Msgf("received unknown event: %s", eventName)
 	}
 
 	return nil