github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/prow/slack/client.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package slack 18 19 import ( 20 "errors" 21 "fmt" 22 "io/ioutil" 23 "net/http" 24 "net/url" 25 "strings" 26 27 "github.com/sirupsen/logrus" 28 ) 29 30 type Logger interface { 31 Debugf(s string, v ...interface{}) 32 } 33 34 // Client allows you to provide connection to Slack API Server 35 // It contains a token that allows to authenticate connection to post and work with channels in the domain 36 type Client struct { 37 // If logger is non-nil, log all method calls with it. 38 logger Logger 39 40 token string 41 fake bool 42 } 43 44 const ( 45 chatPostMessage = "https://slack.com/api/chat.postMessage" 46 47 botName = "prow" 48 botIconEmoji = ":prow:" 49 ) 50 51 // NewClient creates a slack client with an API token. 52 func NewClient(token string) *Client { 53 return &Client{ 54 logger: logrus.WithField("client", "slack"), 55 token: token, 56 } 57 } 58 59 // NewFakeClient returns a client that takes no actions. 60 func NewFakeClient() *Client { 61 return &Client{ 62 fake: true, 63 } 64 } 65 66 func (sl *Client) log(methodName string, args ...interface{}) { 67 if sl.logger == nil { 68 return 69 } 70 var as []string 71 for _, arg := range args { 72 as = append(as, fmt.Sprintf("%v", arg)) 73 } 74 sl.logger.Debugf("%s(%s)", methodName, strings.Join(as, ", ")) 75 } 76 77 func (sl *Client) urlValues() *url.Values { 78 uv := url.Values{} 79 uv.Add("username", botName) 80 uv.Add("icon_emoji", botIconEmoji) 81 uv.Add("token", sl.token) 82 return &uv 83 } 84 85 func (sl *Client) postMessage(url string, uv *url.Values) ([]byte, error) { 86 resp, err := http.PostForm(url, *uv) 87 if err != nil { 88 return nil, err 89 } 90 defer resp.Body.Close() 91 92 if resp.StatusCode != 200 { 93 t, _ := ioutil.ReadAll(resp.Body) 94 return nil, errors.New(string(t)) 95 } 96 t, _ := ioutil.ReadAll(resp.Body) 97 return t, nil 98 } 99 100 // WriteMessage adds text to channel 101 func (sl *Client) WriteMessage(text, channel string) error { 102 sl.log("WriteMessage", text, channel) 103 if sl.fake { 104 return nil 105 } 106 var uv *url.Values = sl.urlValues() 107 uv.Add("channel", channel) 108 uv.Add("text", text) 109 110 _, err := sl.postMessage(chatPostMessage, uv) 111 return err 112 }