Skip to content

Commit

Permalink
fix: Improve Reply to be Thread Aware (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
raed-shomali authored Jul 27, 2023
1 parent bc3ade5 commit fcb291b
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 22 deletions.
26 changes: 24 additions & 2 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func newCommandContext(
) *CommandContext {
request := newRequest(parameters)
writer := newWriter(ctx, logger, slackClient)
replier := newReplier(event.ChannelID, event.UserID, event.TimeStamp, writer)
replier := newReplier(event.ChannelID, event.UserID, event.InThread(), event.TimeStamp, writer)
response := newResponseReplier(writer, replier)

return &CommandContext{
Expand All @@ -28,6 +28,7 @@ func newCommandContext(
definition: definition,
request: request,
response: response,
logger: logger,
}
}

Expand All @@ -39,6 +40,7 @@ type CommandContext struct {
definition *CommandDefinition
request *Request
response *ResponseReplier
logger Logger
}

// Context returns the context
Expand Down Expand Up @@ -71,6 +73,11 @@ func (r *CommandContext) Response() *ResponseReplier {
return r.response
}

// Logger returns the logger
func (r *CommandContext) Logger() Logger {
return r.logger
}

// newInteractionContext creates a new interaction context
func newInteractionContext(
ctx context.Context,
Expand All @@ -79,15 +86,17 @@ func newInteractionContext(
callback *slack.InteractionCallback,
definition *InteractionDefinition,
) *InteractionContext {
inThread := isMessageInThread(callback.OriginalMessage.ThreadTimestamp, callback.OriginalMessage.Timestamp)
writer := newWriter(ctx, logger, slackClient)
replier := newReplier(callback.Channel.ID, callback.User.ID, callback.MessageTs, writer)
replier := newReplier(callback.Channel.ID, callback.User.ID, inThread, callback.MessageTs, writer)
response := newResponseReplier(writer, replier)
return &InteractionContext{
ctx: ctx,
definition: definition,
callback: callback,
slackClient: slackClient,
response: response,
logger: logger,
}
}

Expand All @@ -98,6 +107,7 @@ type InteractionContext struct {
callback *slack.InteractionCallback
slackClient *slack.Client
response *ResponseReplier
logger Logger
}

// Context returns the context
Expand Down Expand Up @@ -125,6 +135,11 @@ func (r *InteractionContext) SlackClient() *slack.Client {
return r.slackClient
}

// Logger returns the logger
func (r *InteractionContext) Logger() Logger {
return r.logger
}

// newJobContext creates a new bot context
func newJobContext(ctx context.Context, logger Logger, slackClient *slack.Client, definition *JobDefinition) *JobContext {
writer := newWriter(ctx, logger, slackClient)
Expand All @@ -134,6 +149,7 @@ func newJobContext(ctx context.Context, logger Logger, slackClient *slack.Client
definition: definition,
slackClient: slackClient,
response: response,
logger: logger,
}
}

Expand All @@ -143,6 +159,7 @@ type JobContext struct {
definition *JobDefinition
slackClient *slack.Client
response *ResponseWriter
logger Logger
}

// Context returns the context
Expand All @@ -164,3 +181,8 @@ func (r *JobContext) Response() *ResponseWriter {
func (r *JobContext) SlackClient() *slack.Client {
return r.slackClient
}

// Logger returns the logger
func (r *JobContext) Logger() Logger {
return r.logger
}
3 changes: 1 addition & 2 deletions examples/interaction-middleware/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"context"
"fmt"
"log"
"os"

Expand Down Expand Up @@ -66,7 +65,7 @@ func slackerInteractive(ctx *slacker.InteractionContext) {
func LoggingInteractionMiddleware() slacker.InteractionMiddlewareHandler {
return func(next slacker.InteractionHandler) slacker.InteractionHandler {
return func(ctx *slacker.InteractionContext) {
fmt.Printf(
ctx.Logger().Infof(
"%s initiated \"%s\" with action \"%v\" in channel %s\n",
ctx.Callback().User.ID,
ctx.Definition().BlockID,
Expand Down
5 changes: 2 additions & 3 deletions examples/job-middleware/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"context"
"fmt"
"log"
"os"

Expand Down Expand Up @@ -54,12 +53,12 @@ func main() {
func LoggingJobMiddleware() slacker.JobMiddlewareHandler {
return func(next slacker.JobHandler) slacker.JobHandler {
return func(ctx *slacker.JobContext) {
fmt.Printf(
ctx.Logger().Infof(
"%s started\n",
ctx.Definition().Name,
)
next(ctx)
fmt.Printf(
ctx.Logger().Infof(
"%s ended\n",
ctx.Definition().Name,
)
Expand Down
2 changes: 1 addition & 1 deletion examples/message-error/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {
Command: "thread",
Description: "Tests errors in threads",
Handler: func(ctx *slacker.CommandContext) {
ctx.Response().ReplyError(errors.New("oops, an error occurred"), slacker.WithInThread())
ctx.Response().ReplyError(errors.New("oops, an error occurred"), slacker.WithInThread(true))
},
}

Expand Down
2 changes: 1 addition & 1 deletion examples/message-thread/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func main() {
Description: "Ping!",
Examples: []string{"ping"},
Handler: func(ctx *slacker.CommandContext) {
ctx.Response().Reply("pong", slacker.WithInThread())
ctx.Response().Reply("pong", slacker.WithInThread(true))
},
}

Expand Down
9 changes: 3 additions & 6 deletions message_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,9 @@ type MessageEvent struct {
BotID string
}

// IsThread indicates if a message event took place in a thread.
func (e *MessageEvent) IsThread() bool {
if e.ThreadTimeStamp == "" || e.ThreadTimeStamp == e.TimeStamp {
return false
}
return true
// InThread indicates if a message event took place in a thread.
func (e *MessageEvent) InThread() bool {
return isMessageInThread(e.ThreadTimeStamp, e.TimeStamp)
}

// IsBot indicates if the message was sent by a bot
Expand Down
8 changes: 4 additions & 4 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ func WithAttachments(attachments []slack.Attachment) ReplyOption {
}

// WithInThread specifies whether to reply inside a thread of the original message
func WithInThread() ReplyOption {
func WithInThread(inThread bool) ReplyOption {
return func(defaults *replyOptions) {
defaults.InThread = true
defaults.InThread = &inThread
}
}

Expand All @@ -110,7 +110,7 @@ func WithSchedule(timestamp time.Time) ReplyOption {

type replyOptions struct {
Attachments []slack.Attachment
InThread bool
InThread *bool
ReplaceMessageTS string
IsEphemeral bool
ScheduleTime *time.Time
Expand All @@ -120,7 +120,7 @@ type replyOptions struct {
func newReplyOptions(options ...ReplyOption) *replyOptions {
config := &replyOptions{
Attachments: []slack.Attachment{},
InThread: false,
InThread: nil,
}

for _, option := range options {
Expand Down
8 changes: 5 additions & 3 deletions response_replier.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import (
)

// newReplier creates a new replier structure
func newReplier(channelID string, userID string, eventTS string, writer *Writer) *Replier {
return &Replier{channelID: channelID, userID: userID, eventTS: eventTS, writer: writer}
func newReplier(channelID string, userID string, inThread bool, eventTS string, writer *Writer) *Replier {
return &Replier{channelID: channelID, userID: userID, inThread: inThread, eventTS: eventTS, writer: writer}
}

// Replier sends messages to the same channel the event came from
type Replier struct {
channelID string
userID string
inThread bool
eventTS string
writer *Writer
}
Expand Down Expand Up @@ -41,7 +42,8 @@ func (r *Replier) convertOptions(options ...ReplyOption) []PostOption {
SetAttachments(replyOptions.Attachments),
}

if replyOptions.InThread {
// If the original message came from a thread, reply in a thread, unless there is an override
if (replyOptions.InThread == nil && r.inThread) || (replyOptions.InThread != nil && *replyOptions.InThread) {
responseOptions = append(responseOptions, SetThreadTS(r.eventTS))
}

Expand Down
9 changes: 9 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package slacker

// isMessageInThread determines if a message is in a thread
func isMessageInThread(threadTimestamp string, messageTimestamp string) bool {
if threadTimestamp == "" || threadTimestamp == messageTimestamp {
return false
}
return true
}

0 comments on commit fcb291b

Please sign in to comment.