aboutsummaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
authorShulhan <m.shulhan@gmail.com>2021-02-12 01:07:40 +0700
committerShulhan <ms@kilabit.info>2021-02-12 03:10:05 +0700
commit3bc9b50c4a252f665ddea44401d39287e299448c (patch)
tree3a8245f5ab9401d882b9eab710148062db1b3b32 /api
parent558bdae00a3906e247d7d2c2e36c13a71d6c8d45 (diff)
downloadpakakeh.go-3bc9b50c4a252f665ddea44401d39287e299448c.tar.xz
api/slack: implement client for webhook
Unlike PostWebhook API which is close and open one connection at the time, the WebhookClient is keep open. Use the WebhookClient for long running program that post message every minutes or seconds.
Diffstat (limited to 'api')
-rw-r--r--api/slack/webhook_client.go94
1 files changed, 94 insertions, 0 deletions
diff --git a/api/slack/webhook_client.go b/api/slack/webhook_client.go
new file mode 100644
index 00000000..597dbe1a
--- /dev/null
+++ b/api/slack/webhook_client.go
@@ -0,0 +1,94 @@
+// Copyright 2021, Shulhan <ms@kilabit.info>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package slack
+
+import (
+ "fmt"
+ "net/http"
+ "net/url"
+ "time"
+
+ libhttp "github.com/shuLhan/share/lib/http"
+)
+
+//
+// WebhookClient for slack.
+// Use this for long running program that post message every minutes or
+// seconds.
+//
+type WebhookClient struct {
+ *libhttp.Client
+ webhookPath string
+ user string
+ channel string
+}
+
+//
+// NewWebhookClient create new slack client that will write the message using
+// webhook URL and optional user and channel.
+//
+func NewWebhookClient(webhookURL, user, channel string) (wcl *WebhookClient, err error) {
+ wurl, err := url.Parse(webhookURL)
+ if err != nil {
+ return nil, fmt.Errorf("NewWebhookClient: %w", err)
+ }
+
+ host := fmt.Sprintf("%s://%s", wurl.Scheme, wurl.Host)
+ wcl = &WebhookClient{
+ Client: libhttp.NewClient(host, nil, false),
+ webhookPath: wurl.Path,
+ user: user,
+ channel: channel,
+ }
+
+ wcl.Client.Timeout = 5 * time.Second
+
+ return wcl, nil
+}
+
+//
+// Post the Message as is.
+//
+func (wcl *WebhookClient) Post(msg *Message) (err error) {
+ if wcl.Client == nil {
+ return nil
+ }
+ httpRes, resBody, err := wcl.PostJSON(nil, wcl.webhookPath, msg)
+ if err != nil {
+ return fmt.Errorf("WebhookClient.Post: %w", err)
+ }
+ if httpRes.StatusCode != http.StatusOK {
+ return fmt.Errorf("Post: %s: %s\n", httpRes.Status, resBody)
+ }
+ return nil
+}
+
+//
+// Write wrap the raw bytes into Message with the user and channel previously
+// defined when creating the client, and post it to slack.
+//
+func (wcl *WebhookClient) Write(b []byte) (n int, err error) {
+ if wcl.Client == nil {
+ return 0, nil
+ }
+ msg := &Message{
+ Channel: wcl.channel,
+ Username: wcl.user,
+ Text: string(b),
+ }
+ err = wcl.Post(msg)
+ if err != nil {
+ return 0, fmt.Errorf("Write: %w", err)
+ }
+ return len(b), nil
+}
+
+//
+// Close the client connection.
+//
+func (wcl *WebhookClient) Close() (err error) {
+ wcl.Client = nil
+ return nil
+}