-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.go
69 lines (59 loc) · 2.07 KB
/
proxy.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
package main
import (
"log"
"net/http"
"github.com/julienschmidt/httprouter"
"google.golang.org/api/script/v1"
)
// Middleware validates and converts params for usage in google apps script
type Middleware func(string) (interface{}, error)
// Proxy acts as a relay between client and google apps scripts adding authentication layer
type Proxy struct {
Service *script.Service
Script string
Name string
Params map[string]Middleware
}
// Handle is a http.Handler for accepting requests at specific endpoint
func (p Proxy) Handle(rw http.ResponseWriter, req *http.Request, ps httprouter.Params) {
request := &script.ExecutionRequest{Function: p.Name}
//Validate and convert parameters
for key, mw := range p.Params {
value, err := mw(ps.ByName(key))
if err != nil {
rw.WriteHeader(400) //Bad request
return
}
request.Parameters = append(request.Parameters, value)
}
resp, err := p.Service.Scripts.Run(p.Script, request).Do()
if err != nil {
rw.WriteHeader(500) //Internal server error
log.Println("Got error while conctacting google app execution script ", err, request)
return
}
if resp.Error != nil {
rw.WriteHeader(500)
err := resp.Error.Details[0].(map[string]interface{})
log.Println("Script error message: ", err["errorMessage"])
//Borrowed from https://developers.google.com/apps-script/guides/rest/quickstart/go
if err["scriptStackTraceElements"] != nil {
// There may not be a stacktrace if the script didn't start executing.
log.Printf("Script error stacktrace:\n")
for _, trace := range err["scriptStackTraceElements"].([]interface{}) {
t := trace.(map[string]interface{})
log.Printf("\t%s: %d\n", t["function"], int(t["lineNumber"].(float64)))
}
}
return
}
//TODO: Add option to alter this, probably middleware
rw.Header().Set("Content-Type", "application/json")
rw.Header().Set("Access-Control-Allow-Origin", "*")
//rw.Write([]byte(fmt.Sprintf("%+v", resp.Response)))
if value, ok := resp.Response.(map[string]interface{})["result"].(string); ok {
rw.Write([]byte(value))
} else {
rw.Write([]byte("null"))
}
}