forked from emiddleton/gads
-
Notifications
You must be signed in to change notification settings - Fork 1
/
managed_customer.go
217 lines (191 loc) · 6.23 KB
/
managed_customer.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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
package gads
import "encoding/xml"
// ManagedCustomerService represents the api that handle links between accounts
type ManagedCustomerService struct {
Auth
}
// LinkStatus represents the state of the link
type LinkStatus string
const (
LinkStatusActive LinkStatus = "ACTIVE"
LinkStatusInactive LinkStatus = "INACTIVE"
LinkStatusPending LinkStatus = "PENDING"
LinkStatusRefused LinkStatus = "REFUSED"
LinkStatusCancelled LinkStatus = "CANCELLED"
LinkStatusUnkwown LinkStatus = "UNKNOWN"
)
// NewManagedCustomerService is the ManagedCustomerService constructor
func NewManagedCustomerService(auth *Auth) *ManagedCustomerService {
return &ManagedCustomerService{Auth: *auth}
}
// ManagedCustomer represents the accounts handled by the current clientCustomerID
// https://developers.google.com/adwords/api/docs/reference/v201809/ManagedCustomerService.ManagedCustomer
type ManagedCustomer struct {
Name string `xml:"name,omitempty"`
CustomerID uint `xml:"customerId,omitempty"`
CanManageClients bool `xml:"canManageClients,omitempty"`
CurrencyCode string `xml:"currencyCode,omitempty"`
TestAccount bool `xml:"testAccount,omitempty"`
DateTimeZone string `xml:"dateTimeZone,omitempty"`
ExcludeHiddenAccount bool `xml:"excludeHiddenAccounts,omitempty"`
}
// ManagedCustomerLinkOperations are used when you change links between mcc and classic adwords account
type ManagedCustomerLinkOperations map[string][]*ManagedCustomerLink
// ManagedCustomerLink represents the status of the link between the current
// account and the account it manages
// https://developers.google.com/adwords/api/docs/reference/v201809/ManagedCustomerService.ManagedCustomerLink
type ManagedCustomerLink struct {
ManagerCustomerID uint `xml:"managerCustomerId,omitempty"`
ClientCustomerId uint `xml:"clientCustomerId,omitempty"`
LinkStatus string `xml:"linkStatus,omitempty"`
PendingDescriptiveName string `xml:"pendingDescriptiveName,omitempty"`
Hidden bool `xml:"isHidden,omitempty"`
}
// ManagedCustomerLinkResult is the response of the MutateLink service
// @see https://developers.google.com/adwords/api/docs/reference/v201809/ManagedCustomerService.MutateLinkResults
type ManagedCustomerLinkResult struct {
Links []*ManagedCustomerLink `xml:"links,omitempty"`
}
// ManagedCustomerMoveOperations are performed when you move an account inside the hierarchy
type ManagedCustomerMoveOperations map[string][]ManagedCustomerMoveOperation
// ManagedCustomerMoveOperation is one operation in the move actions
type ManagedCustomerMoveOperation struct {
OldManagerCustomerId uint
Link ManagedCustomerLink
}
// Get fetches the managed customers of the current account
func (m *ManagedCustomerService) Get(selector Selector) (
customers []ManagedCustomer,
managedCustomerLinks []ManagedCustomerLink,
totalCount int64,
err error,
) {
selector.XMLName = xml.Name{"", "serviceSelector"}
var respBody []byte
respBody, err = m.Auth.request(
managedCustomerServiceUrl,
"get",
struct {
XMLName xml.Name
Sel Selector
}{
XMLName: xml.Name{
Space: managedCustomerUrl,
Local: "get",
},
Sel: selector,
},
)
if err != nil {
return
}
getResp := struct {
Size int64 `xml:"rval>totalNumEntries"`
ManagedCustomers []ManagedCustomer `xml:"rval>entries"`
ManagedCustomerLink []ManagedCustomerLink `xml:"rval>links"`
}{}
err = xml.Unmarshal(respBody, &getResp)
if err != nil {
return
}
totalCount = getResp.Size
return getResp.ManagedCustomers, getResp.ManagedCustomerLink, totalCount, err
}
// MutateManager takes a budgetOperations and creates, modifies or destroys the associated budgets.
func (m *ManagedCustomerService) MutateManager(mcmOps ManagedCustomerMoveOperations) (links []ManagedCustomerLink, err error) {
type managedCustomerMoveOperation struct {
Action string `xml:"https://adwords.google.com/api/adwords/cm/v201809 operator"`
Link ManagedCustomerLink `xml:"operand"`
OldManagerCustomerId uint `xml:"oldManagerCustomerId"`
}
operations := []managedCustomerMoveOperation{}
for action, ops := range mcmOps {
for _, op := range ops {
operations = append(
operations,
managedCustomerMoveOperation{
Action: action,
Link: op.Link,
OldManagerCustomerId: op.OldManagerCustomerId,
},
)
}
}
respBody, err := m.Auth.request(
managedCustomerServiceUrl,
"mutateManager",
struct {
XMLName xml.Name
Ops []managedCustomerMoveOperation `xml:"operations"`
}{
XMLName: xml.Name{
Space: managedCustomerUrl,
Local: "mutateManager",
},
Ops: operations,
},
)
if err != nil {
return links, err
}
mutateResp := struct {
BaseResponse
Links []ManagedCustomerLink `xml:"rval>value"`
}{}
err = xml.Unmarshal(respBody, &mutateResp)
if err != nil {
return links, err
}
if len(mutateResp.PartialFailureErrors) > 0 {
err = mutateResp.PartialFailureErrors
}
return mutateResp.Links, err
}
// MutateLink changes the links between mcc and classic adwords account
func (m *ManagedCustomerService) MutateLink(mcl ManagedCustomerLinkOperations) ([]*ManagedCustomerLink, error) {
type linkOperation struct {
Action string `xml:"https://adwords.google.com/api/adwords/cm/v201809 operator"`
Link *ManagedCustomerLink `xml:"operand"`
}
operations := []*linkOperation{}
for action, ops := range mcl {
for _, op := range ops {
operations = append(
operations,
&linkOperation{
Action: action,
Link: op,
},
)
}
}
respBody, err := m.Auth.request(
managedCustomerServiceUrl,
"mutateLink",
struct {
XMLName xml.Name
Ops []*linkOperation `xml:"operations"`
}{
XMLName: xml.Name{
Space: managedCustomerUrl,
Local: "mutateLink",
},
Ops: operations,
},
)
if err != nil {
return nil, err
}
mutateResp := struct {
BaseResponse
Links []*ManagedCustomerLink `xml:"rval>value>links"`
}{}
err = xml.Unmarshal(respBody, &mutateResp)
if err != nil {
return nil, err
}
if len(mutateResp.PartialFailureErrors) > 0 {
err = mutateResp.PartialFailureErrors
}
return mutateResp.Links, err
}