-
Notifications
You must be signed in to change notification settings - Fork 1
/
imgur.go
143 lines (129 loc) · 3.94 KB
/
imgur.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package ares
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"mime/multipart"
"net/http"
"strings"
"time"
)
type ImgurResponse struct {
Data struct {
Deletehash string `json:"deletehash"`
Link string `json:"link"`
} `json:"data"`
Success bool `json:"success"`
Status int `json:"status"`
}
type VgyResponse struct {
Error bool `json:"error"`
URL string `json:"url"`
Image string `json:"image"`
Size int `json:"size"`
Filename string `json:"filename"`
Ext string `json:"ext"`
Delete string `json:"delete"`
}
type UploadResponse struct {
Link string
DeleteLink string
Status bool
}
func uploadToImgur(fileURL, slackAccessToken, imgurClientID string) *UploadResponse {
// CAUTION: REALLY BAD CODE!
result := &UploadResponse{}
client := &http.Client{
Timeout: 3 * time.Minute,
}
count := 0
retryLabel:
req, err := http.NewRequest("GET", fileURL, nil)
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", slackAccessToken))
resp, err := client.Do(req)
if err != nil {
log.Println("Failed to download file from Slack: ", err.Error())
log.Println("File url: ", fileURL)
return result
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
// not a valid response
log.Println("Failed to download file from Slack:", resp.StatusCode)
return result
}
// currently for some reason uploads to imgur are failing. following function first tries
// to upload to Imgur and if that fails it tries to upload to Vgy
imgBody, err := ioutil.ReadAll(resp.Body)
imgurURL := "https://api.imgur.com/3/image"
imgReq, err := http.NewRequest("POST", imgurURL, bytes.NewBuffer(imgBody))
imgReq.Header.Set("Authorization", fmt.Sprintf("Client-ID %s", imgurClientID))
imgResp, err := client.Do(imgReq)
if err != nil {
log.Fatal("Failed to connect to Imgur: ", err.Error())
}
defer imgResp.Body.Close()
if imgResp.StatusCode == 200 {
var imgurResponse *ImgurResponse
if err = json.NewDecoder(imgResp.Body).Decode(&imgurResponse); err != nil {
log.Println("Failed to decode response from Imgur API: ", err.Error())
return result
}
return formatImgurResponse(imgurResponse)
}
// log.Println("Received a non-200 status while uploading to Imgur: ", imgResp.StatusCode)
// imgRespBody, _ := ioutil.ReadAll(imgResp.Body)
// log.Println("Imgur resp body for fail:", string(imgRespBody))
// trying vgy
vgyURL := "https://vgy.me/upload"
var b bytes.Buffer
w := multipart.NewWriter(&b)
fw, err := w.CreateFormFile("file", getFileNameFromSlackURL(fileURL))
io.Copy(fw, bytes.NewReader(imgBody))
w.Close()
imgReq, err = http.NewRequest("POST", vgyURL, &b)
imgReq.Header.Set("Content-Type", w.FormDataContentType())
vgResp, err := client.Do(imgReq)
defer vgResp.Body.Close()
if vgResp.StatusCode != 200 {
count = count + 1
if count < 3 {
log.Printf("count: %d for %s\n", count, fileURL)
goto retryLabel
}
log.Println("Received a non-200 status while uploading to Vgy: ", vgResp.StatusCode)
// vgRespBody, _ := ioutil.ReadAll(vgResp.Body)
// log.Println("Vgy resp body for fail:", string(vgRespBody))
return result
}
var vgResult *VgyResponse
if err = json.NewDecoder(vgResp.Body).Decode(&vgResult); err != nil {
log.Println("Failed to decode Vgy from Imgur API: ", err.Error())
return result
}
return formatVgyResponse(vgResult)
}
// Slack URLs are of the format:
// https://files.slack.com/files-pri/T06V-F84/download/ggwp.png
// this function returns `ggwp.png`
func getFileNameFromSlackURL(url string) string {
s := strings.Split(url, "/")
return s[len(s)-1]
}
func formatImgurResponse(response *ImgurResponse) *UploadResponse {
return &UploadResponse{
Status: true,
Link: response.Data.Link,
DeleteLink: fmt.Sprintf("https://imgur.com/delete/%s", response.Data.Deletehash),
}
}
func formatVgyResponse(response *VgyResponse) *UploadResponse {
return &UploadResponse{
Status: true,
Link: response.Image,
DeleteLink: response.Delete,
}
}