diff --git a/.env.example b/.env.example index 4042282..cfa7be3 100644 --- a/.env.example +++ b/.env.example @@ -3,4 +3,8 @@ ESI_CLIENT_ID=your-client-id ESI_REDIRECT_URI=http://localhost:3000/callback ESI_SCOPES=esi-planets.manage_planets.v1 HTTP_SERVER_PORT=3000 -ESI_REFRESH_INTERVAL=P10M \ No newline at end of file +ESI_REFRESH_INTERVAL=P10M + +WEBHOOK_URL=https://your-webhook-url.com +WEBHOOK_EMAIL=your-webhook-email +WEBHOOK_TOKEN=your-webhook-token \ No newline at end of file diff --git a/webhook/webhook.go b/webhook/webhook.go new file mode 100644 index 0000000..9f4071d --- /dev/null +++ b/webhook/webhook.go @@ -0,0 +1,20 @@ +// Package webhook provides a generic webhook interface for sending messages +// with channel, topic, and message parameters. +package webhook + +import ( + "time" +) + +// WebhookMessage represents the structure of a webhook message +type WebhookMessage struct { + Channel string `json:"channel"` + Topic string `json:"topic"` + Message string `json:"message"` + Timestamp time.Time `json:"timestamp"` +} + +// WebhookInterface defines the contract for webhook operations +type WebhookInterface interface { + Post(channel, topic, message string) error +} diff --git a/webhook/zulip.go b/webhook/zulip.go new file mode 100644 index 0000000..8329813 --- /dev/null +++ b/webhook/zulip.go @@ -0,0 +1,66 @@ +// Package webhook provides Zulip webhook implementation +package webhook + +import ( + "fmt" + "net/http" + "net/url" + "strings" + "time" + + logger "git.site.quack-lab.dev/dave/cylogger" +) + +// ZulipWebhook implements WebhookInterface for Zulip +type ZulipWebhook struct { + url string + email string + token string + client *http.Client +} + +// NewZulipWebhook creates a new Zulip webhook client +func NewZulipWebhook(url, email, token string) *ZulipWebhook { + logger.Info("Zulip webhook client initialized with email: %s", email) + + return &ZulipWebhook{ + url: url, + email: email, + token: token, + client: &http.Client{ + Timeout: 30 * time.Second, + }, + } +} + +// Post sends a message to Zulip +func (z *ZulipWebhook) Post(channel, topic, message string) error { + logger.Debug("Sending Zulip message to channel: %s, topic: %s", channel, topic) + + data := url.Values{} + data.Set("type", "stream") + data.Set("to", channel) + data.Set("topic", topic) + data.Set("content", message) + + req, err := http.NewRequest("POST", z.url, strings.NewReader(data.Encode())) + if err != nil { + return fmt.Errorf("failed to create zulip request: %w", err) + } + + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.SetBasicAuth(z.email, z.token) + + resp, err := z.client.Do(req) + if err != nil { + return fmt.Errorf("failed to send zulip message: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return fmt.Errorf("zulip request failed with status: %d", resp.StatusCode) + } + + logger.Info("Zulip message sent successfully to channel: %s, topic: %s", channel, topic) + return nil +}