Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Seklfreak committed Feb 8, 2019
0 parents commit e03790c
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 0 deletions.
19 changes: 19 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Copyright (c) 2019 Sebastian Winkler

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
64 changes: 64 additions & 0 deletions events/event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package events

import (
"fmt"
"time"

"github.com/bwmarrin/discordgo"
"github.com/pkg/errors"
)

// Type defines the type for a Event
type Type string

// defines various Event Types
const (
MessageCreateEventType Type = "message_create"
MessageUpdateEventType Type = "message_update"
MessageDeleteEventType Type = "message_delete"
)

// Event represents an Event
type Event struct {
Type Type
ReceivedAt time.Time
BotUserID string

// discordgo event data
MessageCreate *discordgo.MessageCreate
MessageUpdate *discordgo.MessageUpdate
MessageDelete *discordgo.MessageDelete
}

// GenerateRoutingKey generates an Routing Key for AMQP based on a Event Type
func GenerateRoutingKey(eventType Type) string {
return fmt.Sprintf("cacophony.discord.%s", eventType)
}

// GenerateEventFromDiscordgoEvent generates an Event from a Discordgo Event
func GenerateEventFromDiscordgoEvent(botUserID string, eventItem interface{}) (*Event, error) {
event := &Event{
ReceivedAt: time.Now(),
BotUserID: botUserID,
}

switch t := eventItem.(type) {
case *discordgo.MessageCreate:
event.Type = MessageCreateEventType
event.MessageCreate = t

return event, nil
case *discordgo.MessageUpdate:
event.Type = MessageUpdateEventType
event.MessageUpdate = t

return event, nil
case *discordgo.MessageDelete:
event.Type = MessageDeleteEventType
event.MessageDelete = t

return event, nil
}

return nil, errors.New("event type is not supported")
}
10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module gitlab.com/Cacophony/go-kit

require (
github.com/bwmarrin/discordgo v0.19.0
github.com/pkg/errors v0.8.1
github.com/stretchr/testify v1.3.0 // indirect
go.uber.org/atomic v1.3.2 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.9.1
)
21 changes: 21 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
github.com/bwmarrin/discordgo v0.19.0 h1:kMED/DB0NR1QhRcalb85w0Cu3Ep2OrGAqZH1R5awQiY=
github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
63 changes: 63 additions & 0 deletions logging/discordgo_logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package logging

import (
"fmt"
"runtime"
"strings"

"github.com/bwmarrin/discordgo"
"go.uber.org/zap"
)

// DiscordgoLogger returns a logger to use with github.com/bwmarrin/discordgo
func DiscordgoLogger(logger *zap.Logger) func(msgL, caller int, format string, a ...interface{}) {

return func(msgL, caller int, format string, a ...interface{}) {
pc, file, line, _ := runtime.Caller(caller)

files := strings.Split(file, "/")
file = files[len(files)-1]

name := runtime.FuncForPC(pc).Name()
fns := strings.Split(name, ".")
name = fns[len(fns)-1]

l := logger.With(
zap.String("file", fmt.Sprintf("%s:%d", file, line)),
zap.String("method", name),
)

switch msgL {
case discordgo.LogError:
l.Error(
fmt.Sprintf(format, a...),
)

return
case discordgo.LogWarning:
l.Warn(
fmt.Sprintf(format, a...),
)

return
case discordgo.LogInformational:
l.Info(
fmt.Sprintf(format, a...),
)

return
case discordgo.LogDebug:
l.Debug(
fmt.Sprintf(format, a...),
)

return

}

l.Info(
fmt.Sprintf(format, a...),
zap.Int("log_level", msgL),
)
}
}
10 changes: 10 additions & 0 deletions logging/environment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package logging

// Environment represents a environment in which a service is running
type Environment string

// defines possibly environments
const (
DevelopmentEnvironment Environment = "development"
ProductionEnvironment Environment = "production"
)
40 changes: 40 additions & 0 deletions logging/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package logging

import (
"net/http"

"go.uber.org/zap"
)

// NewLogger creates a zap.DiscordgoLogger based on the environment
func NewLogger(env Environment, service, discordWebhookURL string, client *http.Client) (*zap.Logger, error) {
var logger *zap.Logger
var err error

switch env {
case ProductionEnvironment:

logger, err = zap.NewProduction()
if err != nil {
return nil, err
}
default:

logger, err = zap.NewDevelopment()
if err != nil {
return nil, err
}
}

logger = logger.With(zap.String("service", service))

logger = logger.WithOptions(zap.Hooks(
NewZapHookDiscord(
service, discordWebhookURL, client,
),
))

// TODO: add discord hook

return logger, nil
}
57 changes: 57 additions & 0 deletions logging/zap_hook_discord.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package logging

import (
"bytes"
"encoding/json"
"net/http"
"strings"
"time"

"github.com/bwmarrin/discordgo"
"go.uber.org/zap/zapcore"
)

// NewZapHookDiscord sends Zap log messages to a Discord Webhook
// TODO: ratelimit
func NewZapHookDiscord(serviceName, webhookURL string, client *http.Client) func(zapcore.Entry) error {
if webhookURL == "" || client == nil {
return nil
}

return func(entry zapcore.Entry) error {
if entry.Level == zapcore.DebugLevel ||
entry.Level == zapcore.InfoLevel {
return nil
}

body, err := json.Marshal(discordgo.WebhookParams{
Username: strings.Title(serviceName),
Embeds: []*discordgo.MessageEmbed{
{
Title: "Logging message: " + strings.ToUpper(entry.Level.String()),
Description: entry.Message,
Timestamp: entry.Time.Format(time.RFC3339),
Color: 0, // TODO: color per log level
Footer: &discordgo.MessageEmbedFooter{
Text: "powered by Cacophony",
},
Fields: []*discordgo.MessageEmbedField{
{
Name: "caller",
Value: entry.Caller.String(),
},
},
},
},
})
if err != nil {
return err
}

_, err = client.Post(
webhookURL, "application/json", bytes.NewBuffer(body),
)
return err
}

}

0 comments on commit e03790c

Please sign in to comment.