-
Notifications
You must be signed in to change notification settings - Fork 0
/
changeorg.go
129 lines (120 loc) · 3.68 KB
/
changeorg.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
// Package gochange provides functionalities in Go to add signatures
// to petitions via the Change.org API.
package gochange
// Imports required packages.
import (
"errors"
"net/http"
"net/url"
"github.com/judrov/gochange/util"
)
// Sets Host as the base url for the Change.org API.
const (
Host = "https://api.change.org/v1/"
)
// Declares the Changeorg data type
type ChangeOrg struct {
Key string
Host string
}
// NewChangeOrgClient instantiates a new ChangeOrg.
func NewChangeOrgClient(key string) *ChangeOrg {
return &ChangeOrg{Key: key, Host: Host}
}
// GetPetitionId gets the petition id for a given petition url.
func (c *ChangeOrg) GetPetitionId(args PetitionIdArgs) (*int, error) {
// sets up the request parameters.
v := url.Values{}
v.Set("api_key", c.Key)
if len(args.PetitionURL) > 0 {
v.Set("petition_url", args.PetitionURL)
}
// sets up the URL for requesting petition id.
url := c.Host + "petitions/get_id?" + v.Encode()
// makes request
data, err := http.Get(url)
if err != nil {
return nil, err
}
// parses the JSON response
var res PetitionIdResponse
if err := util.Unmarshal(data, &res); err != nil {
return nil, err
}
// checks error messages.
if msg := GetStrings(res.Messages); msg != "" {
err := errors.New(msg)
return nil, err
}
return &res.PetitionID, err
}
// GetAuthKey grants authorization to gather signatures for a petition
// and returns the authorization code. You will receive the code via email.
func (c *ChangeOrg) GetAuthKey(args AuthKeysArgs, secret string) (string, error) {
// sets up the petition parameters.
v := url.Values{}
v.Set("api_key", c.Key)
v.Set("petition_id", args.PetitionID)
v.Set("source_description", args.SourceDesc)
v.Set("source", args.Source)
v.Set("requester_email", args.RequesterEmail)
v.Set("timestamp", util.GetTimeNow())
v.Set("callback", args.Callback)
v.Set("endpoint", "/v1/petitions/"+args.PetitionID+"/auth_keys")
v.Set("rsig", util.Hash(v.Encode()+secret))
// sets up the URL for requesting authorization key for a petition.
url := c.Host + "petitions/" + args.PetitionID + "/auth_keys"
// makes the request.
var res AuthKeysResponse
if err := util.Post(url, v.Encode(), &res); err != nil {
return res.AuthKey, err
}
// checks error messages.
if msg := GetStrings(res.Messages); msg != "" {
err := errors.New(msg)
return res.AuthKey, err
}
return res.AuthKey, nil
}
// SignPetition adds a signature to a petition.
func (c *ChangeOrg) SignPetition(args PetitionArgs, secret string) (string, error) {
// sets up the signature parameters.
v := url.Values{}
v.Set("api_key", c.Key)
v.Set("source", args.Source)
v.Set("email", args.Email)
v.Set("first_name", args.FirstName)
v.Set("last_name", args.LastName)
v.Set("address", args.Address)
v.Set("city", args.City)
v.Set("state_province", args.State)
v.Set("postal_code", args.ZIP)
v.Set("country_code", args.Country)
v.Set("hidden", args.Hidden)
v.Set("timestamp", util.GetTimeNow())
v.Set("endpoint", "/v1/petitions/"+args.PetitionID+"/signatures")
v.Set("rsig", util.Hash(v.Encode()+secret+args.AuthKey))
// sets up the URL for adding petition signatures.
url := c.Host + "petitions/" + args.PetitionID + "/signatures"
// POST the parameters to the signature endpoint.
var res PetitionResponse
if err := util.Post(url, v.Encode(), &res); err != nil {
return res.Result, err
}
// checks error messages.
if msg := GetStrings(res.Messages); msg != "" {
err := errors.New(msg)
return res.Result, err
}
return res.Result, nil
}
// GetStrings returns the concatenation of strings from an array.
func GetStrings(messages []string) string {
msg := ""
if len(messages) > 0 {
for i := range messages {
msg += messages[i]
}
}
return msg
}