-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: adds discord integration to GoMud (#245)
This PR adds a very simple discord integration to GoMud. To use the integration: 1. Setup a discord webhook: https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks 2. Set the environment variable "DISCORD_WEBHOOK_URL" prior to running GoMud. (`DISCORD_WEBHOOK_URL=https://www.mywebhook.com ./gomud` on linux). All feedback is encouraged and welcome, learning Golang slowly.
- Loading branch information
1 parent
7967ca7
commit 1351d6e
Showing
5 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ private-notes.txt | |
_datafiles/**/users/* | ||
**/config-overrides.yaml | ||
**/.roundcount | ||
vendor/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Package discord | ||
// | ||
// This package provides programatic access to discord messages integrated with GoMud. | ||
// | ||
// References: | ||
// https://leovoel.github.io/embed-visualizer/ | ||
// https://birdie0.github.io/discord-webhooks-guide/discord_webhook.html | ||
package discord | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/volte6/gomud/internal/events" | ||
) | ||
|
||
var ( | ||
WebhookUrl string | ||
initialized bool | ||
) | ||
|
||
// Initializes and sets the webhook so we can send messages to discord | ||
// and registers listeners to listen for events | ||
func Init(webhookUrl string) { | ||
if initialized { | ||
return | ||
} | ||
|
||
WebhookUrl = webhookUrl | ||
registerListeners() | ||
initialized = true | ||
} | ||
|
||
func registerListeners() { | ||
events.RegisterListener(events.PlayerSpawn{}, HandlePlayerSpawn) | ||
events.RegisterListener(events.PlayerDespawn{}, HandlePlayerDespawn) | ||
} | ||
|
||
// Sends an embed message to discord which includes a colored bar to the left | ||
// hexColor should be specified as a string in this format "#000000" | ||
func SendRichMessage(message string, hexColor string) error { | ||
if !initialized { | ||
return errors.New("Discord client was not initialized.") | ||
} | ||
|
||
if strings.HasPrefix(hexColor, "#") { | ||
hexColor = hexColor[1:] | ||
} | ||
|
||
color, err := strconv.ParseInt(hexColor, 16, 32) | ||
if err != nil { | ||
message := fmt.Sprintf("Invalid color specified, expected format #000000") | ||
return errors.New(message) | ||
} | ||
|
||
payload := richMessage{ | ||
Embeds: []embed{ | ||
{ | ||
Description: message, | ||
Color: int32(color), | ||
}, | ||
}, | ||
} | ||
|
||
marshalled, err := json.Marshal(payload) | ||
if err != nil { | ||
message := fmt.Sprintf("Couldn't marshal discord message") | ||
return errors.New(message) | ||
} | ||
|
||
return send(marshalled) | ||
} | ||
|
||
// Sends a simple message to discord | ||
func SendMessage(message string) error { | ||
if !initialized { | ||
return errors.New("Discord client was not initialized.") | ||
} | ||
|
||
payload := simpleMessage{ | ||
Content: message, | ||
} | ||
|
||
marshalled, err := json.Marshal(payload) | ||
if err != nil { | ||
message := fmt.Sprintf("Couldn't marshal discord message") | ||
return errors.New(message) | ||
} | ||
|
||
return send(marshalled) | ||
} | ||
|
||
func send(marshalled []byte) error { | ||
request, err := http.NewRequest("POST", WebhookUrl, bytes.NewReader(marshalled)) | ||
request.Header.Set("Content-Type", "application/json; charset=UTF-8") | ||
|
||
client := &http.Client{} | ||
response, err := client.Do(request) | ||
if err != nil { | ||
message := fmt.Sprintf("Couldn't send POST request to discord.") | ||
return errors.New(message) | ||
} | ||
|
||
// Expect 204 No Content reply | ||
if response.StatusCode != 204 { | ||
message := fmt.Sprintf("Expected discord to send status code 204, got %v.", response.StatusCode) | ||
return errors.New(message) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package discord | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/volte6/gomud/internal/events" | ||
"github.com/volte6/gomud/internal/users" | ||
) | ||
|
||
// Player enters the world event | ||
func HandlePlayerSpawn(e events.Event) bool { | ||
evt, typeOk := e.(events.PlayerSpawn) | ||
if !typeOk { | ||
return false | ||
} | ||
|
||
user := users.GetByUserId(evt.UserId) | ||
if user == nil { | ||
return false | ||
} | ||
|
||
message := fmt.Sprintf(":white_check_mark: **%v** connected", user.Character.Name) | ||
err := SendMessage(message) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
// Player leaves the world event | ||
func HandlePlayerDespawn(e events.Event) bool { | ||
evt, typeOk := e.(events.PlayerDespawn) | ||
if !typeOk { | ||
return false | ||
} | ||
|
||
user := users.GetByUserId(evt.UserId) | ||
if user == nil { | ||
return false | ||
} | ||
|
||
message := fmt.Sprintf(":x: **%v** disconnected", user.Character.Name) | ||
err := SendMessage(message) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
return true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package discord | ||
|
||
// Reference: https://birdie0.github.io/discord-webhooks-guide/discord_webhook.html | ||
|
||
// Discord message payload for non-rich content | ||
// This object has many more fields, see reference | ||
type simpleMessage struct { | ||
Content string `json:"content"` | ||
} | ||
|
||
// Discord message payload for rich content | ||
type richMessage struct { | ||
Embeds []embed `json:"embeds"` | ||
} | ||
|
||
// These objects have many more fields, see reference | ||
type embed struct { | ||
Description string `json:"description"` | ||
Color int32 `json:"color"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters