Codebase list golang-github-nlopes-slack / 6854e26
Add support for file uploads Norberto Lopes 9 years ago
5 changed file(s) with 153 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
00 - Add more tests!!!
11 - Add timeouts
2 - Add examples
32 - Fix the Websocket mess
4 - Implement Upload File
53 - Add support to have markdown hints
64 - See section Message Formatting at https://api.slack.com/docs/formatting
0 Nan Nan Nan Nan Nan Nan Nan Nan Batman
0 package main
1
2 import (
3 "fmt"
4
5 "github.com/nlopes/slack"
6 )
7
8 func main() {
9 api := slack.New("YOUR_TOKEN_HERE")
10 params := slack.FileUploadParameters{
11 Title: "Batman Example",
12 //Filetype: "txt",
13 File: "example.txt",
14 //Content: "Nan Nan Nan Nan Nan Nan Nan Nan Batman",
15 }
16 file, err := api.UploadFile(params)
17 if err != nil {
18 fmt.Printf("%s\n", err)
19 return
20 }
21 fmt.Printf("Name: %s, Url: %s\n", file.Name, file.Url)
22 }
11
22 import (
33 "errors"
4 "log"
54 "net/url"
65 "strconv"
6 "strings"
77 )
88
99 const (
7070 IsStarred bool `json:"is_starred"`
7171 }
7272
73 type FileUploadParameters struct {
74 File string
75 Content string
76 Filetype string
77 Filename string
78 Title string
79 InitialComment string
80 Channels []string
81 }
82
7383 type GetFilesParameters struct {
7484 UserId string
7585 TimestampFrom JSONTime
155165 return response.Files, &response.Paging, nil
156166 }
157167
158 func (api *Slack) UploadFile() {
159 log.Fatal("Not implemented yet")
160 }
168 func (api *Slack) UploadFile(params FileUploadParameters) (file *File, err error) {
169 // Test if user token is valid. This helps because client.Do doesn't like this for some reason. XXX: More
170 // investigation needed, but for now this will do.
171 _, err = api.AuthTest()
172 if err != nil {
173 return nil, err
174 }
175 response := &fileResponseFull{}
176 values := url.Values{
177 "token": {api.config.token},
178 }
179 if params.Filetype != "" {
180 values.Add("filetype", params.Filetype)
181 }
182 if params.Filename != "" {
183 values.Add("filename", params.Filename)
184 }
185 if params.Title != "" {
186 values.Add("title", params.Title)
187 }
188 if params.InitialComment != "" {
189 values.Add("initial_comment", params.InitialComment)
190 }
191 if len(params.Channels) != 0 {
192 values.Add("channels", strings.Join(params.Channels, ","))
193 }
194 if params.Content != "" {
195 values.Add("content", params.Content)
196 err = ParseResponse("files.upload", values, response, api.debug)
197 } else if params.File != "" {
198 err = parseResponseMultipart("files.upload", params.File, values, response, api.debug)
199 }
200 if err != nil {
201 return nil, err
202 }
203 if !response.Ok {
204 return nil, errors.New(response.Error)
205 }
206 return &response.File, nil
207 }
22 import (
33 "bytes"
44 "encoding/json"
5 "errors"
6 "io"
57 "io/ioutil"
68 "log"
9 "mime/multipart"
710 "net/http"
811 "net/url"
12 "os"
13 "path/filepath"
914 )
15
16 func fileUploadReq(path, fpath string, values url.Values) (*http.Request, error) {
17 fullpath, err := filepath.Abs(fpath)
18 if err != nil {
19 return nil, err
20 }
21 file, err := os.Open(fullpath)
22 if err != nil {
23 return nil, err
24 }
25 defer file.Close()
26
27 body := &bytes.Buffer{}
28 wr := multipart.NewWriter(body)
29
30 ioWriter, err := wr.CreateFormFile("file", filepath.Base(fullpath))
31 if err != nil {
32 wr.Close()
33 return nil, err
34 }
35 bytes, err := io.Copy(ioWriter, file)
36 if err != nil {
37 wr.Close()
38 return nil, err
39 }
40 // Close the multipart writer or the footer won't be written
41 wr.Close()
42 stat, err := file.Stat()
43 if err != nil {
44 return nil, err
45 }
46 if bytes != stat.Size() {
47 return nil, errors.New("could not read the whole file")
48 }
49 req, err := http.NewRequest("POST", path, body)
50 if err != nil {
51 return nil, err
52 }
53 req.Header.Add("Content-Type", wr.FormDataContentType())
54 req.URL.RawQuery = (values).Encode()
55 return req, nil
56 }
57
58 func parseResponseBody(body io.ReadCloser, intf *interface{}, debug bool) error {
59 var decoder *json.Decoder
60 if debug {
61 response, err := ioutil.ReadAll(body)
62 if err != nil {
63 return err
64 }
65 log.Println(string(response))
66 decoder = json.NewDecoder(bytes.NewReader(response))
67 } else {
68 decoder = json.NewDecoder(body)
69 }
70 if err := decoder.Decode(&intf); err != nil {
71 return err
72 }
73 return nil
74
75 }
76
77 func parseResponseMultipart(path string, filepath string, values url.Values, intf interface{}, debug bool) error {
78 req, err := fileUploadReq(SLACK_API+path, filepath, values)
79 client := &http.Client{}
80 resp, err := client.Do(req)
81 if err != nil {
82 return err
83 }
84 defer resp.Body.Close()
85 return parseResponseBody(resp.Body, &intf, debug)
86 }
1087
1188 func ParseResponse(path string, values url.Values, intf interface{}, debug bool) error {
1289 resp, err := http.PostForm(SLACK_API+path, values)
1491 return err
1592 }
1693 defer resp.Body.Close()
17
18 var decoder *json.Decoder
19 if debug {
20 response, err := ioutil.ReadAll(resp.Body)
21 if err != nil {
22 return err
23 }
24 log.Println(string(response))
25 decoder = json.NewDecoder(bytes.NewReader(response))
26 } else {
27 decoder = json.NewDecoder(resp.Body)
28 }
29 if err := decoder.Decode(&intf); err != nil {
30 return err
31 }
32 return nil
94 return parseResponseBody(resp.Body, &intf, debug)
3395 }