|
|
@ -22,6 +22,7 @@ import (
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"go.opentelemetry.io/otel/attribute"
|
|
|
|
"go.opentelemetry.io/otel/attribute"
|
|
|
|
"go.opentelemetry.io/otel/codes"
|
|
|
|
"go.opentelemetry.io/otel/codes"
|
|
|
|
|
|
|
|
"go.opentelemetry.io/otel/propagation"
|
|
|
|
"go.opentelemetry.io/otel/sdk/resource"
|
|
|
|
"go.opentelemetry.io/otel/sdk/resource"
|
|
|
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
|
|
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
|
|
|
"go.opentelemetry.io/otel/trace"
|
|
|
|
"go.opentelemetry.io/otel/trace"
|
|
|
@ -29,7 +30,6 @@ import (
|
|
|
|
|
|
|
|
|
|
|
|
"go.wperron.io/themis"
|
|
|
|
"go.wperron.io/themis"
|
|
|
|
"go.wperron.io/themis/correlation"
|
|
|
|
"go.wperron.io/themis/correlation"
|
|
|
|
zerologcompat "go.wperron.io/themis/correlation/compat/zerolog"
|
|
|
|
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
const (
|
|
|
@ -40,10 +40,9 @@ var (
|
|
|
|
dbFile = flag.String("db", "", "SQlite database file path.")
|
|
|
|
dbFile = flag.String("db", "", "SQlite database file path.")
|
|
|
|
debug = flag.Bool("debug", false, "Set log level to DEBUG.")
|
|
|
|
debug = flag.Bool("debug", false, "Set log level to DEBUG.")
|
|
|
|
|
|
|
|
|
|
|
|
store *themis.Store
|
|
|
|
store *themis.Store
|
|
|
|
tracer trace.Tracer
|
|
|
|
tracer trace.Tracer
|
|
|
|
seq = &correlation.CryptoRandSequencer{}
|
|
|
|
propagator = propagation.TraceContext{}
|
|
|
|
gen = correlation.NewGenerator(seq)
|
|
|
|
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type Handler func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error
|
|
|
|
type Handler func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error
|
|
|
@ -62,7 +61,7 @@ func main() {
|
|
|
|
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
|
|
|
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout})
|
|
|
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout})
|
|
|
|
log.Logger = log.Logger.Hook(zerologcompat.CorrelationHook{})
|
|
|
|
log.Logger = log.Logger.Hook(correlation.TraceContextHook{})
|
|
|
|
zerolog.DurationFieldUnit = time.Millisecond
|
|
|
|
zerolog.DurationFieldUnit = time.Millisecond
|
|
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
go func() {
|
|
|
@ -254,10 +253,9 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to count claims")
|
|
|
|
return fmt.Errorf("failed to count claims: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ev, err := store.LastOf(ctx, themis.EventFlush)
|
|
|
|
ev, err := store.LastOf(ctx, themis.EventFlush)
|
|
|
@ -271,10 +269,9 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed get last flush event")
|
|
|
|
return fmt.Errorf("failed get last flush event: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lastFlush = "never"
|
|
|
|
lastFlush = "never"
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -288,10 +285,11 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"list-claims": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
"list-claims": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
claims, err := store.ListClaims(ctx)
|
|
|
|
claims, err := store.ListClaims(ctx)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
@ -301,10 +299,9 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to list claims")
|
|
|
|
return fmt.Errorf("failed to list claims: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sb := strings.Builder{}
|
|
|
|
sb := strings.Builder{}
|
|
|
@ -320,14 +317,15 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"claim": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
"claim": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
if i.Type == discordgo.InteractionApplicationCommandAutocomplete {
|
|
|
|
if i.Type == discordgo.InteractionApplicationCommandAutocomplete {
|
|
|
|
log.Debug().Ctx(ctx).Msg("command type interaction autocomplete")
|
|
|
|
log.Debug().Ctx(ctx).Msg("command type interaction autocomplete")
|
|
|
|
handleClaimAutocomplete(ctx, store, s, i)
|
|
|
|
handleClaimAutocomplete(ctx, store, s, i)
|
|
|
|
return
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
opts := i.ApplicationCommandData().Options
|
|
|
|
opts := i.ApplicationCommandData().Options
|
|
|
@ -339,9 +337,9 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
claimType, err := themis.ClaimTypeFromString(opts[0].StringValue())
|
|
|
|
claimType, err := themis.ClaimTypeFromString(opts[0].StringValue())
|
|
|
@ -353,10 +351,9 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Error().Ctx(ctx).Err(err).Str("claim_type", opts[0].StringValue()).Msg("failed to parse claim")
|
|
|
|
return fmt.Errorf("failed to parse claim: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
name := opts[1].StringValue()
|
|
|
|
name := opts[1].StringValue()
|
|
|
|
|
|
|
|
|
|
|
@ -385,9 +382,9 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
@ -397,10 +394,9 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to acquire claim")
|
|
|
|
return fmt.Errorf("failed to acquire claim: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
@ -410,10 +406,11 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"describe-claim": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
"describe-claim": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
id := i.ApplicationCommandData().Options[0]
|
|
|
|
id := i.ApplicationCommandData().Options[0]
|
|
|
|
detail, err := store.DescribeClaim(ctx, int(id.IntValue()))
|
|
|
|
detail, err := store.DescribeClaim(ctx, int(id.IntValue()))
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
@ -424,10 +421,9 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to describe claim")
|
|
|
|
return fmt.Errorf("failed to describe claim: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sb := strings.Builder{}
|
|
|
|
sb := strings.Builder{}
|
|
|
@ -443,10 +439,11 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"delete-claim": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
"delete-claim": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
id := i.ApplicationCommandData().Options[0]
|
|
|
|
id := i.ApplicationCommandData().Options[0]
|
|
|
|
userId := i.Member.User.ID
|
|
|
|
userId := i.Member.User.ID
|
|
|
|
err := store.DeleteClaim(ctx, int(id.IntValue()), userId)
|
|
|
|
err := store.DeleteClaim(ctx, int(id.IntValue()), userId)
|
|
|
@ -462,11 +459,10 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to delete claim")
|
|
|
|
return fmt.Errorf("failed to delete claim: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
@ -476,20 +472,19 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"flush": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
"flush": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
cid := correlation.FromContext(ctx)
|
|
|
|
|
|
|
|
baggage := make(url.Values)
|
|
|
|
baggage := make(url.Values)
|
|
|
|
baggage.Set("correlation_id", cid.String())
|
|
|
|
propagator.Inject(ctx, correlation.UrlValuesCarrier(baggage))
|
|
|
|
state := baggage.Encode()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sb := strings.Builder{}
|
|
|
|
sb := strings.Builder{}
|
|
|
|
sb.WriteString("modal_flush")
|
|
|
|
sb.WriteString("modal_flush")
|
|
|
|
if state != "" {
|
|
|
|
if len(baggage) != 0 {
|
|
|
|
sb.WriteRune(':')
|
|
|
|
sb.WriteRune(':')
|
|
|
|
sb.WriteString(state)
|
|
|
|
sb.WriteString(baggage.Encode())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
@ -520,14 +515,14 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"query": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
"query": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
roDB, err := sql.Open("sqlite3", fmt.Sprintf("file:%s?cache=private&mode=ro", *dbFile))
|
|
|
|
roDB, err := sql.Open("sqlite3", fmt.Sprintf("file:%s?cache=private&mode=ro", *dbFile))
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to open read-only copy of database")
|
|
|
|
return fmt.Errorf("failed to open read-only copy of database: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
q := i.ApplicationCommandData().Options[0].StringValue()
|
|
|
|
q := i.ApplicationCommandData().Options[0].StringValue()
|
|
|
@ -535,14 +530,12 @@ func main() {
|
|
|
|
defer cancelDeadline()
|
|
|
|
defer cancelDeadline()
|
|
|
|
rows, err := roDB.QueryContext(deadlined, q)
|
|
|
|
rows, err := roDB.QueryContext(deadlined, q)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to exec user-provided query")
|
|
|
|
return fmt.Errorf("faied to exec user-provided query: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fmtd, err := themis.FormatRows(ctx, rows)
|
|
|
|
fmtd, err := themis.FormatRows(ctx, rows)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to format rows")
|
|
|
|
return fmt.Errorf("failed to format rows: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2000 is a magic number here, it's the character limit for a discord
|
|
|
|
// 2000 is a magic number here, it's the character limit for a discord
|
|
|
@ -557,9 +550,11 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"schedule": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
"schedule": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
// get schedule from now to 4 mondays into the future
|
|
|
|
// get schedule from now to 4 mondays into the future
|
|
|
|
sched, err := store.GetSchedule(ctx, themis.NextMonday(), themis.NextMonday().Add(4*7*24*time.Hour))
|
|
|
|
sched, err := store.GetSchedule(ctx, themis.NextMonday(), themis.NextMonday().Add(4*7*24*time.Hour))
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
@ -569,10 +564,9 @@ func main() {
|
|
|
|
Content: "failed to get schedule, check logs for more info.",
|
|
|
|
Content: "failed to get schedule, check logs for more info.",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to get schedule")
|
|
|
|
return fmt.Errorf("failed to get schedule: %w", err)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sb := strings.Builder{}
|
|
|
|
sb := strings.Builder{}
|
|
|
@ -602,9 +596,11 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"send-schedule": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
"send-schedule": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
notifier.Send()
|
|
|
|
notifier.Send()
|
|
|
|
|
|
|
|
|
|
|
|
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
@ -614,9 +610,11 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"absent": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
"absent": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
var rawDate string
|
|
|
|
var rawDate string
|
|
|
|
if len(i.ApplicationCommandData().Options) == 0 {
|
|
|
|
if len(i.ApplicationCommandData().Options) == 0 {
|
|
|
|
rawDate = themis.NextMonday().Format(time.DateOnly)
|
|
|
|
rawDate = themis.NextMonday().Format(time.DateOnly)
|
|
|
@ -632,9 +630,9 @@ func main() {
|
|
|
|
Content: "failed to parse provided date, make sure to use the YYYY-MM-DD format.",
|
|
|
|
Content: "failed to parse provided date, make sure to use the YYYY-MM-DD format.",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if date.Before(time.Now()) {
|
|
|
|
if date.Before(time.Now()) {
|
|
|
@ -644,9 +642,9 @@ func main() {
|
|
|
|
Content: "The date must be some time in the future.",
|
|
|
|
Content: "The date must be some time in the future.",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if date.Weekday() != time.Monday {
|
|
|
|
if date.Weekday() != time.Monday {
|
|
|
@ -656,10 +654,10 @@ func main() {
|
|
|
|
Content: "The date you provided is not a Monday.",
|
|
|
|
Content: "The date you provided is not a Monday.",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO(wperron) suggest Mondays before and after?
|
|
|
|
// TODO(wperron) suggest Mondays before and after?
|
|
|
|
return
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
userId := i.Member.User.ID
|
|
|
|
userId := i.Member.User.ID
|
|
|
@ -670,9 +668,9 @@ func main() {
|
|
|
|
Content: "something went wrong recording your absence, check logs for more info.",
|
|
|
|
Content: "something went wrong recording your absence, check logs for more info.",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
return fmt.Errorf("failed to record absence: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
@ -682,8 +680,9 @@ func main() {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("failed to respond to interaction")
|
|
|
|
return fmt.Errorf("failed to respond to interaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -780,7 +779,6 @@ func registerHandlers(sess *discordgo.Session, handlers map[string]Handler) {
|
|
|
|
case discordgo.InteractionApplicationCommand:
|
|
|
|
case discordgo.InteractionApplicationCommand:
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
defer cancel()
|
|
|
|
ctx = context.WithValue(ctx, "correlation_id", gen.Next())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if h, ok := handlers[i.ApplicationCommandData().Name]; ok {
|
|
|
|
if h, ok := handlers[i.ApplicationCommandData().Name]; ok {
|
|
|
|
withLogging(i.ApplicationCommandData().Name, h)(ctx, s, i)
|
|
|
|
withLogging(i.ApplicationCommandData().Name, h)(ctx, s, i)
|
|
|
@ -791,16 +789,11 @@ func registerHandlers(sess *discordgo.Session, handlers map[string]Handler) {
|
|
|
|
|
|
|
|
|
|
|
|
state, err := parseCustomIDState(i.ModalSubmitData().CustomID)
|
|
|
|
state, err := parseCustomIDState(i.ModalSubmitData().CustomID)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("unexpected error occured while parsing state from custom id, returning early.")
|
|
|
|
log.Error().Ctx(ctx).Err(err).Msg("unexpected error occurred while parsing state from custom id, returning early.")
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cid := state.Get("correlation_id")
|
|
|
|
ctx = propagator.Extract(ctx, correlation.UrlValuesCarrier(state))
|
|
|
|
if cid != "" {
|
|
|
|
|
|
|
|
ctx = context.WithValue(ctx, "correlation_id", cid)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
ctx = context.WithValue(ctx, "correlation_id", gen.Next())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if strings.HasPrefix(i.ModalSubmitData().CustomID, "modal_flush") {
|
|
|
|
if strings.HasPrefix(i.ModalSubmitData().CustomID, "modal_flush") {
|
|
|
|
sub := i.ModalSubmitData().Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value
|
|
|
|
sub := i.ModalSubmitData().Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value
|
|
|
@ -848,12 +841,7 @@ func registerHandlers(sess *discordgo.Session, handlers map[string]Handler) {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cid := state.Get("correlation_id")
|
|
|
|
ctx = propagator.Extract(ctx, correlation.UrlValuesCarrier(state))
|
|
|
|
if cid != "" {
|
|
|
|
|
|
|
|
ctx = context.WithValue(ctx, "correlation_id", cid)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
ctx = context.WithValue(ctx, "correlation_id", gen.Next())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch i.MessageComponentData().CustomID {
|
|
|
|
switch i.MessageComponentData().CustomID {
|
|
|
|
case "schedule-response":
|
|
|
|
case "schedule-response":
|
|
|
|