github.com/mailgun/mailgun-go/v3@v3.6.4/spam_complaints.go (about) 1 package mailgun 2 3 import ( 4 "context" 5 "strconv" 6 ) 7 8 const ( 9 complaintsEndpoint = "complaints" 10 ) 11 12 // Complaint structures track how many times one of your emails have been marked as spam. 13 // the recipient thought your messages were not solicited. 14 type Complaint struct { 15 Count int `json:"count"` 16 CreatedAt RFC2822Time `json:"created_at"` 17 Address string `json:"address"` 18 } 19 20 type complaintsResponse struct { 21 Paging Paging `json:"paging"` 22 Items []Complaint `json:"items"` 23 } 24 25 // ListComplaints returns a set of spam complaints registered against your domain. 26 // Recipients of your messages can click on a link which sends feedback to Mailgun 27 // indicating that the message they received is, to them, spam. 28 func (mg *MailgunImpl) ListComplaints(opts *ListOptions) *ComplaintsIterator { 29 r := newHTTPRequest(generateApiUrl(mg, complaintsEndpoint)) 30 r.setClient(mg.Client()) 31 r.setBasicAuth(basicAuthUser, mg.APIKey()) 32 if opts != nil { 33 if opts.Limit != 0 { 34 r.addParameter("limit", strconv.Itoa(opts.Limit)) 35 } 36 } 37 url, err := r.generateUrlWithParameters() 38 return &ComplaintsIterator{ 39 mg: mg, 40 complaintsResponse: complaintsResponse{Paging: Paging{Next: url, First: url}}, 41 err: err, 42 } 43 } 44 45 type ComplaintsIterator struct { 46 complaintsResponse 47 mg Mailgun 48 err error 49 } 50 51 // If an error occurred during iteration `Err()` will return non nil 52 func (ci *ComplaintsIterator) Err() error { 53 return ci.err 54 } 55 56 // Next retrieves the next page of items from the api. Returns false when there 57 // no more pages to retrieve or if there was an error. Use `.Err()` to retrieve 58 // the error 59 func (ci *ComplaintsIterator) Next(ctx context.Context, items *[]Complaint) bool { 60 if ci.err != nil { 61 return false 62 } 63 ci.err = ci.fetch(ctx, ci.Paging.Next) 64 if ci.err != nil { 65 return false 66 } 67 cpy := make([]Complaint, len(ci.Items)) 68 copy(cpy, ci.Items) 69 *items = cpy 70 if len(ci.Items) == 0 { 71 return false 72 } 73 return true 74 } 75 76 // First retrieves the first page of items from the api. Returns false if there 77 // was an error. It also sets the iterator object to the first page. 78 // Use `.Err()` to retrieve the error. 79 func (ci *ComplaintsIterator) First(ctx context.Context, items *[]Complaint) bool { 80 if ci.err != nil { 81 return false 82 } 83 ci.err = ci.fetch(ctx, ci.Paging.First) 84 if ci.err != nil { 85 return false 86 } 87 cpy := make([]Complaint, len(ci.Items)) 88 copy(cpy, ci.Items) 89 *items = cpy 90 return true 91 } 92 93 // Last retrieves the last page of items from the api. 94 // Calling Last() is invalid unless you first call First() or Next() 95 // Returns false if there was an error. It also sets the iterator object 96 // to the last page. Use `.Err()` to retrieve the error. 97 func (ci *ComplaintsIterator) Last(ctx context.Context, items *[]Complaint) bool { 98 if ci.err != nil { 99 return false 100 } 101 ci.err = ci.fetch(ctx, ci.Paging.Last) 102 if ci.err != nil { 103 return false 104 } 105 cpy := make([]Complaint, len(ci.Items)) 106 copy(cpy, ci.Items) 107 *items = cpy 108 return true 109 } 110 111 // Previous retrieves the previous page of items from the api. Returns false when there 112 // no more pages to retrieve or if there was an error. Use `.Err()` to retrieve 113 // the error if any 114 func (ci *ComplaintsIterator) Previous(ctx context.Context, items *[]Complaint) bool { 115 if ci.err != nil { 116 return false 117 } 118 if ci.Paging.Previous == "" { 119 return false 120 } 121 ci.err = ci.fetch(ctx, ci.Paging.Previous) 122 if ci.err != nil { 123 return false 124 } 125 cpy := make([]Complaint, len(ci.Items)) 126 copy(cpy, ci.Items) 127 *items = cpy 128 if len(ci.Items) == 0 { 129 return false 130 } 131 return true 132 } 133 134 func (ci *ComplaintsIterator) fetch(ctx context.Context, url string) error { 135 r := newHTTPRequest(url) 136 r.setClient(ci.mg.Client()) 137 r.setBasicAuth(basicAuthUser, ci.mg.APIKey()) 138 139 return getResponseFromJSON(ctx, r, &ci.complaintsResponse) 140 } 141 142 // GetComplaint returns a single complaint record filed by a recipient at the email address provided. 143 // If no complaint exists, the Complaint instance returned will be empty. 144 func (mg *MailgunImpl) GetComplaint(ctx context.Context, address string) (Complaint, error) { 145 r := newHTTPRequest(generateApiUrl(mg, complaintsEndpoint) + "/" + address) 146 r.setClient(mg.Client()) 147 r.setBasicAuth(basicAuthUser, mg.APIKey()) 148 149 var c Complaint 150 err := getResponseFromJSON(ctx, r, &c) 151 return c, err 152 } 153 154 // CreateComplaint registers the specified address as a recipient who has complained of receiving spam 155 // from your domain. 156 func (mg *MailgunImpl) CreateComplaint(ctx context.Context, address string) error { 157 r := newHTTPRequest(generateApiUrl(mg, complaintsEndpoint)) 158 r.setClient(mg.Client()) 159 r.setBasicAuth(basicAuthUser, mg.APIKey()) 160 p := newUrlEncodedPayload() 161 p.addValue("address", address) 162 _, err := makePostRequest(ctx, r, p) 163 return err 164 } 165 166 // DeleteComplaint removes a previously registered e-mail address from the list of people who complained 167 // of receiving spam from your domain. 168 func (mg *MailgunImpl) DeleteComplaint(ctx context.Context, address string) error { 169 r := newHTTPRequest(generateApiUrl(mg, complaintsEndpoint) + "/" + address) 170 r.setClient(mg.Client()) 171 r.setBasicAuth(basicAuthUser, mg.APIKey()) 172 _, err := makeDeleteRequest(ctx, r) 173 return err 174 }