/
request.go
154 lines (136 loc) · 5.12 KB
/
request.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
144
145
146
147
148
149
150
151
152
153
154
// Provides a client for Open311. May be San Francisco specific for now.
// http://wiki.open311.org/GeoReport_v2/
package open311
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"time"
"github.com/google/go-querystring/query"
)
// Location is the location for a service request. Either:
// Lat/Long or Address or AddressID is required.
type Location struct {
Lat float64 `json:"lat"`
Long float64 `json:"long"`
Address string `json:"address_string"`
AddressID string `json:"address_id"`
}
// ServiceRequest is used to create a new service request
type ServiceRequest struct {
Lat float64 `json:"lat" url:"lat,omitempty"`
Long float64 `json:"long" url:"long,omitempty"`
Address string `json:"address_string" url:"address_string,omitempty"`
AddressID string `json:"address_id" url:"address_id,omitempty"`
Email string `json:"email" url:"email"`
DeviceID string `json:"device_id" url:"device_id"`
AccountID string `json:"account_id" url:"account_id"`
FirstName string `json:"first_name" url:"first_name"`
LastName string `json:"last_name" url:"last_name"`
Phone string `json:"phone" url:"phone"`
Description string `json:"description" url:"description"`
MediaURL string `json:"media_url" url:"media_url"`
}
// ServiceRequestCreation contains the response for a service request
type ServiceRequestCreation struct {
ID string `json:"service_request_id"`
Token string `json:"token"`
ServiceNotice string `json:"service_notice"`
AccountID string `json:"account_id"`
}
// ReqType is a required attribute for creating a service request
const (
Poop = iota
Needles
Garbage
)
// Cleanup is the service code for cleaning things in SF
const Cleanup = "518d5892601827e3880000c5"
// PostServiceRequest creates a new service request
// loc is lat/long or address_string or address_id
// attr is an array of key/values
func (c *Client) PostServiceRequest(code string, reqType int, req ServiceRequest) (ServiceRequestCreation, error) {
var r []ServiceRequestCreation
v, err := query.Values(req)
if err != nil {
return ServiceRequestCreation{}, err
}
v.Add("api_key", c.key)
v.Add("jurisdiction_id", c.jurisdiction)
v.Add("service_code", code)
var form string
switch reqType {
case Poop:
form = v.Encode() + "&attribute[request_type][]=Human_waste_or_urine"
case Needles:
form = v.Encode() + "&attribute[request_type][]=Needles_less_than_20"
case Garbage:
form = v.Encode() + "&attribute[request_type][]=Other_loose_garbage_debris_yard_waste"
}
formBody := strings.NewReader(form)
resp, err := http.Post(c.url+"/requests.json", "application/x-www-form-urlencoded", formBody)
if err != nil {
return ServiceRequestCreation{}, err
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return ServiceRequestCreation{}, err
}
if err = json.Unmarshal(body, &r); err != nil {
return ServiceRequestCreation{}, err
}
return r[0], nil
}
// ServiceRequestID is returned when looking up with a token
type ServiceRequestID struct {
ID string `json:"service_request_id"`
Token string `json:"token"`
}
// GetServiceRequestID returns a service request ID given a token
// XXX SF311 uses the token as the request ID
// XXX this endpoint does not return the correct format
// http://wiki.open311.org/GeoReport_v2/#get-service_request_id-from-a-token
func (c *Client) GetServiceRequestID(token string) (string, error) {
var id ServiceRequestID
getURL := fmt.Sprintf("%s/tokens/%s.json", c.url, token)
err := c.get(getURL, &id)
return id.ID, err
}
// ServiceRequestOpts contains optional arguments when getting service requests
type ServiceRequestOpts struct {
ServiceRequestID string `json:"service_request_id"`
ServiceCode string `json:"service_code"`
StartDate time.Time `json:"start_date"`
EndData time.Time `json:"end_date"`
Status string `json:"status"`
}
// ServiceRequestResponse is returned after opening a service request
type ServiceRequestResponse struct {
ServiceRequestID string `json:"service_request_id"`
Status string `json:"status"`
StatusNotes string `json:"status_notes"`
ServiceName string `json:"service_name"`
ServiceCode string `json:"service_code"`
Description string `json:"description"`
AgencyResponsible string `json:"agency_responsible"`
ServiceNotice string `json:"service_notice"`
RequestedTime time.Time `json:"requested_datetime"`
UpdateTime time.Time `json:"updated_datetime"`
ExpectedTime time.Time `json:"expected_datetime"`
Zipcode string `json:"zipcode"`
Location
}
// GetServiceRequests returns all service requests in the jurisdiction's database
func (c *Client) GetServiceRequests(opts ServiceRequestOpts) ([]ServiceRequestResponse, error) {
return []ServiceRequestResponse{}, nil
}
// GetServiceRequest returns details for a specific service request
func (c *Client) GetServiceRequest(id string) (ServiceRequestResponse, error) {
var s []ServiceRequestResponse
if err := c.get(fmt.Sprintf("/requests/%s.json", id), &s); err != nil {
return ServiceRequestResponse{}, err
}
return s[0], nil
}