aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-04-04 01:53:41 +0200
committerMel <einebeere@gmail.com>2022-04-04 01:53:41 +0200
commitfdd0ea7911b2c98f95ef99f6d1518ee4eb4dfd7a (patch)
tree702f893e5ef2ec4196cd37393014b3ca59e5c0dc
parentb80bda2da026086523f1de8f460637a376c53bf2 (diff)
downloadjinx-fdd0ea7911b2c98f95ef99f6d1518ee4eb4dfd7a.tar.zst
jinx-fdd0ea7911b2c98f95ef99f6d1518ee4eb4dfd7a.zip
Listen to incoming messages and respond to pings
-rw-r--r--cmd/bot/main.go15
-rw-r--r--pkg/bot/bot.go25
-rw-r--r--pkg/discord/discord.go68
-rw-r--r--pkg/discord/entities.go8
4 files changed, 106 insertions, 10 deletions
diff --git a/cmd/bot/main.go b/cmd/bot/main.go
index 51661e8..0f241c9 100644
--- a/cmd/bot/main.go
+++ b/cmd/bot/main.go
@@ -4,6 +4,8 @@ import (
"jinx/pkg/bot"
"log"
"os"
+ "os/signal"
+ "syscall"
)
func main() {
@@ -12,7 +14,18 @@ func main() {
log.Fatal("`BOT_TOKEN` is not set.")
}
- if err := bot.Start(token); err != nil {
+ b, err := bot.Start(token)
+ if err != nil {
+ panic(err)
+ }
+
+ c := make(chan os.Signal, 2)
+ signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
+
+ s := <-c
+ log.Printf("received signal: %s! stopping...", s)
+
+ if err := b.Stop(); err != nil {
panic(err)
}
}
diff --git a/pkg/bot/bot.go b/pkg/bot/bot.go
index 71eb0e9..091e1be 100644
--- a/pkg/bot/bot.go
+++ b/pkg/bot/bot.go
@@ -6,24 +6,33 @@ import (
"jinx/pkg/discord"
)
-func Start(token string) error {
+type Bot struct {
+ Client *discord.Discord
+ cancelContext context.CancelFunc
+}
+
+func Start(token string) (*Bot, error) {
fmt.Println("hi..!")
client := discord.NewClient(token)
ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
fmt.Println("connecting..")
if err := client.Connect(ctx); err != nil {
- return err
+ cancel()
+ return nil, err
}
fmt.Println("connected..")
- if err := client.Disconnect(); err != nil {
- return err
- }
+ return &Bot{
+ Client: client,
+ cancelContext: cancel,
+ }, nil
+}
- return nil
-} \ No newline at end of file
+func (b *Bot) Stop() error {
+ b.cancelContext()
+ return b.Client.Disconnect()
+}
diff --git a/pkg/discord/discord.go b/pkg/discord/discord.go
index 1fefe6c..c5e7d67 100644
--- a/pkg/discord/discord.go
+++ b/pkg/discord/discord.go
@@ -60,6 +60,8 @@ func (d *Discord) Connect(ctx context.Context) error {
return err
}
+ go d.listen(ctx)
+
return nil
}
@@ -141,11 +143,38 @@ func (d *Discord) startHeartbeat(ctx context.Context, interval uint64) {
}
}
+func (d *Discord) listen(ctx context.Context) {
+ for {
+ var msg GatewayPayload[any]
+ if err := d.Conn.ReadJSON(&msg); err != nil {
+ log.Fatalf("error reading message: %s\n", err)
+ }
+
+ select {
+ case <-ctx.Done():
+ return
+ default:
+ fmt.Printf("received message: %+v\n", msg)
+
+ if msg.EventName == "MESSAGE_CREATE" {
+ event := msg.Data.(map[string]interface{})
+ if event["content"] == "ping" {
+ fmt.Println("got ping, sending pong...")
+ if err := d.sendMessage(Snowflake(event["channel_id"].(string)), "pong"); err != nil {
+ log.Fatalf("error sending message: %s\n", err)
+ }
+ }
+ }
+ }
+ }
+}
+
func (d *Discord) identify() error {
msg := GatewayPayload[GatewayIdentifyMsg]{
Op: GATEWAY_OP_IDENTIFY,
Data: GatewayIdentifyMsg{
- Token: d.Token,
+ Token: d.Token,
+ Intents: 13991,
Properties: GatewayIdentifyProperties{
OS: "linux",
Browser: "jinx",
@@ -176,3 +205,40 @@ func (d *Discord) identify() error {
return nil
}
+
+func (d *Discord) sendMessage(channelID Snowflake, content string) error {
+ url := DISCORD_URl + "channels/" + string(channelID) + "/messages"
+
+ msg := struct {
+ Content string `json:"content"`
+ }{
+ Content: content,
+ }
+
+ raw, err := json.Marshal(msg)
+ if err != nil {
+ return err
+ }
+
+ req, err := http.NewRequest("POST", url, bytes.NewBuffer(raw))
+ if err != nil {
+ return err
+ }
+
+ req.Header.Set("Authorization", "Bot "+d.Token)
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("User-Agent", USER_AGENT)
+
+ res, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return err
+ }
+
+ switch res.StatusCode {
+ case 200:
+ default:
+ return errors.New("unexpected status code after sending message: " + res.Status)
+ }
+
+ return nil
+}
diff --git a/pkg/discord/entities.go b/pkg/discord/entities.go
index 85965bf..8a62fc6 100644
--- a/pkg/discord/entities.go
+++ b/pkg/discord/entities.go
@@ -13,3 +13,11 @@ type Guild struct {
Name string `json:"name"`
Unavailable bool `json:"unavailable"`
}
+
+type Message struct {
+ ID Snowflake `json:"id"`
+ ChannelID Snowflake `json:"channel_id"`
+ GuildID Snowflake `json:"guild_id"`
+ Author User `json:"author"`
+ Content string `json:"content"`
+}