Skip to content

Commit

Permalink
Flags fixes + add channelOverride flag (#14)
Browse files Browse the repository at this point in the history
Adding a channelOverride flag. This is useful for those who wants to run
this application side by side their existing solution. This way all
messages can be overwritten to a single channel, for debugging purposes
(i.e. do I get the same messages in my monolith channel as my original
channels?).

It also can be used if one would like to _force_ all users to only allow
sending to a specific channel. This way one could setup this proxy with
their unique endpoint. I.e.

my-channel.this-app with `-channelOverride #my-channel` and make it a
limited proxy.
  • Loading branch information
wiardvanrij authored Oct 22, 2023
1 parent 8f93c48 commit 87d27a4
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 26 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,8 @@ settings:

- `--applicationPort` : Port used for the application endpoint (where you send your requests to)
- Default: *`:8080`*
- Example: `--applicationPort :8080`
- Example: `--applicationPort :8080`

- `--channelOverride` : Override on sending _all_ messages to this defined channel. This is useful for debugging or if you want to force to use a single channel
- Default: *``*
- Example: `--channelOverride #debug-notifications`
9 changes: 5 additions & 4 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,12 @@ func (s *SlackClient) PostMessage(request SlackPostMessageRequest, url string, t
return nil
}

func NewApp(queueSize int, httpClient *http.Client, metrics *Metrics) *App {
func NewApp(queueSize int, httpClient *http.Client, metrics *Metrics, channelOverride string) *App {
return &App{
slackQueue: make(chan SlackPostMessageRequest, queueSize),
messenger: &SlackClient{client: httpClient},
metrics: metrics,
slackQueue: make(chan SlackPostMessageRequest, queueSize),
messenger: &SlackClient{client: httpClient},
metrics: metrics,
channelOverride: channelOverride,
}
}

Expand Down
45 changes: 24 additions & 21 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,33 +44,36 @@ type SlackPostMessageRequest struct {
}

type App struct {
slackQueue chan SlackPostMessageRequest
wg sync.WaitGroup
messenger SlackMessenger
metrics *Metrics
slackQueue chan SlackPostMessageRequest
wg sync.WaitGroup
messenger SlackMessenger
metrics *Metrics
channelOverride string
}

func main() {
var (
MaxRetries = 2
InitialBackoffMs = 1000
SlackPostMessageURL = "https://slack.com/api/chat.postMessage"
maxRetries = 2
initialBackoffMs = 1000
slackPostMessageURL = "https://slack.com/api/chat.postMessage"
maxQueueSize = 100
burst = 3
tokenFlag string
MetricsPort = ":9090"
ApplicationPort = ":8080"
token string
metricsPort = ":9090"
applicationPort = ":8080"
channelOverride string
)

// Define the flags with the default values // TODO: move the ones that can change to dflag
flag.IntVar(&MaxRetries, "maxRetries", MaxRetries, "Maximum number of retries for posting a message")
flag.IntVar(&InitialBackoffMs, "initialBackoffMs", InitialBackoffMs, "Initial backoff in milliseconds for retries")
flag.StringVar(&SlackPostMessageURL, "slackURL", SlackPostMessageURL, "Slack Post Message API URL")
flag.IntVar(&maxRetries, "maxRetries", maxRetries, "Maximum number of retries for posting a message")
flag.IntVar(&initialBackoffMs, "initialBackoffMs", initialBackoffMs, "Initial backoff in milliseconds for retries")
flag.StringVar(&slackPostMessageURL, "slackURL", slackPostMessageURL, "Slack Post Message API URL")
flag.IntVar(&maxQueueSize, "queueSize", maxQueueSize, "Maximum number of messages in the queue")
flag.IntVar(&burst, "burst", burst, "Maximum number of burst to allow")
flag.StringVar(&tokenFlag, "token", "", "Bearer token for the Slack API")
flag.StringVar(&MetricsPort, "metricsPort", MetricsPort, "Port for the metrics server")
flag.StringVar(&ApplicationPort, "applicationPort", ApplicationPort, "Port for the application server")
flag.StringVar(&token, "token", "", "Bearer token for the Slack API")
flag.StringVar(&metricsPort, "metricsPort", metricsPort, "Port for the metrics server")
flag.StringVar(&applicationPort, "applicationPort", applicationPort, "Port for the application server")
flag.StringVar(&channelOverride, "channelOverride", "", "Override the channel for all messages - Be careful with this one!")

scli.ServerMain()

Expand All @@ -81,14 +84,14 @@ func main() {
// Initialize the app, metrics are passed along so they are accessible
app := NewApp(maxQueueSize, &http.Client{
Timeout: 10 * time.Second,
}, metrics)
}, metrics, channelOverride)
// The only required flag is the token at the moment.
if tokenFlag == "" {
if token == "" {
log.Fatalf("Missing token flag")
}

log.Infof("Starting metrics server.")
StartMetricServer(r, MetricsPort)
StartMetricServer(r, metricsPort)

// Main ctx
ctx, cancel := context.WithCancel(context.Background())
Expand All @@ -99,11 +102,11 @@ func main() {
defer serverCancel()

log.Infof("Starting main app logic")
go app.processQueue(ctx, MaxRetries, InitialBackoffMs, SlackPostMessageURL, tokenFlag, burst)
go app.processQueue(ctx, maxRetries, initialBackoffMs, slackPostMessageURL, token, burst)
log.Infof("Starting receiver server")
// Check error return of app.StartServer in go routine anon function:
go func() {
err := app.StartServer(serverCtx, ApplicationPort)
err := app.StartServer(serverCtx, applicationPort)
if err != nil {
log.Fatalf("Error starting server: %v", err)
}
Expand Down
8 changes: 8 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ func (app *App) handleRequest(w http.ResponseWriter, r *http.Request) {

// Start the logic (as we passed all our checks) to process the request.
app.metrics.RequestsReceivedTotal.WithLabelValues(request.Channel).Inc()

// If the channelOverride flag is set, we override the channel for all messages.
// We still use the original channel for the metrics (see above).
if app.channelOverride != "" {
log.S(log.Debug, "Overriding channel", log.String("channelOverride", app.channelOverride), log.String("channel", request.Channel))
request.Channel = app.channelOverride
}

// Add a counter to the wait group, this is important to wait for all the messages to be processed before shutting down the server.
app.wg.Add(1)
// Send the message to the slackQueue to be processed
Expand Down

0 comments on commit 87d27a4

Please sign in to comment.