├── .github
├── CODEOWNERS
├── renovate.json
└── workflows
│ └── test.yaml
├── .gitignore
├── LICENSE
├── Readme.md
├── activity.go
├── activity_test.go
├── analytics.go
├── analytics_test.go
├── api_quota.go
├── bulk_email.go
├── client_test.go
├── domains.go
├── domains_test.go
├── email.go
├── email_test.go
├── email_verification.go
├── go.mod
├── go.sum
├── helpers.go
├── inbound.go
├── mailersend.go
├── mailersend_test.go
├── messages.go
├── messages_test.go
├── recipients.go
├── schedule_message.go
├── sender_identities.go
├── sms.go
├── sms_activity.go
├── sms_inbound.go
├── sms_messages.go
├── sms_numbers.go
├── sms_recipients.go
├── sms_webhooks.go
├── suppressions.go
├── templates.go
├── tokens.go
└── webhooks.go
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @mailersend/go-sdk-maintainers
2 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/.github/workflows/test.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | on:
3 | pull_request:
4 | branches:
5 | - main
6 | name: Test
7 | jobs:
8 | test:
9 | runs-on: ${{ matrix.os }}
10 | strategy:
11 | matrix:
12 | os: [ubuntu-24.04]
13 | go: ["1.17", "1.18", "1.19"]
14 | name: Test on go ${{ matrix.go }} and ${{ matrix.os }}
15 | steps:
16 | - uses: actions/checkout@v4
17 | - name: Setup go
18 | uses: actions/setup-go@v5
19 | with:
20 | go-version: ${{ matrix.go }}
21 | - run: go test
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### Go ###
2 | # Binaries for programs and plugins
3 | *.exe
4 | *.exe~
5 | *.dll
6 | *.so
7 | *.dylib
8 |
9 | # Test binary, built with `go test -c`
10 | *.test
11 |
12 | # Output of the go coverage tool, specifically when used with LiteIDE
13 | *.out
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 MailerSend
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | MailerSend Golang SDK
4 |
5 | [](./LICENSE)
6 | [](https://github.com/mailersend/mailersend-go/actions/workflows/test.yaml)
7 |
8 | # Table of Contents
9 | - [Installation](#installation)
10 | - [Usage](#usage)
11 | - [Email](#email)
12 | - [Send an email](#send-an-email)
13 | - [Add CC, BCC recipients](#add-cc-bcc-recipients)
14 | - [Send a template-based email](#send-a-template-based-email)
15 | - [Personalization](#personalization)
16 | - [Send email with attachment](#send-email-with-attachment)
17 | - [Send email with inline attachment](#send-email-with-inline-attachment)
18 | - [Bulk Email](#bulk-email)
19 | - [Send bulk email](#send-bulk-email)
20 | - [Get bulk email status](#get-bulk-email-status)
21 | - [Activity](#activity)
22 | - [Get a list of activities](#get-a-list-of-activities)
23 | - [Analytics](#analytics)
24 | - [Activity data by date](#activity-data-by-date)
25 | - [Opens by country](#opens-by-country)
26 | - [Opens by user-agent name](#opens-by-user-agent-name)
27 | - [Opens by reading environment](#opens-by-reading-environment)
28 | - [Inbound Routes](#inbound-routes)
29 | - [Get a list of inbound routes](#get-a-list-of-inbound-routes)
30 | - [Get a single inbound route](#get-a-single-inbound-route)
31 | - [Add an inbound route](#add-an-inbound-route)
32 | - [Update an inbound route](#update-an-inbound-route)
33 | - [Delete an inbound route](#delete-an-inbound-route)
34 | - [Domains](#domains)
35 | - [Get a list of domains](#get-a-list-of-domains)
36 | - [Get a single domain](#get-a-single-domain)
37 | - [Delete a domain](#delete-a-domain)
38 | - [Add a Domain](#add-a-domain)
39 | - [Get DNS Records](#get-dns-records)
40 | - [Get verification status](#get-verification-status)
41 | - [Get a list of recipients per domain](#get-a-list-of-recipients-per-domain)
42 | - [Update domain settings](#update-domain-settings)
43 | - [Messages](#messages)
44 | - [Get a list of messages](#get-a-list-of-messages)
45 | - [Get a single message](#get-a-single-message)
46 | - [Scheduled Messages](#scheduled-messages)
47 | - [Get a list of scheduled messages](#get-a-list-of-scheduled-messages)
48 | - [Get a single scheduled message](#get-a-single-scheduled-message)
49 | - [Delete a scheduled message](#delete-a-scheduled-message)
50 | - [Recipients](#recipients)
51 | - [Get a list of recipients](#get-a-list-of-recipients)
52 | - [Get a single recipients](#get-a-single-recipient)
53 | - [Delete a recipients](#delete-a-recipient)
54 | - [Get recipients from a suppression list](#get-recipients-from-a-suppression-list)
55 | - [Add recipients to a suppression list](#add-recipients-to-a-suppression-list)
56 | - [Delete recipients from a suppression list](#delete-recipients-from-a-suppression-list)
57 | - [Tokens](#tokens)
58 | - [Create a token](#create-a-token)
59 | - [Pause / Unpause Token](#pause--unpause-token)
60 | - [Delete a token](#delete-a-token)
61 | - [Webhooks](#webhooks)
62 | - [Get a list of webhooks](#get-a-list-of-webhooks)
63 | - [Get a single webhook](#get-a-single-webhook)
64 | - [Create a webhook](#create-a-webhook)
65 | - [Update a Webhook](#update-a-webhook)
66 | - [Delete a Webhook](#delete-a-webhook)
67 | - [Templates](#templates)
68 | - [Get a list of templates](#get-a-list-of-templates)
69 | - [Get a single template](#get-a-single-template)
70 | - [Delete a template](#delete-a-template)
71 | - [Email Verification](#email-verification)
72 | - [Verify a single email](#verify-single-email)
73 | - [Get all email verification lists](#get-all-email-verification-lists)
74 | - [Get an email verification list](#get-an-email-verification-list)
75 | - [Create an email verification list](#create-an-email-verification-list)
76 | - [Verify an email list](#verify-an-email-list)
77 | - [Get email verification list results](#get-email-verification-list-results)
78 | - [SMS](#sms)
79 | - [Send an SMS](#send-an-sms)
80 | - [SMS Messages](#sms-messages)
81 | - [Get a list of SMS messages](#get-a-list-of-sms-messages)
82 | - [Get info on an SMS message](#get-info-on-an-sms-message)
83 | - [SMS Activity](#sms-activity)
84 | - [Get a list of activities](#get-a-list-of-sms-activities)
85 | - [Get activity of a single SMS message](#get-activity-of-a-single-sms-message)
86 | - [SMS Phone Numbers](#sms-phone-numbers)
87 | - [Get a list of SMS phone numbers](#get-a-list-of-sms-phone-numbers)
88 | - [Get an SMS phone number](#get-an-sms-phone-number)
89 | - [Update a single SMS phone number](#update-a-single-sms-phone-number)
90 | - [Delete an SMS phone number](#delete-an-sms-phone-number)
91 | - [SMS Recipients](#sms-recipients)
92 | - [Get a list of SMS recipients](#get-a-list-of-sms-recipients)
93 | - [Get an SMS recipient](#get-an-sms-recipient)
94 | - [Update a single SMS recipient](#update-a-single-sms-recipient)
95 | - [SMS Inbounds](#sms-inbounds)
96 | - [Get a list of SMS inbound routes](#get-a-list-of-sms-inbound-routes)
97 | - [Get a single SMS inbound route](#get-a-single-inbound-route)
98 | - [Create an SMS inbound route](#create-an-sms-inbound-route)
99 | - [Update an SMS inbound route](#update-an-sms-inbound-route)
100 | - [Delete an SMS inbound route](#delete-an-sms-inbound-route)
101 | - [SMS Webhooks](#sms-webhook)
102 | - [Get a list of SMS webhooks](#get-a-list-of-sms-webhooks)
103 | - [Get an SMS webhook](#get-an-sms-webhook)
104 | - [Create an SMS webhook](#create-an-sms-webhook)
105 | - [Update an SMS webhook](#update-an-sms-webhook)
106 | - [Delete an SMS webhook](#delete-an-sms-webhook)
107 | - [Sender Identities](#sender-identities)
108 | - [Get a list of Sender Identities](#get-a-list-of-sender-identities)
109 | - [Get a single Sender Identity](#get-a-single-sender-identity)
110 | - [Get a single Sender Identity By Email](#get-a-single-sender-identity-by-email)
111 | - [Add a Sender_Identity](#create-a-sender-identity)
112 | - [Update a Sender Identity](#update-a-sender-identity)
113 | - [Update a Sender Identity By Email](#update-a-sender-identity-by-email)
114 | - [Delete a Sender Identity](#delete-a-sender-identity)
115 | - [Delete a Sender Identity By Email](#delete-a-sender-identity-by-email)
116 | - [Other Endpoints](#other-endpoints)
117 | - [Get an API Quota](#get-an-api-quota)
118 | - [Types](#types)
119 | - [Helpers](#helpers)
120 | - [Testing](#testing)
121 | - [Support and Feedback](#support-and-feedback)
122 | - [License](#license)
123 |
124 |
125 |
126 | # Installation
127 | We recommend using this package with golang [modules](https://github.com/golang/go/wiki/Modules)
128 |
129 | ```
130 | $ go get github.com/mailersend/mailersend-go
131 | ```
132 |
133 | # Usage
134 |
135 | ## Email
136 |
137 | ### Send an email
138 |
139 | ```go
140 | package main
141 |
142 | import (
143 | "context"
144 | "os"
145 | "fmt"
146 | "time"
147 |
148 | "github.com/mailersend/mailersend-go"
149 | )
150 |
151 | func main() {
152 | // Create an instance of the mailersend client
153 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY"))
154 |
155 | ctx := context.Background()
156 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
157 | defer cancel()
158 |
159 | subject := "Subject"
160 | text := "This is the text content"
161 | html := "
This is the HTML content
" 162 | 163 | from := mailersend.From{ 164 | Name: "Your Name", 165 | Email: "your@domain.com", 166 | } 167 | 168 | recipients := []mailersend.Recipient{ 169 | { 170 | Name: "Your Client", 171 | Email: "your@client.com", 172 | }, 173 | } 174 | 175 | // Send in 5 minute 176 | sendAt := time.Now().Add(time.Minute * 5).Unix() 177 | 178 | tags := []string{"foo", "bar"} 179 | 180 | message := ms.Email.NewMessage() 181 | 182 | message.SetFrom(from) 183 | message.SetRecipients(recipients) 184 | message.SetSubject(subject) 185 | message.SetHTML(html) 186 | message.SetText(text) 187 | message.SetTags(tags) 188 | message.SetSendAt(sendAt) 189 | message.SetInReplyTo("client-id") 190 | 191 | res, _ := ms.Email.Send(ctx, message) 192 | 193 | fmt.Printf(res.Header.Get("X-Message-Id")) 194 | 195 | } 196 | 197 | ``` 198 | 199 | ### Add CC, BCC recipients 200 | 201 | ```go 202 | package main 203 | 204 | import ( 205 | "context" 206 | "os" 207 | "fmt" 208 | "time" 209 | 210 | "github.com/mailersend/mailersend-go" 211 | ) 212 | 213 | func main() { 214 | // Create an instance of the mailersend client 215 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 216 | 217 | ctx := context.Background() 218 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 219 | defer cancel() 220 | 221 | subject := "Subject" 222 | text := "This is the text content" 223 | html := "This is the HTML content
" 224 | 225 | from := mailersend.From{ 226 | Name: "Your Name", 227 | Email: "your@domain.com", 228 | } 229 | 230 | recipients := []mailersend.Recipient{ 231 | { 232 | Name: "Your Client", 233 | Email: "your@client.com", 234 | }, 235 | } 236 | 237 | cc := []mailersend.Recipient{ 238 | { 239 | Name: "CC", 240 | Email: "cc@client.com", 241 | }, 242 | } 243 | 244 | bcc := []mailersend.Recipient{ 245 | { 246 | Name: "BCC", 247 | Email: "bcc@client.com", 248 | }, 249 | } 250 | 251 | replyTo := mailersend.ReplyTo{ 252 | Name: "Reply To", 253 | Email: "reply_to@client.com", 254 | } 255 | 256 | tags := []string{"foo", "bar"} 257 | 258 | message := ms.Email.NewMessage() 259 | 260 | message.SetFrom(from) 261 | message.SetRecipients(recipients) 262 | message.SetSubject(subject) 263 | message.SetHTML(html) 264 | message.SetText(text) 265 | message.SetTags(tags) 266 | message.SetCc(cc) 267 | message.SetBcc(bcc) 268 | message.SetReplyTo(replyTo) 269 | 270 | res, _ := ms.Email.Send(ctx, message) 271 | 272 | fmt.Printf(res.Header.Get("X-Message-Id")) 273 | 274 | } 275 | ``` 276 | 277 | ### Send a template-based email 278 | 279 | ```go 280 | package main 281 | 282 | import ( 283 | "context" 284 | "os" 285 | "fmt" 286 | "time" 287 | 288 | "github.com/mailersend/mailersend-go" 289 | ) 290 | 291 | func main() { 292 | // Create an instance of the mailersend client 293 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 294 | 295 | ctx := context.Background() 296 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 297 | defer cancel() 298 | 299 | subject := "Subject" 300 | 301 | from := mailersend.From{ 302 | Name: "Your Name", 303 | Email: "your@domain.com", 304 | } 305 | 306 | recipients := []mailersend.Recipient{ 307 | { 308 | Name: "Your Client", 309 | Email: "your@client.com", 310 | }, 311 | } 312 | 313 | variables := []mailersend.Variables{ 314 | { 315 | Email: "your@client.com", 316 | Substitutions: []mailersend.Substitution{ 317 | { 318 | Var: "foo", 319 | Value: "bar", 320 | }, 321 | }, 322 | }, 323 | } 324 | 325 | message := ms.Email.NewMessage() 326 | 327 | message.SetFrom(from) 328 | message.SetRecipients(recipients) 329 | message.SetSubject(subject) 330 | message.SetTemplateID("template-id") 331 | message.SetSubstitutions(variables) 332 | 333 | res, _ := ms.Email.Send(ctx, message) 334 | 335 | fmt.Printf(res.Header.Get("X-Message-Id")) 336 | 337 | } 338 | ``` 339 | 340 | ### Personalization 341 | 342 | ```go 343 | package main 344 | 345 | import ( 346 | "context" 347 | "os" 348 | "fmt" 349 | "time" 350 | 351 | "github.com/mailersend/mailersend-go" 352 | ) 353 | 354 | func main() { 355 | // Create an instance of the mailersend client 356 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 357 | 358 | ctx := context.Background() 359 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 360 | defer cancel() 361 | 362 | subject := "Subject {{ var }}" 363 | text := "This is the text version with a {{ var }}." 364 | html := "This is the HTML version with a {{ var }}.
" 365 | 366 | from := mailersend.From{ 367 | Name: "Your Name", 368 | Email: "your@domain.com", 369 | } 370 | 371 | recipients := []mailersend.Recipient{ 372 | { 373 | Name: "Your Client", 374 | Email: "your@client.com", 375 | }, 376 | } 377 | 378 | personalization := []mailersend.Personalization{ 379 | { 380 | Email: "your@client.com", 381 | Data: map[string]interface{}{ 382 | "Var": "value", 383 | }, 384 | }, 385 | } 386 | 387 | message := ms.Email.NewMessage() 388 | 389 | message.SetFrom(from) 390 | message.SetRecipients(recipients) 391 | message.SetSubject(subject) 392 | message.SetText(text) 393 | message.SetHTML(html) 394 | 395 | message.SetPersonalization(personalization) 396 | 397 | res, _ := ms.Email.Send(ctx, message) 398 | 399 | fmt.Printf(res.Header.Get("X-Message-Id")) 400 | 401 | } 402 | ``` 403 | 404 | ### Send email with attachment 405 | 406 | ```go 407 | package main 408 | 409 | import ( 410 | "bufio" 411 | "context" 412 | "os" 413 | "encoding/base64" 414 | "fmt" 415 | "io" 416 | "os" 417 | "time" 418 | 419 | "github.com/mailersend/mailersend-go" 420 | ) 421 | 422 | func main() { 423 | // Create an instance of the mailersend client 424 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 425 | 426 | ctx := context.Background() 427 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 428 | defer cancel() 429 | 430 | subject := "Subject" 431 | text := "This is the text content" 432 | html := "This is the HTML content
" 433 | 434 | from := mailersend.From{ 435 | Name: "Your Name", 436 | Email: "your@domain.com", 437 | } 438 | 439 | recipients := []mailersend.Recipient{ 440 | { 441 | Name: "Your Client", 442 | Email: "your@client.com", 443 | }, 444 | } 445 | 446 | tags := []string{"foo", "bar"} 447 | 448 | message := ms.Email.NewMessage() 449 | 450 | message.SetFrom(from) 451 | message.SetRecipients(recipients) 452 | message.SetSubject(subject) 453 | message.SetHTML(html) 454 | message.SetText(text) 455 | message.SetTags(tags) 456 | 457 | // Open file on disk. 458 | f, _ := os.Open("./file.jpg") 459 | 460 | reader := bufio.NewReader(f) 461 | content, _ := io.ReadAll(reader) 462 | 463 | // Encode as base64. 464 | encoded := base64.StdEncoding.EncodeToString(content) 465 | 466 | attachment := mailersend.Attachment{Filename: "file.jpg", Content: encoded} 467 | 468 | message.AddAttachment(attachment) 469 | 470 | res, _ := ms.Email.Send(ctx, message) 471 | 472 | fmt.Printf(res.Header.Get("X-Message-Id")) 473 | 474 | } 475 | ``` 476 | 477 | 478 | ### Send email with inline attachment 479 | 480 | ```go 481 | package main 482 | 483 | import ( 484 | "bufio" 485 | "context" 486 | "os" 487 | "encoding/base64" 488 | "fmt" 489 | "io" 490 | "os" 491 | "time" 492 | 493 | "github.com/mailersend/mailersend-go" 494 | ) 495 | 496 | func main() { 497 | // Create an instance of the mailersend client 498 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 499 | 500 | ctx := context.Background() 501 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 502 | defer cancel() 503 | 504 | subject := "Subject" 505 | text := "This is the text content" 506 | html := "This is the HTML content
This is the HTML content
" 582 | 583 | from := mailersend.From{ 584 | Name: "Your Name", 585 | Email: "your@domain.com", 586 | } 587 | 588 | recipients := []mailersend.Recipient{ 589 | { 590 | Name: "Your Client", 591 | Email: "your@client.com", 592 | }, 593 | } 594 | 595 | var messages []*mailersend.Message 596 | 597 | for i := range [2]int{} { 598 | msg := &mailersend.Message{ 599 | From: from, 600 | Recipients: recipients, 601 | Subject: fmt.Sprintf("%s %v", subject, i), 602 | Text: text, 603 | HTML: html, 604 | } 605 | messages = append(messages, msg) 606 | } 607 | 608 | _, _, err := ms.BulkEmail.Send(ctx, messages) 609 | if err != nil { 610 | log.Fatal(err) 611 | } 612 | 613 | } 614 | 615 | ``` 616 | 617 | ### Get bulk email status 618 | 619 | ```go 620 | package main 621 | 622 | import ( 623 | "context" 624 | "os" 625 | "time" 626 | "log" 627 | 628 | "github.com/mailersend/mailersend-go" 629 | ) 630 | 631 | func main() { 632 | // Create an instance of the mailersend client 633 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 634 | 635 | ctx := context.Background() 636 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 637 | defer cancel() 638 | 639 | _, _, err := ms.BulkEmail.Status(ctx, "bulk-email-id") 640 | if err != nil { 641 | log.Fatal(err) 642 | } 643 | 644 | } 645 | ``` 646 | 647 | ## Activity 648 | 649 | ### Get a list of activities 650 | 651 | ```go 652 | package main 653 | 654 | import ( 655 | "context" 656 | "os" 657 | "log" 658 | "time" 659 | 660 | "github.com/mailersend/mailersend-go" 661 | ) 662 | 663 | func main() { 664 | // Create an instance of the mailersend client 665 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 666 | 667 | ctx := context.Background() 668 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 669 | defer cancel() 670 | 671 | from := time.Now().Add(-24 * time.Hour).Unix() 672 | to := time.Now().Unix() 673 | domainID := "domain-id" 674 | 675 | options := &mailersend.ActivityOptions{ 676 | DomainID: domainID, 677 | DateFrom: from, 678 | DateTo: to, 679 | } 680 | 681 | _, _, err := ms.Activity.List(ctx, options) 682 | if err != nil { 683 | log.Fatal(err) 684 | } 685 | } 686 | ``` 687 | 688 | ## Analytics 689 | 690 | ### Activity data by date 691 | 692 | ```go 693 | package main 694 | 695 | import ( 696 | "context" 697 | "os" 698 | "log" 699 | "time" 700 | 701 | "github.com/mailersend/mailersend-go" 702 | ) 703 | 704 | func main() { 705 | // Create an instance of the mailersend client 706 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 707 | 708 | ctx := context.Background() 709 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 710 | defer cancel() 711 | 712 | from := time.Now().Add(-24 * time.Hour).Unix() 713 | to := time.Now().Unix() 714 | domainID := "domain-id" 715 | events := []string{"sent", "queued"} 716 | 717 | options := &mailersend.AnalyticsOptions{ 718 | DomainID: domainID, 719 | DateFrom: from, 720 | DateTo: to, 721 | Event: events, 722 | } 723 | 724 | _, _, err := ms.Analytics.GetActivityByDate(ctx, options) 725 | if err != nil { 726 | log.Fatal(err) 727 | } 728 | } 729 | ``` 730 | 731 | ### Opens by country 732 | 733 | ```go 734 | package main 735 | 736 | import ( 737 | "context" 738 | "os" 739 | "log" 740 | "time" 741 | 742 | "github.com/mailersend/mailersend-go" 743 | ) 744 | 745 | func main() { 746 | // Create an instance of the mailersend client 747 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 748 | 749 | ctx := context.Background() 750 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 751 | defer cancel() 752 | 753 | from := time.Now().Add(-24 * time.Hour).Unix() 754 | to := time.Now().Unix() 755 | domainID := "domain-id" 756 | 757 | options := &mailersend.AnalyticsOptions{ 758 | DomainID: domainID, 759 | DateFrom: from, 760 | DateTo: to, 761 | } 762 | 763 | _, _, err := ms.Analytics.GetOpensByCountry(ctx, options) 764 | if err != nil { 765 | log.Fatal(err) 766 | } 767 | } 768 | ``` 769 | 770 | ### Opens by user-agent name 771 | 772 | ```go 773 | package main 774 | 775 | import ( 776 | "context" 777 | "os" 778 | "log" 779 | "time" 780 | 781 | "github.com/mailersend/mailersend-go" 782 | ) 783 | 784 | func main() { 785 | // Create an instance of the mailersend client 786 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 787 | 788 | ctx := context.Background() 789 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 790 | defer cancel() 791 | 792 | from := time.Now().Add(-24 * time.Hour).Unix() 793 | to := time.Now().Unix() 794 | domainID := "domain-id" 795 | 796 | options := &mailersend.AnalyticsOptions{ 797 | DomainID: domainID, 798 | DateFrom: from, 799 | DateTo: to, 800 | } 801 | 802 | _, _, err := ms.Analytics.GetOpensByUserAgent(ctx, options) 803 | if err != nil { 804 | log.Fatal(err) 805 | } 806 | } 807 | ``` 808 | 809 | ### Opens by reading environment 810 | 811 | ```go 812 | package main 813 | 814 | import ( 815 | "context" 816 | "os" 817 | "log" 818 | "time" 819 | 820 | "github.com/mailersend/mailersend-go" 821 | ) 822 | 823 | func main() { 824 | // Create an instance of the mailersend client 825 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 826 | 827 | ctx := context.Background() 828 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 829 | defer cancel() 830 | 831 | from := time.Now().Add(-24 * time.Hour).Unix() 832 | to := time.Now().Unix() 833 | domainID := "domain-id" 834 | 835 | options := &mailersend.AnalyticsOptions{ 836 | DomainID: domainID, 837 | DateFrom: from, 838 | DateTo: to, 839 | } 840 | 841 | _, _, err := ms.Analytics.GetOpensByReadingEnvironment(ctx, options) 842 | if err != nil { 843 | log.Fatal(err) 844 | } 845 | } 846 | ``` 847 | 848 | ## Inbound Routes 849 | 850 | ### Get a list of inbound routes 851 | 852 | ```go 853 | package main 854 | 855 | import ( 856 | "context" 857 | "os" 858 | 859 | "github.com/mailersend/mailersend-go" 860 | ) 861 | 862 | func main() { 863 | // Create an instance of the mailersend client 864 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 865 | 866 | ctx := context.TODO() 867 | 868 | domainID := "domain-id" 869 | 870 | listOptions := &mailersend.ListInboundOptions{ 871 | DomainID: domainID, 872 | } 873 | 874 | _, _, _ = ms.Inbound.List(ctx, listOptions) 875 | } 876 | ``` 877 | 878 | ### Get a single inbound route 879 | 880 | ```go 881 | package main 882 | 883 | import ( 884 | "context" 885 | "os" 886 | 887 | "github.com/mailersend/mailersend-go" 888 | ) 889 | 890 | func main() { 891 | // Create an instance of the mailersend client 892 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 893 | 894 | ctx := context.TODO() 895 | 896 | inboundID := "inbound-id" 897 | 898 | _, _, _ = ms.Inbound.Get(ctx, inboundID) 899 | } 900 | ``` 901 | 902 | 903 | ### Add an inbound route 904 | 905 | ```go 906 | package main 907 | 908 | import ( 909 | "context" 910 | "os" 911 | 912 | "github.com/mailersend/mailersend-go" 913 | ) 914 | 915 | func main() { 916 | // Create an instance of the mailersend client 917 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 918 | 919 | ctx := context.TODO() 920 | 921 | domainID := "domain-id" 922 | 923 | createOptions := &mailersend.CreateInboundOptions{ 924 | DomainID: domainID, 925 | Name: "Example Route", 926 | DomainEnabled: *mailersend.Bool(false), 927 | MatchFilter: &mailersend.MatchFilter{ 928 | Type: "match_all", 929 | }, 930 | InboundPriority: 1, 931 | CatchFilter: &mailersend.CatchFilter{}, 932 | Forwards: []mailersend.Forwards{ 933 | { 934 | Type: "webhook", 935 | Value: "https://example.com", 936 | }, 937 | }, 938 | } 939 | 940 | _, _, _ = ms.Inbound.Create(ctx, createOptions) 941 | } 942 | ``` 943 | 944 | ### Update an inbound route 945 | 946 | ```go 947 | package main 948 | 949 | import ( 950 | "context" 951 | "os" 952 | 953 | "github.com/mailersend/mailersend-go" 954 | ) 955 | 956 | func main() { 957 | // Create an instance of the mailersend client 958 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 959 | 960 | ctx := context.TODO() 961 | 962 | inboundID := "inbound-id" 963 | 964 | updateOptions := &mailersend.UpdateInboundOptions{ 965 | Name: "Example Route", 966 | DomainEnabled: *mailersend.Bool(true), 967 | InboundDomain: "inbound.example.com", 968 | InboundPriority: 1, 969 | MatchFilter: &mailersend.MatchFilter{ 970 | Type: "match_all", 971 | }, 972 | CatchFilter: &mailersend.CatchFilter{ 973 | Type: "catch_recipient", 974 | Filters: []mailersend.Filter{ 975 | { 976 | Comparer: "equal", 977 | Value: "email", 978 | }, 979 | { 980 | Comparer: "equal", 981 | Value: "emails", 982 | }, 983 | }, 984 | }, 985 | Forwards: []mailersend.Forwards{ 986 | { 987 | Type: "webhook", 988 | Value: "https://example.com", 989 | }, 990 | }, 991 | } 992 | 993 | _, _, _ = ms.Inbound.Update(ctx, inboundID, updateOptions) 994 | } 995 | ``` 996 | 997 | ### Delete an inbound route 998 | 999 | ```go 1000 | package main 1001 | 1002 | import ( 1003 | "context" 1004 | "os" 1005 | 1006 | "github.com/mailersend/mailersend-go" 1007 | ) 1008 | 1009 | func main() { 1010 | // Create an instance of the mailersend client 1011 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1012 | 1013 | ctx := context.TODO() 1014 | 1015 | inboundID := "inbound-id" 1016 | 1017 | _, _ = ms.Inbound.Delete(ctx, inboundID) 1018 | } 1019 | ``` 1020 | 1021 | ## Domains 1022 | 1023 | ### Get a list of domains 1024 | 1025 | ```go 1026 | package main 1027 | 1028 | import ( 1029 | "context" 1030 | "os" 1031 | "log" 1032 | "time" 1033 | 1034 | "github.com/mailersend/mailersend-go" 1035 | ) 1036 | 1037 | func main() { 1038 | // Create an instance of the mailersend client 1039 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1040 | 1041 | ctx := context.Background() 1042 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1043 | defer cancel() 1044 | 1045 | options := &mailersend.ListDomainOptions{ 1046 | Page: 1, 1047 | Limit: 25, 1048 | } 1049 | 1050 | _, _, err := ms.Domain.List(ctx, options) 1051 | if err != nil { 1052 | log.Fatal(err) 1053 | } 1054 | } 1055 | ``` 1056 | 1057 | ### Get a single domain 1058 | 1059 | ```go 1060 | package main 1061 | 1062 | import ( 1063 | "context" 1064 | "os" 1065 | "log" 1066 | "time" 1067 | 1068 | "github.com/mailersend/mailersend-go" 1069 | ) 1070 | 1071 | func main() { 1072 | // Create an instance of the mailersend client 1073 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1074 | 1075 | ctx := context.Background() 1076 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1077 | defer cancel() 1078 | 1079 | domainID := "domain-id" 1080 | 1081 | _, _, err := ms.Domain.Get(ctx, domainID) 1082 | if err != nil { 1083 | log.Fatal(err) 1084 | } 1085 | } 1086 | ``` 1087 | 1088 | ### Delete a domain 1089 | 1090 | ```go 1091 | package main 1092 | 1093 | import ( 1094 | "context" 1095 | "os" 1096 | "log" 1097 | "time" 1098 | 1099 | "github.com/mailersend/mailersend-go" 1100 | ) 1101 | 1102 | func main() { 1103 | // Create an instance of the mailersend client 1104 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1105 | 1106 | ctx := context.Background() 1107 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1108 | defer cancel() 1109 | 1110 | domainID := "domain-id" 1111 | 1112 | _, err := ms.Domain.Delete(ctx, domainID) 1113 | if err != nil { 1114 | log.Fatal(err) 1115 | } 1116 | } 1117 | ``` 1118 | 1119 | ### Add a domain 1120 | 1121 | ```go 1122 | package main 1123 | 1124 | import ( 1125 | "context" 1126 | "os" 1127 | "log" 1128 | "time" 1129 | 1130 | "github.com/mailersend/mailersend-go" 1131 | ) 1132 | 1133 | func main() { 1134 | // Create an instance of the mailersend client 1135 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1136 | 1137 | ctx := context.Background() 1138 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1139 | defer cancel() 1140 | 1141 | options := &mailersend.CreateDomainOptions{ 1142 | Name: "domain.test", 1143 | } 1144 | 1145 | _, _, err := ms.Domain.Create(ctx, options) 1146 | if err != nil { 1147 | log.Fatal(err) 1148 | } 1149 | } 1150 | ``` 1151 | 1152 | ### Get DNS Records 1153 | 1154 | ```go 1155 | package main 1156 | 1157 | import ( 1158 | "context" 1159 | "os" 1160 | "log" 1161 | "time" 1162 | 1163 | "github.com/mailersend/mailersend-go" 1164 | ) 1165 | 1166 | func main() { 1167 | // Create an instance of the mailersend client 1168 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1169 | 1170 | ctx := context.Background() 1171 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1172 | defer cancel() 1173 | 1174 | domainID := "domain-id" 1175 | 1176 | _, _, err := ms.Domain.GetDNS(ctx, domainID) 1177 | if err != nil { 1178 | log.Fatal(err) 1179 | } 1180 | } 1181 | ``` 1182 | 1183 | ### Get verification status 1184 | 1185 | ```go 1186 | package main 1187 | 1188 | import ( 1189 | "context" 1190 | "os" 1191 | "log" 1192 | "time" 1193 | 1194 | "github.com/mailersend/mailersend-go" 1195 | ) 1196 | 1197 | func main() { 1198 | // Create an instance of the mailersend client 1199 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1200 | 1201 | ctx := context.Background() 1202 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1203 | defer cancel() 1204 | 1205 | domainID := "domain-id" 1206 | 1207 | _, _, err := ms.Domain.Verify(ctx, domainID) 1208 | if err != nil { 1209 | log.Fatal(err) 1210 | } 1211 | } 1212 | ``` 1213 | 1214 | ### Get a list of recipients per domain 1215 | 1216 | ```go 1217 | package main 1218 | 1219 | import ( 1220 | "context" 1221 | "os" 1222 | "log" 1223 | "time" 1224 | 1225 | "github.com/mailersend/mailersend-go" 1226 | ) 1227 | 1228 | func main() { 1229 | // Create an instance of the mailersend client 1230 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1231 | 1232 | ctx := context.Background() 1233 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1234 | defer cancel() 1235 | 1236 | domainID := "domain-id" 1237 | 1238 | options := &mailersend.GetRecipientsOptions{ 1239 | DomainID: domainID, 1240 | Page: 1, 1241 | Limit: 25, 1242 | } 1243 | 1244 | _, _, err := ms.Domain.GetRecipients(ctx, options) 1245 | if err != nil { 1246 | log.Fatal(err) 1247 | } 1248 | } 1249 | ``` 1250 | 1251 | ### Update domain settings 1252 | 1253 | ```go 1254 | package main 1255 | 1256 | import ( 1257 | "context" 1258 | "os" 1259 | "log" 1260 | "time" 1261 | 1262 | "github.com/mailersend/mailersend-go" 1263 | ) 1264 | 1265 | func main() { 1266 | // Create an instance of the mailersend client 1267 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1268 | 1269 | ctx := context.Background() 1270 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1271 | defer cancel() 1272 | 1273 | domainID := "domain-id" 1274 | 1275 | options := &mailersend.DomainSettingOptions{ 1276 | DomainID: domainID, 1277 | SendPaused: mailersend.Bool(false), 1278 | TrackClicks: mailersend.Bool(true), 1279 | } 1280 | 1281 | _, _, err := ms.Domain.Update(ctx, options) 1282 | if err != nil { 1283 | log.Fatal(err) 1284 | } 1285 | } 1286 | ``` 1287 | 1288 | ## Messages 1289 | 1290 | ### Get a list of messages 1291 | 1292 | ```go 1293 | package main 1294 | 1295 | import ( 1296 | "context" 1297 | "os" 1298 | "log" 1299 | "time" 1300 | 1301 | "github.com/mailersend/mailersend-go" 1302 | ) 1303 | 1304 | func main() { 1305 | // Create an instance of the mailersend client 1306 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1307 | 1308 | ctx := context.Background() 1309 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1310 | defer cancel() 1311 | 1312 | options := &mailersend.ListMessageOptions{ 1313 | Page: 1, 1314 | Limit: 25, 1315 | } 1316 | 1317 | _, _, err := ms.Message.List(ctx, options) 1318 | if err != nil { 1319 | log.Fatal(err) 1320 | } 1321 | } 1322 | ``` 1323 | 1324 | ### Get a single message 1325 | 1326 | ```go 1327 | package main 1328 | 1329 | import ( 1330 | "context" 1331 | "os" 1332 | "log" 1333 | "time" 1334 | 1335 | "github.com/mailersend/mailersend-go" 1336 | ) 1337 | 1338 | func main() { 1339 | // Create an instance of the mailersend client 1340 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1341 | 1342 | ctx := context.Background() 1343 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1344 | defer cancel() 1345 | 1346 | messageID := "message-id" 1347 | 1348 | _, _, err := ms.Message.Get(ctx, messageID) 1349 | if err != nil { 1350 | log.Fatal(err) 1351 | } 1352 | } 1353 | ``` 1354 | 1355 | 1356 | ## Scheduled messages 1357 | 1358 | ### Get a list of scheduled messages 1359 | 1360 | ```go 1361 | package main 1362 | 1363 | import ( 1364 | "context" 1365 | "os" 1366 | "log" 1367 | 1368 | "github.com/mailersend/mailersend-go" 1369 | ) 1370 | 1371 | func main() { 1372 | // Create an instance of the mailersend client 1373 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1374 | 1375 | ctx := context.TODO() 1376 | 1377 | domainID := "domain-id" 1378 | 1379 | _, _, err := ms.ScheduleMessage.List(ctx, domainID) 1380 | if err != nil { 1381 | log.Fatal(err) 1382 | } 1383 | } 1384 | ``` 1385 | 1386 | ### Get a single scheduled message 1387 | 1388 | ```go 1389 | package main 1390 | 1391 | import ( 1392 | "context" 1393 | "os" 1394 | "log" 1395 | 1396 | "github.com/mailersend/mailersend-go" 1397 | ) 1398 | 1399 | func main() { 1400 | // Create an instance of the mailersend client 1401 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1402 | 1403 | ctx := context.TODO() 1404 | 1405 | messageID := "message-id" 1406 | 1407 | _, _, err := ms.ScheduleMessage.Get(ctx, messageID) 1408 | if err != nil { 1409 | log.Fatal(err) 1410 | } 1411 | } 1412 | ``` 1413 | 1414 | ### Delete a scheduled message 1415 | 1416 | ```go 1417 | package main 1418 | 1419 | import ( 1420 | "context" 1421 | "os" 1422 | "log" 1423 | 1424 | "github.com/mailersend/mailersend-go" 1425 | ) 1426 | 1427 | func main() { 1428 | // Create an instance of the mailersend client 1429 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1430 | 1431 | ctx := context.TODO() 1432 | 1433 | messageID := "message-id" 1434 | 1435 | _, err := ms.ScheduleMessage.Delete(ctx, messageID) 1436 | if err != nil { 1437 | log.Fatal(err) 1438 | } 1439 | } 1440 | ``` 1441 | 1442 | ## Recipients 1443 | 1444 | ### Get a list of recipients 1445 | 1446 | ```go 1447 | package main 1448 | 1449 | import ( 1450 | "context" 1451 | "os" 1452 | "log" 1453 | "time" 1454 | 1455 | "github.com/mailersend/mailersend-go" 1456 | ) 1457 | 1458 | func main() { 1459 | // Create an instance of the mailersend client 1460 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1461 | 1462 | ctx := context.Background() 1463 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1464 | defer cancel() 1465 | 1466 | options := &mailersend.ListRecipientOptions{ 1467 | //DomainID: domainID, 1468 | Page: 1, 1469 | Limit: 25, 1470 | } 1471 | 1472 | _, _, err := ms.Recipient.List(ctx, options) 1473 | if err != nil { 1474 | log.Fatal(err) 1475 | } 1476 | } 1477 | ``` 1478 | 1479 | ### Get a single recipient 1480 | 1481 | ```go 1482 | package main 1483 | 1484 | import ( 1485 | "context" 1486 | "os" 1487 | "log" 1488 | "time" 1489 | 1490 | "github.com/mailersend/mailersend-go" 1491 | ) 1492 | 1493 | func main() { 1494 | // Create an instance of the mailersend client 1495 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1496 | 1497 | ctx := context.Background() 1498 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1499 | defer cancel() 1500 | 1501 | recipientID := "recipient-id" 1502 | 1503 | _, _, err := ms.Recipient.Get(ctx, recipientID) 1504 | if err != nil { 1505 | log.Fatal(err) 1506 | } 1507 | } 1508 | ``` 1509 | 1510 | ### Delete a recipient 1511 | 1512 | ```go 1513 | package main 1514 | 1515 | import ( 1516 | "context" 1517 | "os" 1518 | "log" 1519 | "time" 1520 | 1521 | "github.com/mailersend/mailersend-go" 1522 | ) 1523 | 1524 | func main() { 1525 | // Create an instance of the mailersend client 1526 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1527 | 1528 | ctx := context.Background() 1529 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1530 | defer cancel() 1531 | 1532 | recipientID := "recipient-id" 1533 | 1534 | _, err := ms.Recipient.Delete(ctx, recipientID) 1535 | if err != nil { 1536 | log.Fatal(err) 1537 | } 1538 | } 1539 | ``` 1540 | 1541 | 1542 | ### Get recipients from a suppression list 1543 | 1544 | ```go 1545 | package main 1546 | 1547 | import ( 1548 | "context" 1549 | "os" 1550 | "log" 1551 | "time" 1552 | 1553 | "github.com/mailersend/mailersend-go" 1554 | ) 1555 | 1556 | func main() { 1557 | // Create an instance of the mailersend client 1558 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1559 | 1560 | ctx := context.Background() 1561 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1562 | defer cancel() 1563 | 1564 | listOptions := &mailersend.SuppressionOptions{ 1565 | DomainID: "domain-id", 1566 | Page: 1, 1567 | Limit: 25, 1568 | } 1569 | 1570 | // List Block List Recipients 1571 | _, _, err := ms.Suppression.ListBlockList(ctx, listOptions) 1572 | if err != nil { 1573 | log.Fatal(err) 1574 | } 1575 | 1576 | // List Hard Bounces 1577 | _, _, _ = ms.Suppression.ListHardBounces(ctx, listOptions) 1578 | 1579 | // List Spam Complaints 1580 | _, _, _ = ms.Suppression.ListSpamComplaints(ctx, listOptions) 1581 | 1582 | // List Unsubscribes 1583 | _, _, _ = ms.Suppression.ListUnsubscribes(ctx, listOptions) 1584 | 1585 | 1586 | } 1587 | ``` 1588 | 1589 | ### Add recipients to a suppression list 1590 | 1591 | ```go 1592 | package main 1593 | 1594 | import ( 1595 | "context" 1596 | "os" 1597 | "time" 1598 | 1599 | "github.com/mailersend/mailersend-go" 1600 | ) 1601 | 1602 | func main() { 1603 | // Create an instance of the mailersend client 1604 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1605 | 1606 | ctx := context.Background() 1607 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1608 | defer cancel() 1609 | 1610 | // Add Recipient to Block List 1611 | createSuppressionBlockOptions := &mailersend.CreateSuppressionBlockOptions{ 1612 | DomainID: "domain-id", 1613 | Recipients: []string{"test@example.com"}, 1614 | Patterns: []string{".*@example.com"}, 1615 | } 1616 | 1617 | _, _, _ = ms.Suppression.CreateBlock(ctx, createSuppressionBlockOptions) 1618 | 1619 | // Add Recipient to Hard Bounces 1620 | createSuppressionHardBounceOptions := &mailersend.CreateSuppressionOptions{ 1621 | DomainID: "domain-id", 1622 | Recipients: []string{"test@example.com"}, 1623 | } 1624 | 1625 | _, _, _ = ms.Suppression.CreateHardBounce(ctx, createSuppressionHardBounceOptions) 1626 | 1627 | // Add Recipient to Spam Complaints 1628 | createSuppressionSpamComplaintsOptions := &mailersend.CreateSuppressionOptions{ 1629 | DomainID: "domain-id", 1630 | Recipients: []string{"test@example.com"}, 1631 | } 1632 | 1633 | _, _, _ = ms.Suppression.CreateHardBounce(ctx, createSuppressionSpamComplaintsOptions) 1634 | 1635 | // Add Recipient to Unsubscribes 1636 | createSuppressionUnsubscribesOptions := &mailersend.CreateSuppressionOptions{ 1637 | DomainID: "domain-id", 1638 | Recipients: []string{"test@example.com"}, 1639 | } 1640 | 1641 | _, _, _ = ms.Suppression.CreateHardBounce(ctx, createSuppressionUnsubscribesOptions) 1642 | 1643 | } 1644 | ``` 1645 | 1646 | ### Delete recipients from a suppression list 1647 | 1648 | ```go 1649 | package main 1650 | 1651 | import ( 1652 | "context" 1653 | "os" 1654 | "time" 1655 | 1656 | "github.com/mailersend/mailersend-go" 1657 | ) 1658 | 1659 | func main() { 1660 | // Create an instance of the mailersend client 1661 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1662 | 1663 | ctx := context.Background() 1664 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1665 | defer cancel() 1666 | 1667 | domainID := "domain-id" 1668 | 1669 | // Delete All {type} 1670 | 1671 | // mailersend.BlockList 1672 | // mailersend.HardBounces 1673 | // mailersend.SpamComplaints 1674 | // mailersend.Unsubscribes 1675 | 1676 | _, _ = ms.Suppression.DeleteAll(ctx, domainID, mailersend.Unsubscribes) 1677 | 1678 | // Delete 1679 | 1680 | deleteSuppressionOption := &mailersend.DeleteSuppressionOptions{ 1681 | DomainID: domainID, 1682 | Ids: []string{"suppression-id"}, 1683 | } 1684 | 1685 | _, _ = ms.Suppression.Delete(ctx, deleteSuppressionOption, mailersend.Unsubscribes) 1686 | 1687 | 1688 | } 1689 | ``` 1690 | 1691 | ## Tokens 1692 | 1693 | ### Create a token 1694 | 1695 | ```go 1696 | package main 1697 | 1698 | import ( 1699 | "context" 1700 | "os" 1701 | "log" 1702 | "time" 1703 | 1704 | "github.com/mailersend/mailersend-go" 1705 | ) 1706 | 1707 | func main() { 1708 | // Create an instance of the mailersend client 1709 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1710 | 1711 | ctx := context.Background() 1712 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1713 | defer cancel() 1714 | 1715 | domainID := "domain-id" 1716 | 1717 | scopes := []string{ 1718 | "tokens_full", 1719 | "email_full", 1720 | "domains_full", 1721 | "activity_full", 1722 | "analytics_full", 1723 | "webhooks_full", 1724 | "templates_full", 1725 | } 1726 | 1727 | options := &mailersend.CreateTokenOptions{ 1728 | Name: "token name", 1729 | DomainID: domainID, 1730 | Scopes: scopes, 1731 | } 1732 | 1733 | newToken, _, err := ms.Token.Create(ctx, options) 1734 | if err != nil { 1735 | log.Fatal(err) 1736 | } 1737 | 1738 | // Make sure you keep your access token secret 1739 | log.Print(newToken.Data.AccessToken) 1740 | } 1741 | ``` 1742 | 1743 | ### Pause / Unpause Token 1744 | 1745 | ```go 1746 | package main 1747 | 1748 | import ( 1749 | "context" 1750 | "os" 1751 | "log" 1752 | "time" 1753 | 1754 | "github.com/mailersend/mailersend-go" 1755 | ) 1756 | 1757 | func main() { 1758 | // Create an instance of the mailersend client 1759 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1760 | 1761 | ctx := context.Background() 1762 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1763 | defer cancel() 1764 | 1765 | tokenID := "token-id" 1766 | 1767 | updateOptions := &mailersend.UpdateTokenOptions{ 1768 | TokenID: tokenID, 1769 | Status: "pause/unpause", 1770 | } 1771 | 1772 | _, _, err := ms.Token.Update(ctx, updateOptions) 1773 | if err != nil { 1774 | log.Fatal(err) 1775 | } 1776 | } 1777 | ``` 1778 | 1779 | ### Delete a Token 1780 | 1781 | ```go 1782 | package main 1783 | 1784 | import ( 1785 | "context" 1786 | "os" 1787 | "log" 1788 | "time" 1789 | 1790 | "github.com/mailersend/mailersend-go" 1791 | ) 1792 | 1793 | func main() { 1794 | // Create an instance of the mailersend client 1795 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1796 | 1797 | ctx := context.Background() 1798 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1799 | defer cancel() 1800 | 1801 | tokenID := "token-id" 1802 | 1803 | _, err := ms.Token.Delete(ctx, tokenID) 1804 | if err != nil { 1805 | log.Fatal(err) 1806 | } 1807 | } 1808 | ``` 1809 | 1810 | ## Webhooks 1811 | 1812 | ### Get a list of webhooks 1813 | 1814 | ```go 1815 | package main 1816 | 1817 | import ( 1818 | "context" 1819 | "os" 1820 | "log" 1821 | "time" 1822 | 1823 | "github.com/mailersend/mailersend-go" 1824 | ) 1825 | 1826 | func main() { 1827 | // Create an instance of the mailersend client 1828 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1829 | 1830 | ctx := context.Background() 1831 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1832 | defer cancel() 1833 | 1834 | domainID := "domain-id" 1835 | 1836 | options := &mailersend.ListWebhookOptions{ 1837 | DomainID: domainID, 1838 | Limit: 25, 1839 | } 1840 | 1841 | _, _, err := ms.Webhook.List(ctx, options) 1842 | if err != nil { 1843 | log.Fatal(err) 1844 | } 1845 | } 1846 | ``` 1847 | 1848 | ### Get a single webhook 1849 | 1850 | ```go 1851 | package main 1852 | 1853 | import ( 1854 | "context" 1855 | "os" 1856 | "log" 1857 | "time" 1858 | 1859 | "github.com/mailersend/mailersend-go" 1860 | ) 1861 | 1862 | func main() { 1863 | // Create an instance of the mailersend client 1864 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1865 | 1866 | ctx := context.Background() 1867 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1868 | defer cancel() 1869 | 1870 | webhookID := "webhook-id" 1871 | 1872 | _, _, err := ms.Webhook.Get(ctx, webhookID) 1873 | if err != nil { 1874 | log.Fatal(err) 1875 | } 1876 | } 1877 | ``` 1878 | 1879 | ### Create a Webhook 1880 | 1881 | ```go 1882 | package main 1883 | 1884 | import ( 1885 | "context" 1886 | "os" 1887 | "log" 1888 | "time" 1889 | 1890 | "github.com/mailersend/mailersend-go" 1891 | ) 1892 | 1893 | func main() { 1894 | // Create an instance of the mailersend client 1895 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1896 | 1897 | ctx := context.Background() 1898 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1899 | defer cancel() 1900 | 1901 | domainID := "domain-id" 1902 | events := []string{"activity.opened", "activity.clicked"} 1903 | 1904 | createOptions := &mailersend.CreateWebhookOptions{ 1905 | Name: "Webhook", 1906 | DomainID: domainID, 1907 | URL: "https://test.com", 1908 | Enabled: mailersend.Bool(false), 1909 | Events: events, 1910 | } 1911 | 1912 | _, _, err := ms.Webhook.Create(ctx, createOptions) 1913 | if err != nil { 1914 | log.Fatal(err) 1915 | } 1916 | } 1917 | ``` 1918 | 1919 | ### Update a Webhook 1920 | 1921 | ```go 1922 | package main 1923 | 1924 | import ( 1925 | "context" 1926 | "os" 1927 | "log" 1928 | "time" 1929 | 1930 | "github.com/mailersend/mailersend-go" 1931 | ) 1932 | 1933 | func main() { 1934 | // Create an instance of the mailersend client 1935 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1936 | 1937 | ctx := context.Background() 1938 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1939 | defer cancel() 1940 | 1941 | webhookID := "webhook-id" 1942 | events := []string{"activity.clicked"} 1943 | 1944 | updateOptions := &mailersend.UpdateWebhookOptions{ 1945 | WebhookID: webhookID, 1946 | Enabled: mailersend.Bool(true), 1947 | Events: events, 1948 | } 1949 | 1950 | _, _, err := ms.Webhook.Update(ctx, updateOptions) 1951 | if err != nil { 1952 | log.Fatal(err) 1953 | } 1954 | } 1955 | ``` 1956 | 1957 | ### Delete a Webhook 1958 | 1959 | ```go 1960 | package main 1961 | 1962 | import ( 1963 | "context" 1964 | "os" 1965 | "log" 1966 | "time" 1967 | 1968 | "github.com/mailersend/mailersend-go" 1969 | ) 1970 | 1971 | func main() { 1972 | // Create an instance of the mailersend client 1973 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 1974 | 1975 | ctx := context.Background() 1976 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 1977 | defer cancel() 1978 | 1979 | webhookID := "webhook-id" 1980 | 1981 | _, err := ms.Webhook.Delete(ctx, webhookID) 1982 | if err != nil { 1983 | log.Fatal(err) 1984 | } 1985 | } 1986 | ``` 1987 | 1988 | ## Templates 1989 | 1990 | ### Get a list of templates 1991 | 1992 | ```go 1993 | package main 1994 | 1995 | import ( 1996 | "context" 1997 | "os" 1998 | "log" 1999 | "time" 2000 | 2001 | "github.com/mailersend/mailersend-go" 2002 | ) 2003 | 2004 | func main() { 2005 | // Create an instance of the mailersend client 2006 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2007 | 2008 | ctx := context.Background() 2009 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2010 | defer cancel() 2011 | 2012 | options := &mailersend.ListTemplateOptions{ 2013 | Page: 1, 2014 | Limit: 25, 2015 | } 2016 | 2017 | _, _, err := ms.Template.List(ctx, options) 2018 | if err != nil { 2019 | log.Fatal(err) 2020 | } 2021 | } 2022 | ``` 2023 | 2024 | ### Get a single template 2025 | 2026 | ```go 2027 | package main 2028 | 2029 | import ( 2030 | "context" 2031 | "os" 2032 | "log" 2033 | "time" 2034 | 2035 | "github.com/mailersend/mailersend-go" 2036 | ) 2037 | 2038 | func main() { 2039 | // Create an instance of the mailersend client 2040 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2041 | 2042 | ctx := context.Background() 2043 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2044 | defer cancel() 2045 | 2046 | templateID := "template-id" 2047 | 2048 | _, _, err := ms.Template.Get(ctx, templateID) 2049 | if err != nil { 2050 | log.Fatal(err) 2051 | } 2052 | } 2053 | ``` 2054 | 2055 | ### Delete a template 2056 | 2057 | ```go 2058 | package main 2059 | 2060 | import ( 2061 | "context" 2062 | "os" 2063 | "log" 2064 | "time" 2065 | 2066 | "github.com/mailersend/mailersend-go" 2067 | ) 2068 | 2069 | func main() { 2070 | // Create an instance of the mailersend client 2071 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2072 | 2073 | ctx := context.Background() 2074 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2075 | defer cancel() 2076 | 2077 | templateID := "template-id" 2078 | 2079 | _, err := ms.Template.Delete(ctx, templateID) 2080 | if err != nil { 2081 | log.Fatal(err) 2082 | } 2083 | } 2084 | ``` 2085 | 2086 | ## Email Verification 2087 | 2088 | ### Verify a single email 2089 | 2090 | ```go 2091 | package main 2092 | 2093 | import ( 2094 | "context" 2095 | "os" 2096 | "log" 2097 | "time" 2098 | 2099 | "github.com/mailersend/mailersend-go" 2100 | ) 2101 | 2102 | func main() { 2103 | // Create an instance of the mailersend client 2104 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2105 | 2106 | ctx := context.Background() 2107 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2108 | defer cancel() 2109 | 2110 | options := &mailersend.SingleEmailVerificationOptions{ 2111 | Email: "john@doe.com" 2112 | } 2113 | 2114 | _, _, err := ms.EmailVerification.VerifySingle(ctx, options) 2115 | if err != nil { 2116 | log.Fatal(err) 2117 | } 2118 | } 2119 | ``` 2120 | 2121 | ### Get all email verification lists 2122 | 2123 | ```go 2124 | package main 2125 | 2126 | import ( 2127 | "context" 2128 | "os" 2129 | "log" 2130 | "time" 2131 | 2132 | "github.com/mailersend/mailersend-go" 2133 | ) 2134 | 2135 | func main() { 2136 | // Create an instance of the mailersend client 2137 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2138 | 2139 | ctx := context.Background() 2140 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2141 | defer cancel() 2142 | 2143 | options := &mailersend.ListEmailVerificationOptions{ 2144 | Page: 1, 2145 | Limit: 25, 2146 | } 2147 | 2148 | _, _, err := ms.EmailVerification.List(ctx, options) 2149 | if err != nil { 2150 | log.Fatal(err) 2151 | } 2152 | } 2153 | ``` 2154 | 2155 | ### Get an email verification list 2156 | 2157 | ```go 2158 | package main 2159 | 2160 | import ( 2161 | "context" 2162 | "os" 2163 | "log" 2164 | "time" 2165 | 2166 | "github.com/mailersend/mailersend-go" 2167 | ) 2168 | 2169 | func main() { 2170 | // Create an instance of the mailersend client 2171 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2172 | 2173 | ctx := context.Background() 2174 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2175 | defer cancel() 2176 | 2177 | _, _, err := ms.EmailVerification.Get(ctx, "email-verification-id") 2178 | if err != nil { 2179 | log.Fatal(err) 2180 | } 2181 | } 2182 | ``` 2183 | 2184 | ### Create an email verification list 2185 | 2186 | ```go 2187 | package main 2188 | 2189 | import ( 2190 | "context" 2191 | "os" 2192 | "log" 2193 | "time" 2194 | 2195 | "github.com/mailersend/mailersend-go" 2196 | ) 2197 | 2198 | func main() { 2199 | // Create an instance of the mailersend client 2200 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2201 | 2202 | ctx := context.Background() 2203 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2204 | defer cancel() 2205 | 2206 | options := &mailersend.CreateEmailVerificationOptions{ 2207 | Name: "Email Verification List ", 2208 | Emails: []string{"your@client.com", "your@client.eu"}, 2209 | } 2210 | 2211 | _, _, err := ms.EmailVerification.Create(ctx, options) 2212 | if err != nil { 2213 | log.Fatal(err) 2214 | } 2215 | } 2216 | ``` 2217 | 2218 | ### Verify an email list 2219 | 2220 | ```go 2221 | package main 2222 | 2223 | import ( 2224 | "context" 2225 | "os" 2226 | "log" 2227 | "time" 2228 | 2229 | "github.com/mailersend/mailersend-go" 2230 | ) 2231 | 2232 | func main() { 2233 | // Create an instance of the mailersend client 2234 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2235 | 2236 | ctx := context.Background() 2237 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2238 | defer cancel() 2239 | 2240 | _, _, err := ms.EmailVerification.Verify(ctx, "email-verification-id") 2241 | if err != nil { 2242 | log.Fatal(err) 2243 | } 2244 | } 2245 | ``` 2246 | 2247 | ### Get email verification list results 2248 | 2249 | ```go 2250 | package main 2251 | 2252 | import ( 2253 | "context" 2254 | "os" 2255 | "log" 2256 | "time" 2257 | 2258 | "github.com/mailersend/mailersend-go" 2259 | ) 2260 | 2261 | func main() { 2262 | // Create an instance of the mailersend client 2263 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2264 | 2265 | ctx := context.Background() 2266 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2267 | defer cancel() 2268 | 2269 | options := &mailersend.GetEmailVerificationOptions{ 2270 | EmailVerificationId: "email-verification-id", 2271 | Page: 1, 2272 | Limit: 25, 2273 | } 2274 | 2275 | _, _, err := ms.EmailVerification.GetResults(ctx, options) 2276 | if err != nil { 2277 | log.Fatal(err) 2278 | } 2279 | } 2280 | ``` 2281 | 2282 | ## SMS 2283 | 2284 | ### Send an SMS 2285 | 2286 | ```go 2287 | package main 2288 | 2289 | import ( 2290 | "context" 2291 | "os" 2292 | "fmt" 2293 | "time" 2294 | 2295 | "github.com/mailersend/mailersend-go" 2296 | ) 2297 | 2298 | func main() { 2299 | // Create an instance of the mailersend client 2300 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2301 | 2302 | ctx := context.Background() 2303 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2304 | defer cancel() 2305 | 2306 | message := ms.Sms.NewMessage() 2307 | message.SetFrom("your-number") 2308 | message.SetTo([]string{"client-number"}) 2309 | message.SetText("This is the message content {{ var }}") 2310 | 2311 | personalization := []mailersend.SmsPersonalization{ 2312 | { 2313 | PhoneNumber: "client-number", 2314 | Data: map[string]interface{}{ 2315 | "var": "foo", 2316 | }, 2317 | }, 2318 | } 2319 | 2320 | message.SetPersonalization(personalization) 2321 | 2322 | res, _ := ms.Sms.Send(context.TODO(), message) 2323 | fmt.Printf(res.Header.Get("X-SMS-Message-Id")) 2324 | } 2325 | ``` 2326 | 2327 | ## SMS Messages 2328 | 2329 | ### Get a list of SMS messages 2330 | 2331 | ```go 2332 | package main 2333 | 2334 | import ( 2335 | "context" 2336 | "os" 2337 | "log" 2338 | "time" 2339 | 2340 | "github.com/mailersend/mailersend-go" 2341 | ) 2342 | 2343 | func main() { 2344 | // Create an instance of the mailersend client 2345 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2346 | 2347 | ctx := context.Background() 2348 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2349 | defer cancel() 2350 | 2351 | options := &mailersend.ListSmsMessageOptions{ 2352 | Limit: 10, 2353 | } 2354 | 2355 | _, _, err := ms.SmsMessage.List(ctx, options) 2356 | if err != nil { 2357 | log.Fatal(err) 2358 | } 2359 | } 2360 | ``` 2361 | 2362 | ### Get info on an SMS message 2363 | 2364 | ```go 2365 | package main 2366 | 2367 | import ( 2368 | "context" 2369 | "os" 2370 | "log" 2371 | "time" 2372 | 2373 | "github.com/mailersend/mailersend-go" 2374 | ) 2375 | 2376 | func main() { 2377 | // Create an instance of the mailersend client 2378 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2379 | 2380 | ctx := context.Background() 2381 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2382 | defer cancel() 2383 | 2384 | _, _, err := ms.SmsMessage.Get(ctx, "sms-message-id") 2385 | if err != nil { 2386 | log.Fatal(err) 2387 | } 2388 | } 2389 | ``` 2390 | 2391 | ## SMS Activity 2392 | 2393 | ### Get a list of SMS activities 2394 | 2395 | ```go 2396 | package main 2397 | 2398 | import ( 2399 | "context" 2400 | "os" 2401 | "log" 2402 | "time" 2403 | 2404 | "github.com/mailersend/mailersend-go" 2405 | ) 2406 | 2407 | func main() { 2408 | // Create an instance of the mailersend client 2409 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2410 | 2411 | ctx := context.Background() 2412 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2413 | defer cancel() 2414 | 2415 | options := &mailersend.SmsActivityOptions{} 2416 | 2417 | _, _, err := ms.SmsActivityService.List(context.TODO(), options) 2418 | if err != nil { 2419 | log.Fatal(err) 2420 | } 2421 | } 2422 | ``` 2423 | 2424 | ### Get activity of a single SMS message 2425 | 2426 | ```go 2427 | package main 2428 | 2429 | import ( 2430 | "context" 2431 | "os" 2432 | "log" 2433 | "time" 2434 | 2435 | "github.com/mailersend/mailersend-go" 2436 | ) 2437 | 2438 | func main() { 2439 | // Create an instance of the mailersend client 2440 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2441 | 2442 | ctx := context.Background() 2443 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2444 | defer cancel() 2445 | 2446 | _, _, err := ms.SmsActivityService.Get(context.TODO(), "message-id") 2447 | if err != nil { 2448 | log.Fatal(err) 2449 | } 2450 | } 2451 | ``` 2452 | 2453 | ## SMS phone numbers 2454 | 2455 | ### Get a list of SMS phone numbers 2456 | 2457 | ```go 2458 | package main 2459 | 2460 | import ( 2461 | "context" 2462 | "os" 2463 | "log" 2464 | "time" 2465 | 2466 | "github.com/mailersend/mailersend-go" 2467 | ) 2468 | 2469 | func main() { 2470 | // Create an instance of the mailersend client 2471 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2472 | 2473 | ctx := context.Background() 2474 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2475 | defer cancel() 2476 | 2477 | options := &mailersend.SmsNumberOptions{} 2478 | 2479 | _, _, err := ms.SmsNumber.List(context.TODO(), options) 2480 | if err != nil { 2481 | log.Fatal(err) 2482 | } 2483 | } 2484 | ``` 2485 | 2486 | ### Get an SMS phone number 2487 | 2488 | ```go 2489 | package main 2490 | 2491 | import ( 2492 | "context" 2493 | "os" 2494 | "log" 2495 | "time" 2496 | 2497 | "github.com/mailersend/mailersend-go" 2498 | ) 2499 | 2500 | func main() { 2501 | // Create an instance of the mailersend client 2502 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2503 | 2504 | ctx := context.Background() 2505 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2506 | defer cancel() 2507 | 2508 | _, _, err := ms.SmsNumber.Get(context.TODO(), "number-id") 2509 | if err != nil { 2510 | log.Fatal(err) 2511 | } 2512 | } 2513 | ``` 2514 | 2515 | ### Update a single SMS phone number 2516 | 2517 | ```go 2518 | package main 2519 | 2520 | import ( 2521 | "context" 2522 | "os" 2523 | "log" 2524 | "time" 2525 | 2526 | "github.com/mailersend/mailersend-go" 2527 | ) 2528 | 2529 | func main() { 2530 | // Create an instance of the mailersend client 2531 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2532 | 2533 | ctx := context.Background() 2534 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2535 | defer cancel() 2536 | 2537 | options := &mailersend.SmsNumberSettingOptions{ 2538 | Id: "number-id", 2539 | Paused: mailersend.Bool(false), 2540 | } 2541 | 2542 | _, _, err := ms.SmsNumber.Update(context.TODO(), options) 2543 | if err != nil { 2544 | log.Fatal(err) 2545 | } 2546 | } 2547 | ``` 2548 | 2549 | 2550 | ### Delete an SMS phone number 2551 | 2552 | ```go 2553 | package main 2554 | 2555 | import ( 2556 | "context" 2557 | "os" 2558 | "log" 2559 | "time" 2560 | 2561 | "github.com/mailersend/mailersend-go" 2562 | ) 2563 | 2564 | func main() { 2565 | // Create an instance of the mailersend client 2566 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2567 | 2568 | ctx := context.Background() 2569 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2570 | defer cancel() 2571 | 2572 | numberID := "number-id" 2573 | 2574 | _, err := ms.SmsNumber.Delete(ctx, numberID) 2575 | if err != nil { 2576 | log.Fatal(err) 2577 | } 2578 | } 2579 | ``` 2580 | 2581 | ## SMS recipients 2582 | 2583 | ### Get a list of SMS recipients 2584 | 2585 | ```go 2586 | package main 2587 | 2588 | import ( 2589 | "context" 2590 | "os" 2591 | "log" 2592 | "time" 2593 | 2594 | "github.com/mailersend/mailersend-go" 2595 | ) 2596 | 2597 | func main() { 2598 | // Create an instance of the mailersend client 2599 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2600 | 2601 | ctx := context.Background() 2602 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2603 | defer cancel() 2604 | 2605 | options := &mailersend.SmsRecipientOptions{SmsNumberId: "sms-number-id"} 2606 | 2607 | _, _, err := ms.SmsRecipient.List(context.TODO(), options) 2608 | if err != nil { 2609 | log.Fatal(err) 2610 | } 2611 | } 2612 | ``` 2613 | 2614 | ### Get an SMS recipient 2615 | 2616 | ```go 2617 | package main 2618 | 2619 | import ( 2620 | "context" 2621 | "os" 2622 | "log" 2623 | "time" 2624 | 2625 | "github.com/mailersend/mailersend-go" 2626 | ) 2627 | 2628 | func main() { 2629 | // Create an instance of the mailersend client 2630 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2631 | 2632 | ctx := context.Background() 2633 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2634 | defer cancel() 2635 | 2636 | _, _, err := ms.SmsRecipient.Get(context.TODO(), "sms-recipient-id") 2637 | if err != nil { 2638 | log.Fatal(err) 2639 | } 2640 | } 2641 | ``` 2642 | 2643 | ### Update a single SMS recipient 2644 | 2645 | ```go 2646 | package main 2647 | 2648 | import ( 2649 | "context" 2650 | "os" 2651 | "log" 2652 | "time" 2653 | 2654 | "github.com/mailersend/mailersend-go" 2655 | ) 2656 | 2657 | func main() { 2658 | // Create an instance of the mailersend client 2659 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2660 | 2661 | ctx := context.Background() 2662 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2663 | defer cancel() 2664 | 2665 | options := &mailersend.SmsRecipientSettingOptions{ 2666 | Id: "sms-recipient-id", 2667 | Status: "opt_out", 2668 | } 2669 | 2670 | _, _, err := ms.SmsRecipient.Update(context.TODO(), options) 2671 | if err != nil { 2672 | log.Fatal(err) 2673 | } 2674 | } 2675 | ``` 2676 | 2677 | 2678 | ## SMS inbounds 2679 | 2680 | ### Get a list of SMS inbound routes 2681 | 2682 | ```go 2683 | package main 2684 | 2685 | import ( 2686 | "context" 2687 | "os" 2688 | "log" 2689 | "time" 2690 | 2691 | "github.com/mailersend/mailersend-go" 2692 | ) 2693 | 2694 | func main() { 2695 | // Create an instance of the mailersend client 2696 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2697 | 2698 | ctx := context.Background() 2699 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2700 | defer cancel() 2701 | 2702 | listOptions := &mailersend.ListSmsInboundOptions{ 2703 | SmsNumberId: "sms-number-id", 2704 | } 2705 | 2706 | _, _, err := ms.SmsInbound.List(ctx, listOptions) 2707 | if err != nil { 2708 | log.Fatal(err) 2709 | } 2710 | } 2711 | ``` 2712 | 2713 | ### Get a single SMS inbound route 2714 | 2715 | ```go 2716 | package main 2717 | 2718 | import ( 2719 | "context" 2720 | "os" 2721 | "log" 2722 | "time" 2723 | 2724 | "github.com/mailersend/mailersend-go" 2725 | ) 2726 | 2727 | func main() { 2728 | // Create an instance of the mailersend client 2729 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2730 | 2731 | ctx := context.Background() 2732 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2733 | defer cancel() 2734 | 2735 | _, _, err := ms.SmsInbound.Get(ctx, "sms-inbound-id") 2736 | if err != nil { 2737 | log.Fatal(err) 2738 | } 2739 | 2740 | } 2741 | ``` 2742 | 2743 | 2744 | ### Create an SMS inbound route 2745 | 2746 | ```go 2747 | package main 2748 | 2749 | import ( 2750 | "context" 2751 | "os" 2752 | "log" 2753 | "time" 2754 | 2755 | "github.com/mailersend/mailersend-go" 2756 | ) 2757 | 2758 | func main() { 2759 | // Create an instance of the mailersend client 2760 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2761 | 2762 | ctx := context.Background() 2763 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2764 | defer cancel() 2765 | 2766 | options := &mailersend.CreateSmsInboundOptions{ 2767 | SmsNumberId: "sms-number-id", 2768 | Name: "Example Route", 2769 | ForwardUrl: "https://example.com", 2770 | Filter: mailersend.Filter{ 2771 | Comparer: "equal", 2772 | Value: "START", 2773 | }, 2774 | Enabled: mailersend.Bool(true), 2775 | } 2776 | 2777 | _, _, err := ms.SmsInbound.Create(ctx, options) 2778 | if err != nil { 2779 | log.Fatal(err) 2780 | } 2781 | } 2782 | ``` 2783 | 2784 | ### Update an SMS inbound route 2785 | 2786 | ```go 2787 | package main 2788 | 2789 | import ( 2790 | "context" 2791 | "os" 2792 | "log" 2793 | "time" 2794 | 2795 | "github.com/mailersend/mailersend-go" 2796 | ) 2797 | 2798 | func main() { 2799 | // Create an instance of the mailersend client 2800 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2801 | 2802 | ctx := context.Background() 2803 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2804 | defer cancel() 2805 | 2806 | options := &mailersend.UpdateSmsInboundOptions{ 2807 | Id: "sms-inbound-id", 2808 | SmsNumberId: "sms-number-id", 2809 | Name: "Example Route", 2810 | ForwardUrl: "https://example.com", 2811 | Filter: mailersend.Filter{ 2812 | Comparer: "equal", 2813 | Value: "START", 2814 | }, 2815 | Enabled: mailersend.Bool(false), 2816 | } 2817 | 2818 | _, _, err := ms.SmsInbound.Update(ctx, options) 2819 | if err != nil { 2820 | log.Fatal(err) 2821 | } 2822 | } 2823 | ``` 2824 | 2825 | ### Delete an SMS inbound route 2826 | 2827 | ```go 2828 | package main 2829 | 2830 | import ( 2831 | "context" 2832 | "os" 2833 | "log" 2834 | "time" 2835 | 2836 | "github.com/mailersend/mailersend-go" 2837 | ) 2838 | 2839 | func main() { 2840 | // Create an instance of the mailersend client 2841 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2842 | 2843 | ctx := context.Background() 2844 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2845 | defer cancel() 2846 | 2847 | _, err := ms.SmsInbound.Delete(ctx, "sms-inbound-id") 2848 | if err != nil { 2849 | log.Fatal(err) 2850 | } 2851 | } 2852 | ``` 2853 | 2854 | ## SMS webhooks 2855 | 2856 | ### Get a list of SMS webhooks 2857 | 2858 | ```go 2859 | package main 2860 | 2861 | import ( 2862 | "context" 2863 | "os" 2864 | "log" 2865 | "time" 2866 | 2867 | "github.com/mailersend/mailersend-go" 2868 | ) 2869 | 2870 | func main() { 2871 | // Create an instance of the mailersend client 2872 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2873 | 2874 | ctx := context.Background() 2875 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2876 | defer cancel() 2877 | 2878 | options := &mailersend.ListSmsWebhookOptions{ 2879 | SmsNumberId: "sms-number-id", 2880 | } 2881 | 2882 | _, _, err := ms.SmsWebhook.List(ctx, options) 2883 | if err != nil { 2884 | log.Fatal(err) 2885 | } 2886 | } 2887 | ``` 2888 | 2889 | ### Get an SMS webhook 2890 | 2891 | ```go 2892 | package main 2893 | 2894 | import ( 2895 | "context" 2896 | "os" 2897 | "log" 2898 | "time" 2899 | 2900 | "github.com/mailersend/mailersend-go" 2901 | ) 2902 | 2903 | func main() { 2904 | // Create an instance of the mailersend client 2905 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2906 | 2907 | ctx := context.Background() 2908 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2909 | defer cancel() 2910 | 2911 | _, _, err := ms.SmsWebhook.Get(ctx, "sms-webhook-id") 2912 | if err != nil { 2913 | log.Fatal(err) 2914 | } 2915 | 2916 | } 2917 | ``` 2918 | 2919 | 2920 | ### Create an SMS webhook 2921 | 2922 | ```go 2923 | package main 2924 | 2925 | import ( 2926 | "context" 2927 | "os" 2928 | "log" 2929 | "time" 2930 | 2931 | "github.com/mailersend/mailersend-go" 2932 | ) 2933 | 2934 | func main() { 2935 | // Create an instance of the mailersend client 2936 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2937 | 2938 | ctx := context.Background() 2939 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2940 | defer cancel() 2941 | 2942 | events := []string{"sms.sent"} 2943 | 2944 | options := &mailersend.CreateSmsWebhookOptions{ 2945 | SmsNumberId: "sms-number-id", 2946 | Name: "Webhook", 2947 | Events: events, 2948 | URL: "https://test.com", 2949 | Enabled: mailersend.Bool(false), 2950 | } 2951 | 2952 | _, _, err := ms.SmsWebhook.Create(ctx, options) 2953 | if err != nil { 2954 | log.Fatal(err) 2955 | } 2956 | } 2957 | ``` 2958 | 2959 | ### Update an SMS webhook 2960 | 2961 | ```go 2962 | package main 2963 | 2964 | import ( 2965 | "context" 2966 | "os" 2967 | "log" 2968 | "time" 2969 | 2970 | "github.com/mailersend/mailersend-go" 2971 | ) 2972 | 2973 | func main() { 2974 | // Create an instance of the mailersend client 2975 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 2976 | 2977 | ctx := context.Background() 2978 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 2979 | defer cancel() 2980 | 2981 | events := []string{"sms.sent"} 2982 | 2983 | options := &mailersend.UpdateSmsWebhookOptions{ 2984 | Id: "sms-webhook-id", 2985 | Name: "Webhook", 2986 | Events: events, 2987 | Enabled: mailersend.Bool(true), 2988 | URL: "https://test.com", 2989 | } 2990 | 2991 | _, _, err := ms.SmsWebhook.Update(ctx, options) 2992 | if err != nil { 2993 | log.Fatal(err) 2994 | } 2995 | } 2996 | ``` 2997 | 2998 | ### Delete an SMS webhook 2999 | 3000 | ```go 3001 | package main 3002 | 3003 | import ( 3004 | "context" 3005 | "os" 3006 | "log" 3007 | "time" 3008 | 3009 | "github.com/mailersend/mailersend-go" 3010 | ) 3011 | 3012 | func main() { 3013 | // Create an instance of the mailersend client 3014 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3015 | 3016 | ctx := context.Background() 3017 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3018 | defer cancel() 3019 | 3020 | _, err := ms.SmsWebhook.Delete(ctx, "sms-webhook-id") 3021 | if err != nil { 3022 | log.Fatal(err) 3023 | } 3024 | } 3025 | ``` 3026 | 3027 | ## Sender identities 3028 | 3029 | ### Get a list of Sender Identities 3030 | 3031 | ```go 3032 | package main 3033 | 3034 | import ( 3035 | "context" 3036 | "os" 3037 | "log" 3038 | "time" 3039 | 3040 | "github.com/mailersend/mailersend-go" 3041 | ) 3042 | 3043 | func main() { 3044 | // Create an instance of the mailersend client 3045 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3046 | 3047 | ctx := context.Background() 3048 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3049 | defer cancel() 3050 | 3051 | options := &mailersend.ListIdentityOptions{ 3052 | DomainID: "domain-id", 3053 | } 3054 | 3055 | _, _, err := ms.Identity.List(ctx, options) 3056 | if err != nil { 3057 | log.Fatal(err) 3058 | } 3059 | } 3060 | ``` 3061 | 3062 | ### Get a single Sender Identity 3063 | 3064 | ```go 3065 | package main 3066 | 3067 | import ( 3068 | "context" 3069 | "os" 3070 | "log" 3071 | "time" 3072 | 3073 | "github.com/mailersend/mailersend-go" 3074 | ) 3075 | 3076 | func main() { 3077 | // Create an instance of the mailersend client 3078 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3079 | 3080 | ctx := context.Background() 3081 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3082 | defer cancel() 3083 | 3084 | _, _, err := ms.Identity.Get(ctx, "identity-id") 3085 | if err != nil { 3086 | log.Fatal(err) 3087 | } 3088 | } 3089 | ``` 3090 | 3091 | ### Get a single Sender Identity By Email 3092 | 3093 | ```go 3094 | package main 3095 | 3096 | import ( 3097 | "context" 3098 | "os" 3099 | "log" 3100 | "time" 3101 | 3102 | "github.com/mailersend/mailersend-go" 3103 | ) 3104 | 3105 | func main() { 3106 | // Create an instance of the mailersend client 3107 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3108 | 3109 | ctx := context.Background() 3110 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3111 | defer cancel() 3112 | 3113 | _, _, err := ms.Identity.GetByEmail(ctx, "identity-email") 3114 | if err != nil { 3115 | log.Fatal(err) 3116 | } 3117 | } 3118 | ``` 3119 | 3120 | ### Create a Sender Identity 3121 | 3122 | ```go 3123 | package main 3124 | 3125 | import ( 3126 | "context" 3127 | "os" 3128 | "log" 3129 | "time" 3130 | 3131 | "github.com/mailersend/mailersend-go" 3132 | ) 3133 | 3134 | func main() { 3135 | // Create an instance of the mailersend client 3136 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3137 | 3138 | ctx := context.Background() 3139 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3140 | defer cancel() 3141 | 3142 | options := &mailersend.CreateIdentityOptions{ 3143 | DomainID: "domain-id", 3144 | Name: "Sender Name", 3145 | Email: "Sender Email", 3146 | } 3147 | 3148 | _, _, err := ms.Identity.Create(ctx, options) 3149 | if err != nil { 3150 | log.Fatal(err) 3151 | } 3152 | } 3153 | ``` 3154 | 3155 | ### Update a Sender Identity 3156 | 3157 | ```go 3158 | package main 3159 | 3160 | import ( 3161 | "context" 3162 | "os" 3163 | "log" 3164 | "time" 3165 | 3166 | "github.com/mailersend/mailersend-go" 3167 | ) 3168 | 3169 | func main() { 3170 | // Create an instance of the mailersend client 3171 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3172 | 3173 | ctx := context.Background() 3174 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3175 | defer cancel() 3176 | 3177 | options := &mailersend.UpdateIdentityOptions{ 3178 | Name: "Sender Name", 3179 | ReplyToEmail: "Reply To Email", 3180 | } 3181 | 3182 | _, _, err := ms.Identity.Update(ctx, "identity-id", options) 3183 | if err != nil { 3184 | log.Fatal(err) 3185 | } 3186 | } 3187 | ``` 3188 | 3189 | ### Update a Sender Identity By Email 3190 | 3191 | ```go 3192 | package main 3193 | 3194 | import ( 3195 | "context" 3196 | "os" 3197 | "log" 3198 | "time" 3199 | 3200 | "github.com/mailersend/mailersend-go" 3201 | ) 3202 | 3203 | func main() { 3204 | // Create an instance of the mailersend client 3205 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3206 | 3207 | ctx := context.Background() 3208 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3209 | defer cancel() 3210 | 3211 | options := &mailersend.UpdateIdentityOptions{ 3212 | Name: "Sender Name", 3213 | ReplyToEmail: "Reply To Email", 3214 | } 3215 | 3216 | _, _, err := ms.Identity.UpdateByEmail(ctx, "identity-email", options) 3217 | if err != nil { 3218 | log.Fatal(err) 3219 | } 3220 | } 3221 | ``` 3222 | 3223 | ### Delete a Sender Identity 3224 | 3225 | ```go 3226 | package main 3227 | 3228 | import ( 3229 | "context" 3230 | "os" 3231 | "log" 3232 | "time" 3233 | 3234 | "github.com/mailersend/mailersend-go" 3235 | ) 3236 | 3237 | func main() { 3238 | // Create an instance of the mailersend client 3239 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3240 | 3241 | ctx := context.Background() 3242 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3243 | defer cancel() 3244 | 3245 | _, err := ms.Identity.Delete(ctx, "identity-id") 3246 | if err != nil { 3247 | log.Fatal(err) 3248 | } 3249 | } 3250 | ``` 3251 | 3252 | ### Delete a Sender Identity By Email 3253 | 3254 | ```go 3255 | package main 3256 | 3257 | import ( 3258 | "context" 3259 | "os" 3260 | "log" 3261 | "time" 3262 | 3263 | "github.com/mailersend/mailersend-go" 3264 | ) 3265 | 3266 | func main() { 3267 | // Create an instance of the mailersend client 3268 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3269 | 3270 | ctx := context.Background() 3271 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3272 | defer cancel() 3273 | 3274 | _, err := ms.Identity.DeleteByEmail(ctx, "identity-email") 3275 | if err != nil { 3276 | log.Fatal(err) 3277 | } 3278 | } 3279 | ``` 3280 | 3281 | ## Other Endpoints 3282 | 3283 | ### Get an API Quota 3284 | 3285 | ```go 3286 | package main 3287 | 3288 | import ( 3289 | "context" 3290 | "log" 3291 | "time" 3292 | "fmt" 3293 | 3294 | "github.com/mailersend/mailersend-go" 3295 | ) 3296 | 3297 | func main() { 3298 | // Create an instance of the mailersend client 3299 | ms := mailersend.NewMailersend(os.Getenv("MAILERSEND_API_KEY")) 3300 | 3301 | ctx := context.Background() 3302 | ctx, cancel := context.WithTimeout(ctx, 5*time.Second) 3303 | defer cancel() 3304 | 3305 | _, _, err := ms.ApiQuota.Get(ctx) 3306 | if err != nil { 3307 | log.Fatal(err) 3308 | } 3309 | } 3310 | ``` 3311 | 3312 | # Types 3313 | 3314 | Most API responses are Unmarshalled into their corresponding types. 3315 | 3316 | You can see all available types on pkg.go.dev 3317 | 3318 | https://pkg.go.dev/github.com/mailersend/mailersend-go#pkg-types 3319 | 3320 | # Helpers 3321 | 3322 | We provide a few helpers to help with development. 3323 | 3324 | ```go 3325 | 3326 | // Create a pointer to a true boolean 3327 | mailersend.Bool(true) 3328 | 3329 | // Create a pointer to a false boolean 3330 | mailersend.Bool(false) 3331 | 3332 | // Create a pointer to a Int 3333 | mailersend.Int(2) 3334 | 3335 | // Create a pointer to a Int64 3336 | mailersend.Int64(2) 3337 | 3338 | // Create a pointer to a String 3339 | mailersend.String("string") 3340 | 3341 | ``` 3342 | 3343 | # Testing 3344 | 3345 | We provide interfaces for all services to help with testing 3346 | 3347 | ```go 3348 | type mockDomainService struct { 3349 | mailersend.DomainService 3350 | } 3351 | 3352 | func (m *mockDomainService) List(ctx context.Context, options *ListDomainOptions) (*DomainRoot, *Response, error) { 3353 | return &mailersend.DomainRoot{Data: []mailersend.Domain{{Name: "example.com"}}}, nil, nil 3354 | } 3355 | 3356 | func TestListDomains(t *testing.T) { 3357 | client := &mailersend.Client{} 3358 | client.Domain = &mockDomainService{} 3359 | 3360 | ctx := context.Background() 3361 | result, _, err := client.Domain.List(ctx, nil) 3362 | if err != nil || len(result.Data) == 0 || result.Data[0].Name != "example.com" { 3363 | t.Fatalf("mock failed") 3364 | } 3365 | } 3366 | ``` 3367 | 3368 | [pkg/testing](https://golang.org/pkg/testing/) 3369 | 3370 | ``` 3371 | $ go test 3372 | ``` 3373 | 3374 | 3375 | # Available endpoints 3376 | 3377 | | Feature group | Endpoint | Available | 3378 | | ------------- | ----------- | --------- | 3379 | | Email | `POST send` | ✅ | 3380 | 3381 | *If, at the moment, some endpoint is not available, please use other available tools to access it. [Refer to official API docs for more info](https://developers.mailersend.com/).* 3382 | 3383 | 3384 | 3385 | # Support and Feedback 3386 | 3387 | In case you find any bugs, submit an issue directly here in GitHub. 3388 | 3389 | You are welcome to create SDK for any other programming language. 3390 | 3391 | If you have any troubles using our API or SDK free to contact our support by email [info@mailersend.com](mailto:info@mailersend.com) 3392 | 3393 | The official documentation is at [https://developers.mailersend.com](https://developers.mailersend.com) 3394 | 3395 | 3396 | # License 3397 | 3398 | [The MIT License (MIT)](LICENSE) 3399 | -------------------------------------------------------------------------------- /activity.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | ) 8 | 9 | const activityBasePath = "/activity" 10 | 11 | type ActivityService interface { 12 | List(ctx context.Context, options *ActivityOptions) (*ActivityRoot, *Response, error) 13 | } 14 | 15 | type activityService struct { 16 | *service 17 | } 18 | 19 | // activityRoot - format of activity response 20 | type ActivityRoot struct { 21 | Data []ActivityData `json:"data"` 22 | Links Links `json:"links"` 23 | Meta Meta `json:"meta"` 24 | } 25 | 26 | type ActivityData struct { 27 | ID string `json:"id"` 28 | CreatedAt string `json:"created_at"` 29 | UpdatedAt string `json:"updated_at"` 30 | Type string `json:"type"` 31 | Email ActivityEmail `json:"email"` 32 | } 33 | 34 | type ActivityEmail struct { 35 | ID string `json:"id"` 36 | From string `json:"from"` 37 | Subject string `json:"subject"` 38 | Text string `json:"text"` 39 | HTML string `json:"html"` 40 | Status string `json:"status"` 41 | Tags interface{} `json:"tags"` 42 | CreatedAt string `json:"created_at"` 43 | UpdatedAt string `json:"updated_at"` 44 | Recipient ActivityRecipient `json:"recipient"` 45 | } 46 | 47 | type ActivityRecipient struct { 48 | ID string `json:"id"` 49 | Email string `json:"email"` 50 | CreatedAt string `json:"created_at"` 51 | UpdatedAt string `json:"updated_at"` 52 | DeletedAt string `json:"deleted_at"` 53 | } 54 | 55 | // ActivityOptions - modifies the behavior of ActivityService.List method 56 | type ActivityOptions struct { 57 | DomainID string `url:"-"` 58 | Page int `url:"page,omitempty"` 59 | DateFrom int64 `url:"date_from,omitempty"` 60 | DateTo int64 `url:"date_to,omitempty"` 61 | Limit int `url:"limit,omitempty"` 62 | Event []string `url:"event[],omitempty"` 63 | } 64 | 65 | func (s *activityService) List(ctx context.Context, options *ActivityOptions) (*ActivityRoot, *Response, error) { 66 | path := fmt.Sprintf("%s/%s", activityBasePath, options.DomainID) 67 | 68 | req, err := s.client.newRequest(http.MethodGet, path, options) 69 | if err != nil { 70 | return nil, nil, err 71 | } 72 | 73 | root := new(ActivityRoot) 74 | res, err := s.client.do(ctx, req, root) 75 | if err != nil { 76 | return nil, res, err 77 | } 78 | 79 | return root, res, nil 80 | } 81 | -------------------------------------------------------------------------------- /activity_test.go: -------------------------------------------------------------------------------- 1 | package mailersend_test 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "testing" 10 | "time" 11 | 12 | "github.com/mailersend/mailersend-go" 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | func TestCanCreateActivityOptions(t *testing.T) { 17 | from := time.Now().Unix() 18 | to := time.Now().Add(-24 * time.Hour).Unix() 19 | 20 | options := mailersend.ActivityOptions{DateFrom: from, DateTo: to} 21 | 22 | assert.Equal(t, 0, options.Limit) 23 | assert.Equal(t, from, options.DateFrom) 24 | assert.Equal(t, to, options.DateTo) 25 | 26 | } 27 | 28 | func TestCanMockActivity(t *testing.T) { 29 | ms := mailersend.NewMailersend(testKey) 30 | 31 | from := time.Now().Unix() 32 | to := time.Now().Add(-24 * time.Hour).Unix() 33 | 34 | client := NewTestClient(func(req *http.Request) *http.Response { 35 | // Test request parameters 36 | 37 | assert.Equal(t, req.URL.String(), fmt.Sprintf("https://api.mailersend.com/v1/activity/domain-id?date_from=%v&date_to=%v", from, to)) 38 | return &http.Response{ 39 | StatusCode: http.StatusAccepted, 40 | Body: io.NopCloser(bytes.NewBufferString(`OK`)), 41 | } 42 | }) 43 | 44 | ctx := context.TODO() 45 | 46 | ms.SetClient(client) 47 | 48 | options := &mailersend.ActivityOptions{DomainID: "domain-id", DateFrom: from, DateTo: to} 49 | 50 | _, _, _ = ms.Activity.List(ctx, options) 51 | 52 | assert.Equal(t, 0, options.Limit) 53 | assert.Equal(t, from, options.DateFrom) 54 | assert.Equal(t, to, options.DateTo) 55 | 56 | } 57 | -------------------------------------------------------------------------------- /analytics.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | ) 8 | 9 | const analyticsBasePath = "/analytics" 10 | 11 | type AnalyticsService interface { 12 | GetActivityByDate(ctx context.Context, options *AnalyticsOptions) (*AnalyticsActivityRoot, *Response, error) 13 | GetOpensByCountry(ctx context.Context, options *AnalyticsOptions) (*OpensRoot, *Response, error) 14 | GetOpensByUserAgent(ctx context.Context, options *AnalyticsOptions) (*OpensRoot, *Response, error) 15 | GetOpensByReadingEnvironment(ctx context.Context, options *AnalyticsOptions) (*OpensRoot, *Response, error) 16 | } 17 | 18 | type analyticsService struct { 19 | *service 20 | } 21 | 22 | // AnalyticsActivityRoot - format of analytics response 23 | type AnalyticsActivityRoot struct { 24 | Data AnalyticsData `json:"data"` 25 | } 26 | 27 | type AnalyticsData struct { 28 | DateFrom string `json:"date_from"` 29 | DateTo string `json:"date_to"` 30 | GroupBy string `json:"group_by"` 31 | Stats []AnalyticsStats `json:"stats"` 32 | } 33 | 34 | type AnalyticsStats struct { 35 | Date string `json:"date"` 36 | Queued int `json:"queued,omitempty"` 37 | Sent int `json:"sent,omitempty"` 38 | Delivered int `json:"delivered,omitempty"` 39 | SoftBounced int `json:"soft_bounced,omitempty"` 40 | HardBounced int `json:"hard_bounced,omitempty"` 41 | Junk int `json:"junk,omitempty"` 42 | Opened int `json:"opened,omitempty"` 43 | Clicked int `json:"clicked,omitempty"` 44 | Unsubscribed int `json:"unsubscribed,omitempty"` 45 | SpamComplaints int `json:"spam_complaints,omitempty"` 46 | } 47 | 48 | type OpensRoot struct { 49 | Data OpenData `json:"data"` 50 | } 51 | 52 | type OpenData struct { 53 | DateFrom int `json:"date_from"` 54 | DateTo int `json:"date_to"` 55 | Stats []OpenStats `json:"stats"` 56 | } 57 | 58 | type OpenStats struct { 59 | Name string `json:"name"` 60 | Count int `json:"count"` 61 | } 62 | 63 | // AnalyticsOptions - modifies the behavior of AnalyticsService methods 64 | type AnalyticsOptions struct { 65 | DomainID string `url:"domain_id,omitempty"` 66 | RecipientID []int64 `url:"recipient_id,omitempty"` 67 | DateFrom int64 `url:"date_from"` 68 | DateTo int64 `url:"date_to"` 69 | GroupBy string `url:"group_by,omitempty"` 70 | Tags []string `url:"tags[],omitempty"` 71 | Event []string `url:"event[],omitempty"` 72 | } 73 | 74 | func (s *analyticsService) GetActivityByDate(ctx context.Context, options *AnalyticsOptions) (*AnalyticsActivityRoot, *Response, error) { 75 | path := fmt.Sprintf("%s/date", analyticsBasePath) 76 | 77 | req, err := s.client.newRequest("GET", path, options) 78 | if err != nil { 79 | return nil, nil, err 80 | } 81 | 82 | root := new(AnalyticsActivityRoot) 83 | res, err := s.client.do(ctx, req, root) 84 | if err != nil { 85 | return nil, res, err 86 | } 87 | 88 | return root, res, nil 89 | } 90 | 91 | func (s *analyticsService) GetOpensByCountry(ctx context.Context, options *AnalyticsOptions) (*OpensRoot, *Response, error) { 92 | path := fmt.Sprintf("%s/country", analyticsBasePath) 93 | 94 | req, err := s.client.newRequest(http.MethodGet, path, options) 95 | if err != nil { 96 | return nil, nil, err 97 | } 98 | 99 | root := new(OpensRoot) 100 | res, err := s.client.do(ctx, req, root) 101 | if err != nil { 102 | return nil, res, err 103 | } 104 | 105 | return root, res, nil 106 | } 107 | 108 | func (s *analyticsService) GetOpensByUserAgent(ctx context.Context, options *AnalyticsOptions) (*OpensRoot, *Response, error) { 109 | path := fmt.Sprintf("%s/ua-name", analyticsBasePath) 110 | 111 | req, err := s.client.newRequest(http.MethodGet, path, options) 112 | if err != nil { 113 | return nil, nil, err 114 | } 115 | 116 | root := new(OpensRoot) 117 | res, err := s.client.do(ctx, req, root) 118 | if err != nil { 119 | return nil, res, err 120 | } 121 | 122 | return root, res, nil 123 | } 124 | 125 | func (s *analyticsService) GetOpensByReadingEnvironment(ctx context.Context, options *AnalyticsOptions) (*OpensRoot, *Response, error) { 126 | path := fmt.Sprintf("%s/ua-type", analyticsBasePath) 127 | 128 | req, err := s.client.newRequest(http.MethodGet, path, options) 129 | if err != nil { 130 | return nil, nil, err 131 | } 132 | 133 | root := new(OpensRoot) 134 | res, err := s.client.do(ctx, req, root) 135 | if err != nil { 136 | return nil, res, err 137 | } 138 | 139 | return root, res, nil 140 | } 141 | -------------------------------------------------------------------------------- /analytics_test.go: -------------------------------------------------------------------------------- 1 | package mailersend_test 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/mailersend/mailersend-go" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestCanCreateAnalyticsOptions(t *testing.T) { 12 | from := time.Now().Unix() 13 | to := time.Now().Add(-24 * time.Hour).Unix() 14 | 15 | domainID := "domain-id" 16 | 17 | options := mailersend.AnalyticsOptions{DomainID: domainID, DateFrom: from, DateTo: to} 18 | 19 | assert.Equal(t, domainID, options.DomainID) 20 | assert.Equal(t, from, options.DateFrom) 21 | assert.Equal(t, to, options.DateTo) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /api_quota.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | const apiQuotaBasePath = "/api-quota" 10 | 11 | type ApiQuotaService interface { 12 | Get(ctx context.Context) (*ApiQuotaRoot, *Response, error) 13 | } 14 | 15 | type apiQuotaService struct { 16 | *service 17 | } 18 | 19 | type ApiQuotaRoot struct { 20 | Quota int `json:"quota"` 21 | Remaining int `json:"remaining"` 22 | Reset time.Time `json:"reset"` 23 | } 24 | 25 | func (s *apiQuotaService) Get(ctx context.Context) (*ApiQuotaRoot, *Response, error) { 26 | req, err := s.client.newRequest(http.MethodGet, apiQuotaBasePath, nil) 27 | if err != nil { 28 | return nil, nil, err 29 | } 30 | 31 | root := new(ApiQuotaRoot) 32 | res, err := s.client.do(ctx, req, root) 33 | if err != nil { 34 | return nil, res, err 35 | } 36 | 37 | return root, res, nil 38 | } 39 | -------------------------------------------------------------------------------- /bulk_email.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const bulkEmailBasePath = "/bulk-email" 11 | 12 | type BulkEmailService interface { 13 | Send(ctx context.Context, message []*Message) (*BulkEmailResponse, *Response, error) 14 | Status(ctx context.Context, bulkEmailID string) (*BulkEmailRoot, *Response, error) 15 | } 16 | 17 | type bulkEmailService struct { 18 | *service 19 | } 20 | 21 | type BulkEmailResponse struct { 22 | Message string `json:"message"` 23 | BulkEmailID string `json:"bulk_email_id"` 24 | } 25 | 26 | type BulkEmailRoot struct { 27 | Data BulkEmailData `json:"data"` 28 | } 29 | type BulkEmailData struct { 30 | ID string `json:"id"` 31 | State string `json:"state"` 32 | TotalRecipientsCount int `json:"total_recipients_count"` 33 | SuppressedRecipientsCount int `json:"suppressed_recipients_count"` 34 | SuppressedRecipients interface{} `json:"suppressed_recipients"` 35 | ValidationErrorsCount int `json:"validation_errors_count"` 36 | ValidationErrors interface{} `json:"validation_errors"` 37 | MessagesID []string `json:"messages_id"` 38 | CreatedAt time.Time `json:"created_at"` 39 | UpdatedAt time.Time `json:"updated_at"` 40 | } 41 | 42 | // Send - send bulk messages 43 | func (s *bulkEmailService) Send(ctx context.Context, message []*Message) (*BulkEmailResponse, *Response, error) { 44 | req, err := s.client.newRequest(http.MethodPost, bulkEmailBasePath, message) 45 | if err != nil { 46 | return nil, nil, err 47 | } 48 | 49 | root := new(BulkEmailResponse) 50 | res, err := s.client.do(ctx, req, root) 51 | if err != nil { 52 | return nil, res, err 53 | } 54 | 55 | return root, res, nil 56 | } 57 | 58 | func (s *bulkEmailService) Status(ctx context.Context, bulkEmailID string) (*BulkEmailRoot, *Response, error) { 59 | path := fmt.Sprintf("%s/%s", bulkEmailBasePath, bulkEmailID) 60 | 61 | req, err := s.client.newRequest(http.MethodGet, path, nil) 62 | if err != nil { 63 | return nil, nil, err 64 | } 65 | 66 | root := new(BulkEmailRoot) 67 | res, err := s.client.do(ctx, req, root) 68 | if err != nil { 69 | return nil, res, err 70 | } 71 | 72 | return root, res, nil 73 | } 74 | -------------------------------------------------------------------------------- /client_test.go: -------------------------------------------------------------------------------- 1 | package mailersend_test 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | type RoundTripFunc func(req *http.Request) *http.Response 8 | 9 | func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) { 10 | return f(req), nil 11 | } 12 | 13 | //NewTestClient returns *http.Client with Transport replaced to avoid making real calls 14 | func NewTestClient(fn RoundTripFunc) *http.Client { 15 | return &http.Client{ 16 | Transport: fn, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /domains.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | ) 8 | 9 | const domainBasePath = "/domains" 10 | 11 | type DomainService interface { 12 | List(ctx context.Context, options *ListDomainOptions) (*DomainRoot, *Response, error) 13 | Get(ctx context.Context, domainID string) (*SingleDomainRoot, *Response, error) 14 | Update(ctx context.Context, options *DomainSettingOptions) (*SingleDomainRoot, *Response, error) 15 | Delete(ctx context.Context, domainID string) (*Response, error) 16 | Create(ctx context.Context, options *CreateDomainOptions) (*SingleDomainRoot, *Response, error) 17 | GetDNS(ctx context.Context, domainID string) (*DnsRoot, *Response, error) 18 | Verify(ctx context.Context, domainID string) (*VerifyRoot, *Response, error) 19 | GetRecipients(ctx context.Context, options *GetRecipientsOptions) (*DomainRecipientRoot, *Response, error) 20 | } 21 | 22 | type domainService struct { 23 | *service 24 | } 25 | 26 | // DomainRoot format of domain response 27 | type DomainRoot struct { 28 | Data []Domain `json:"data"` 29 | Links Links `json:"links"` 30 | Meta Meta `json:"meta"` 31 | } 32 | 33 | // SingleDomainRoot format of domain response 34 | type SingleDomainRoot struct { 35 | Data Domain `json:"data"` 36 | } 37 | 38 | type Domain struct { 39 | ID string `json:"id"` 40 | Name string `json:"name"` 41 | Dkim bool `json:"dkim"` 42 | Spf bool `json:"spf"` 43 | Tracking bool `json:"tracking"` 44 | IsVerified bool `json:"is_verified"` 45 | IsCnameVerified bool `json:"is_cname_verified"` 46 | IsDNSActive bool `json:"is_dns_active"` 47 | IsCnameActive bool `json:"is_cname_active"` 48 | IsTrackingAllowed bool `json:"is_tracking_allowed"` 49 | HasNotQueuedMessages bool `json:"has_not_queued_messages"` 50 | NotQueuedMessagesCount int `json:"not_queued_messages_count"` 51 | DomainSettings DomainSettings `json:"domain_settings"` 52 | CreatedAt string `json:"created_at"` 53 | UpdatedAt string `json:"updated_at"` 54 | } 55 | 56 | type DomainSettings struct { 57 | SendPaused bool `json:"send_paused,omitempty"` 58 | TrackClicks bool `json:"track_clicks,omitempty"` 59 | TrackOpens bool `json:"track_opens,omitempty"` 60 | TrackUnsubscribe bool `json:"track_unsubscribe,omitempty"` 61 | TrackUnsubscribeHTML string `json:"track_unsubscribe_html,omitempty"` 62 | TrackUnsubscribePlain string `json:"track_unsubscribe_plain,omitempty"` 63 | TrackContent bool `json:"track_content,omitempty"` 64 | CustomTrackingEnabled bool `json:"custom_tracking_enabled,omitempty"` 65 | CustomTrackingSubdomain string `json:"custom_tracking_subdomain,omitempty"` 66 | IgnoreDuplicatedRecipients bool `json:"ignore_duplicated_recipients,omitempty"` 67 | PrecedenceBulk bool `json:"precedence_bulk,omitempty"` 68 | } 69 | 70 | type DnsRoot struct { 71 | Data Dns `json:"data"` 72 | } 73 | 74 | type Spf struct { 75 | Hostname string `json:"hostname"` 76 | Type string `json:"type"` 77 | Value string `json:"value"` 78 | } 79 | 80 | type Dkim struct { 81 | Hostname string `json:"hostname"` 82 | Type string `json:"type"` 83 | Value string `json:"value"` 84 | } 85 | 86 | type ReturnPath struct { 87 | Hostname string `json:"hostname"` 88 | Type string `json:"type"` 89 | Value string `json:"value"` 90 | } 91 | 92 | type CustomTracking struct { 93 | Hostname string `json:"hostname"` 94 | Type string `json:"type"` 95 | Value string `json:"value"` 96 | } 97 | 98 | type InboundRouting struct { 99 | Hostname string `json:"hostname"` 100 | Type string `json:"type"` 101 | Value string `json:"value"` 102 | Priority string `json:"priority"` 103 | } 104 | 105 | type Dns struct { 106 | ID string `json:"id"` 107 | Spf Spf `json:"spf"` 108 | Dkim Dkim `json:"dkim"` 109 | ReturnPath ReturnPath `json:"return_path"` 110 | CustomTracking CustomTracking `json:"custom_tracking"` 111 | InboundRouting InboundRouting `json:"inbound_routing"` 112 | } 113 | 114 | type VerifyRoot struct { 115 | Message string `json:"message"` 116 | Data Verify `json:"data"` 117 | } 118 | type Verify struct { 119 | Dkim bool `json:"dkim"` 120 | Spf bool `json:"spf"` 121 | Mx bool `json:"mx"` 122 | Tracking bool `json:"tracking"` 123 | Cname bool `json:"cname"` 124 | RpCname bool `json:"rp_cname"` 125 | } 126 | 127 | // DomainRecipientRoot format of domain response 128 | type DomainRecipientRoot struct { 129 | Data []DomainRecipient `json:"data"` 130 | Links Links `json:"links"` 131 | Meta Meta `json:"meta"` 132 | } 133 | 134 | // DomainRecipient list of domain recipients 135 | type DomainRecipient struct { 136 | ID string `json:"id"` 137 | Email string `json:"email"` 138 | CreatedAt string `json:"created_at"` 139 | UpdatedAt string `json:"updated_at"` 140 | DeletedAt string `json:"deleted_at"` 141 | } 142 | 143 | // ListDomainOptions - modifies the behavior of domainService.List Method 144 | type ListDomainOptions struct { 145 | Page int `url:"page,omitempty"` 146 | Limit int `url:"limit,omitempty"` 147 | Verified *bool `url:"verified,omitempty"` 148 | } 149 | 150 | // DomainSettingOptions - modifies the behavior of domainService.Update Method 151 | type DomainSettingOptions struct { 152 | DomainID string `json:"-"` 153 | SendPaused *bool `json:"send_paused,omitempty"` 154 | TrackClicks *bool `json:"track_clicks,omitempty"` 155 | TrackOpens *bool `json:"track_opens,omitempty"` 156 | TrackUnsubscribe *bool `json:"track_unsubscribe,omitempty"` 157 | TrackUnsubscribeHTML string `json:"track_unsubscribe_html,omitempty"` 158 | TrackUnsubscribePlain string `json:"track_unsubscribe_plain,omitempty"` 159 | TrackContent *bool `json:"track_content,omitempty"` 160 | CustomTrackingEnabled *bool `json:"custom_tracking_enabled,omitempty"` 161 | CustomTrackingSubdomain string `json:"custom_tracking_subdomain,omitempty"` 162 | IgnoreDuplicatedRecipients *bool `json:"ignore_duplicated_recipients,omitempty"` 163 | PrecedenceBulk *bool `json:"precedence_bulk,omitempty"` 164 | } 165 | 166 | type CreateDomainOptions struct { 167 | Name string `json:"name"` 168 | ReturnPathSubdomain string `json:"return_path_subdomain,omitempty"` 169 | CustomTrackingSubdomain string `json:"custom_tracking_subdomain,omitempty"` 170 | InboundRoutingSubdomain string `json:"inbound_routing_subdomain,omitempty"` 171 | } 172 | 173 | // GetRecipientsOptions - modifies the behavior of domainService.GetRecipients Method 174 | type GetRecipientsOptions struct { 175 | DomainID string `url:"-"` 176 | Page int `url:"page,omitempty"` 177 | Limit int `url:"limit,omitempty"` 178 | } 179 | 180 | func (s *domainService) List(ctx context.Context, options *ListDomainOptions) (*DomainRoot, *Response, error) { 181 | req, err := s.client.newRequest(http.MethodGet, domainBasePath, options) 182 | if err != nil { 183 | return nil, nil, err 184 | } 185 | 186 | root := new(DomainRoot) 187 | res, err := s.client.do(ctx, req, root) 188 | if err != nil { 189 | return nil, res, err 190 | } 191 | 192 | return root, res, nil 193 | } 194 | 195 | func (s *domainService) Get(ctx context.Context, domainID string) (*SingleDomainRoot, *Response, error) { 196 | path := fmt.Sprintf("%s/%s", domainBasePath, domainID) 197 | 198 | req, err := s.client.newRequest(http.MethodGet, path, nil) 199 | if err != nil { 200 | return nil, nil, err 201 | } 202 | 203 | root := new(SingleDomainRoot) 204 | res, err := s.client.do(ctx, req, root) 205 | if err != nil { 206 | return nil, res, err 207 | } 208 | 209 | return root, res, nil 210 | } 211 | 212 | func (s *domainService) Update(ctx context.Context, options *DomainSettingOptions) (*SingleDomainRoot, *Response, error) { 213 | path := fmt.Sprintf("%s/%s/settings", domainBasePath, options.DomainID) 214 | 215 | req, err := s.client.newRequest(http.MethodPut, path, options) 216 | if err != nil { 217 | return nil, nil, err 218 | } 219 | 220 | root := new(SingleDomainRoot) 221 | res, err := s.client.do(ctx, req, root) 222 | if err != nil { 223 | return nil, res, err 224 | } 225 | 226 | return root, res, nil 227 | } 228 | 229 | func (s *domainService) Delete(ctx context.Context, domainID string) (*Response, error) { 230 | path := fmt.Sprintf("%s/%s", domainBasePath, domainID) 231 | 232 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 233 | if err != nil { 234 | return nil, err 235 | } 236 | 237 | return s.client.do(ctx, req, nil) 238 | } 239 | 240 | func (s *domainService) Create(ctx context.Context, options *CreateDomainOptions) (*SingleDomainRoot, *Response, error) { 241 | req, err := s.client.newRequest(http.MethodPost, domainBasePath, options) 242 | if err != nil { 243 | return nil, nil, err 244 | } 245 | 246 | root := new(SingleDomainRoot) 247 | res, err := s.client.do(ctx, req, root) 248 | if err != nil { 249 | return nil, res, err 250 | } 251 | 252 | return root, res, nil 253 | } 254 | 255 | func (s *domainService) GetDNS(ctx context.Context, domainID string) (*DnsRoot, *Response, error) { 256 | path := fmt.Sprintf("%s/%s/dns-records", domainBasePath, domainID) 257 | 258 | req, err := s.client.newRequest(http.MethodGet, path, nil) 259 | if err != nil { 260 | return nil, nil, err 261 | } 262 | 263 | root := new(DnsRoot) 264 | res, err := s.client.do(ctx, req, root) 265 | if err != nil { 266 | return nil, res, err 267 | } 268 | 269 | return root, res, nil 270 | } 271 | 272 | func (s *domainService) Verify(ctx context.Context, domainID string) (*VerifyRoot, *Response, error) { 273 | path := fmt.Sprintf("%s/%s/verify", domainBasePath, domainID) 274 | 275 | req, err := s.client.newRequest(http.MethodGet, path, nil) 276 | if err != nil { 277 | return nil, nil, err 278 | } 279 | 280 | root := new(VerifyRoot) 281 | res, err := s.client.do(ctx, req, root) 282 | if err != nil { 283 | return nil, res, err 284 | } 285 | 286 | return root, res, nil 287 | } 288 | 289 | func (s *domainService) GetRecipients(ctx context.Context, options *GetRecipientsOptions) (*DomainRecipientRoot, *Response, error) { 290 | path := fmt.Sprintf("%s/%s/recipients", domainBasePath, options.DomainID) 291 | 292 | req, err := s.client.newRequest(http.MethodGet, path, nil) 293 | if err != nil { 294 | return nil, nil, err 295 | } 296 | 297 | root := new(DomainRecipientRoot) 298 | res, err := s.client.do(ctx, req, root) 299 | if err != nil { 300 | return nil, res, err 301 | } 302 | 303 | return root, res, nil 304 | } 305 | -------------------------------------------------------------------------------- /domains_test.go: -------------------------------------------------------------------------------- 1 | package mailersend_test 2 | 3 | import ( 4 | "github.com/mailersend/mailersend-go" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func TestCanCreateDomainListOptions(t *testing.T) { 10 | options := mailersend.ListDomainOptions{Page: 0, Limit: 25, Verified: mailersend.Bool(true)} 11 | 12 | assert.Equal(t, 0, options.Page) 13 | assert.Equal(t, 25, options.Limit) 14 | assert.Equal(t, mailersend.Bool(true), options.Verified) 15 | 16 | } 17 | 18 | func TestCanCreateDomainOptions(t *testing.T) { 19 | options := mailersend.DomainSettingOptions{ 20 | DomainID: "domain-id", 21 | SendPaused: mailersend.Bool(false), 22 | TrackClicks: mailersend.Bool(true), 23 | TrackOpens: mailersend.Bool(true), 24 | TrackUnsubscribe: mailersend.Bool(true), 25 | TrackUnsubscribeHTML: "", 26 | TrackUnsubscribePlain: "", 27 | TrackContent: mailersend.Bool(true), 28 | CustomTrackingEnabled: mailersend.Bool(true), 29 | CustomTrackingSubdomain: "email.mailersend.com", 30 | } 31 | 32 | options.TrackOpens = mailersend.Bool(false) 33 | 34 | assert.Equal(t, "domain-id", options.DomainID) 35 | assert.Equal(t, mailersend.Bool(false), options.SendPaused) 36 | assert.Equal(t, mailersend.Bool(true), options.TrackClicks) 37 | assert.Equal(t, mailersend.Bool(false), options.TrackOpens) 38 | 39 | } 40 | -------------------------------------------------------------------------------- /email.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | ) 7 | 8 | const emailBasePath = "/email" 9 | 10 | type EmailService interface { 11 | NewMessage() *Message 12 | Send(ctx context.Context, message *Message) (*Response, error) 13 | } 14 | 15 | type emailService struct { 16 | *service 17 | } 18 | 19 | const ( 20 | DispositionInline = "inline" 21 | DispositionAttachment = "attachment" 22 | ) 23 | 24 | // Message structures contain both the message text and the envelop for an e-mail message. 25 | type Message struct { 26 | Recipients []Recipient `json:"to"` 27 | From From `json:"from"` 28 | CC []Recipient `json:"cc,omitempty"` 29 | Bcc []Recipient `json:"bcc,omitempty"` 30 | ReplyTo ReplyTo `json:"reply_to,omitempty"` 31 | InReplyTo string `json:"in_reply_to,omitempty"` 32 | Subject string `json:"subject,omitempty"` 33 | Text string `json:"text,omitempty"` 34 | HTML string `json:"html,omitempty"` 35 | TemplateID string `json:"template_id,omitempty"` 36 | SendAt int64 `json:"send_at,omitempty"` 37 | Tags []string `json:"tags,omitempty"` 38 | Attachments []Attachment `json:"attachments,omitempty"` 39 | 40 | TemplateVariables []Variables `json:"variables"` 41 | Personalization []Personalization `json:"personalization"` 42 | Headers []Header `json:"headers"` 43 | ListUnsubscribe string `json:"list_unsubscribe"` 44 | PrecedenceBulk bool `json:"precedence_bulk,omitempty"` 45 | References []string `json:"references,omitempty"` 46 | Settings Settings `json:"settings,omitempty"` 47 | } 48 | 49 | // From - simple struct to declare from name/ email 50 | type From = Recipient 51 | 52 | // ReplyTo - simple struct to declare from name/ email 53 | type ReplyTo = Recipient 54 | 55 | // Recipient - you can set multiple recipients 56 | type Recipient struct { 57 | Name string `json:"name"` 58 | Email string `json:"email"` 59 | } 60 | 61 | // Deprecated: Variables - you can set multiple Substitutions for each Recipient 62 | type Variables struct { 63 | Email string `json:"email"` 64 | Substitutions []Substitution `json:"substitutions"` 65 | } 66 | 67 | // Deprecated: Substitution - you can set multiple Substitutions for each Recipient 68 | type Substitution struct { 69 | Var string `json:"var"` 70 | Value string `json:"value"` 71 | } 72 | 73 | // Personalization - you can set multiple Personalization for each Recipient 74 | type Personalization struct { 75 | Email string `json:"email"` 76 | Data map[string]interface{} `json:"data"` 77 | } 78 | 79 | // Header - you can set multiple Personalization for each Recipient 80 | type Header struct { 81 | Name string `json:"name"` 82 | Value string `json:"value"` 83 | } 84 | 85 | // Attachment - you can set multiple Attachments 86 | type Attachment struct { 87 | Content string `json:"content"` 88 | Filename string `json:"filename"` 89 | Disposition string `json:"disposition,omitempty"` 90 | ID string `json:"id,omitempty"` 91 | } 92 | 93 | // Settings - you can set email Settings 94 | type Settings struct { 95 | TrackClicks bool `json:"track_clicks"` 96 | TrackOpens bool `json:"track_opens"` 97 | TrackContent bool `json:"track_content"` 98 | } 99 | 100 | // Deprecated: NewMessage - Setup a new message ready to be sent 101 | func (ms *Mailersend) NewMessage() *Message { 102 | return &Message{} 103 | } 104 | 105 | // NewMessage - Setup a new email message ready to be sent. 106 | func (s *emailService) NewMessage() *Message { 107 | return &Message{} 108 | } 109 | 110 | // SetFrom - Set from. 111 | func (m *Message) SetFrom(from From) { 112 | m.From = from 113 | } 114 | 115 | // SetRecipients - Set all the recipients. 116 | func (m *Message) SetRecipients(recipients []Recipient) { 117 | m.Recipients = recipients 118 | } 119 | 120 | // SetCc - Set CC. 121 | func (m *Message) SetCc(cc []Recipient) { 122 | m.CC = cc 123 | } 124 | 125 | // SetBcc - Set Bcc. 126 | func (m *Message) SetBcc(bcc []Recipient) { 127 | m.Bcc = bcc 128 | } 129 | 130 | // SetReplyTo - Set ReplyTo. 131 | func (m *Message) SetReplyTo(replyTo Recipient) { 132 | m.ReplyTo = replyTo 133 | } 134 | 135 | // SetInReplyTo - Set InReplyTo. 136 | func (m *Message) SetInReplyTo(inReplyTo string) { 137 | m.InReplyTo = inReplyTo 138 | } 139 | 140 | // SetSubject - Set the subject of the email, required if not using a template. 141 | func (m *Message) SetSubject(subject string) { 142 | m.Subject = subject 143 | } 144 | 145 | // SetHTML - Set the html content of the email, required if not using a template. 146 | func (m *Message) SetHTML(html string) { 147 | m.HTML = html 148 | } 149 | 150 | // SetText - Set the text content of the email, required if not using a template. 151 | func (m *Message) SetText(text string) { 152 | m.Text = text 153 | } 154 | 155 | // SetTemplateID - Set the template ID. 156 | func (m *Message) SetTemplateID(templateID string) { 157 | m.TemplateID = templateID 158 | } 159 | 160 | // Deprecated: SetSubstitutions - Set the template substitutions. 161 | func (m *Message) SetSubstitutions(variables []Variables) { 162 | m.TemplateVariables = variables 163 | } 164 | 165 | // SetPersonalization - Set the template personalization. 166 | func (m *Message) SetPersonalization(personalization []Personalization) { 167 | m.Personalization = personalization 168 | } 169 | 170 | // SetHeaders - Set the custom headers. 171 | func (m *Message) SetHeaders(headers []Header) { 172 | m.Headers = headers 173 | } 174 | 175 | // SetListUnsubscribe - Set the custom list unsubscribe header (Professional and Enterprise accounts only) 176 | func (m *Message) SetListUnsubscribe(listUnsubscribe string) { 177 | m.ListUnsubscribe = listUnsubscribe 178 | } 179 | 180 | // SetTags - Set all the tags. 181 | func (m *Message) SetTags(tags []string) { 182 | m.Tags = tags 183 | } 184 | 185 | // AddAttachment - Add an attachment base64 encoded content. 186 | func (m *Message) AddAttachment(attachment Attachment) { 187 | m.Attachments = append(m.Attachments, attachment) 188 | } 189 | 190 | // SetSendAt - Set send_at. 191 | func (m *Message) SetSendAt(sendAt int64) { 192 | m.SendAt = sendAt 193 | } 194 | 195 | // SetPrecedenceBulk - Set precedence_bulk 196 | func (m *Message) SetPrecedenceBulk(precedenceBulk bool) { 197 | m.PrecedenceBulk = precedenceBulk 198 | } 199 | 200 | // SetReferences - Set references 201 | func (m *Message) SetReferences(references []string) { 202 | m.References = references 203 | } 204 | 205 | // AddReference - Add a reference 206 | func (m *Message) AddReference(reference string) { 207 | m.References = append(m.References, reference) 208 | } 209 | 210 | // SetSettings - Set settings 211 | func (m *Message) SetSettings(settings Settings) { 212 | m.Settings = settings 213 | } 214 | 215 | // Deprecated: Send - send the message 216 | func (ms *Mailersend) Send(ctx context.Context, message *Message) (*Response, error) { 217 | req, err := ms.newRequest(http.MethodPost, emailBasePath, message) 218 | if err != nil { 219 | return nil, err 220 | } 221 | 222 | return ms.do(ctx, req, nil) 223 | } 224 | 225 | // Send - send the message 226 | func (s *emailService) Send(ctx context.Context, message *Message) (*Response, error) { 227 | req, err := s.client.newRequest(http.MethodPost, emailBasePath, message) 228 | if err != nil { 229 | return nil, err 230 | } 231 | 232 | return s.client.do(ctx, req, nil) 233 | } 234 | -------------------------------------------------------------------------------- /email_test.go: -------------------------------------------------------------------------------- 1 | package mailersend_test 2 | 3 | import ( 4 | "bufio" 5 | "encoding/base64" 6 | "io" 7 | "os" 8 | "testing" 9 | 10 | "github.com/mailersend/mailersend-go" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | const ( 15 | fromName = "Your Name" 16 | fromEmail = "your@domain.com" 17 | 18 | toName = "Your Client" 19 | toEmail = "your@client.com" 20 | 21 | subject = "Subject" 22 | text = "This is the text content" 23 | html = "This is the HTML content
" 24 | 25 | templateID = "123" 26 | ) 27 | 28 | var from = mailersend.From{ 29 | Name: fromName, 30 | Email: fromEmail, 31 | } 32 | 33 | var recipients = []mailersend.Recipient{ 34 | { 35 | Name: toName, 36 | Email: toEmail, 37 | }, 38 | } 39 | 40 | var cc = []mailersend.Recipient{ 41 | { 42 | Name: "CC 1" + toName, 43 | Email: "cc1-" + toEmail, 44 | }, 45 | { 46 | Name: "CC 2" + toName, 47 | Email: "cc2-" + toEmail, 48 | }, 49 | } 50 | 51 | var bcc = []mailersend.Recipient{ 52 | { 53 | Name: "BCC " + toName, 54 | Email: "bcc-" + toEmail, 55 | }, 56 | } 57 | 58 | func basicEmail() *mailersend.Message { 59 | ms := mailersend.NewMailersend(testKey) 60 | 61 | message := ms.NewMessage() 62 | 63 | message.SetFrom(from) 64 | message.SetRecipients(recipients) 65 | message.SetSubject(subject) 66 | message.SetHTML(html) 67 | message.SetText(text) 68 | 69 | return message 70 | } 71 | 72 | func basicEmailNew() *mailersend.Message { 73 | ms := mailersend.NewMailersend(testKey) 74 | 75 | message := ms.Email.NewMessage() 76 | 77 | message.SetFrom(from) 78 | message.SetRecipients(recipients) 79 | message.SetSubject(subject) 80 | message.SetHTML(html) 81 | message.SetText(text) 82 | 83 | return message 84 | } 85 | 86 | func TestSimpleMessage(t *testing.T) { 87 | message := basicEmail() 88 | 89 | assert.Equal(t, from, message.From) 90 | assert.Equal(t, recipients[0], message.Recipients[0]) 91 | assert.Equal(t, subject, message.Subject) 92 | assert.Equal(t, html, message.HTML) 93 | assert.Equal(t, text, message.Text) 94 | } 95 | 96 | func TestSimpleMessageNew(t *testing.T) { 97 | message := basicEmailNew() 98 | 99 | assert.Equal(t, from, message.From) 100 | assert.Equal(t, recipients[0], message.Recipients[0]) 101 | assert.Equal(t, subject, message.Subject) 102 | assert.Equal(t, html, message.HTML) 103 | assert.Equal(t, text, message.Text) 104 | } 105 | 106 | func TestCanCCMessage(t *testing.T) { 107 | message := basicEmail() 108 | message.SetCc(cc) 109 | 110 | assert.Equal(t, cc, message.CC) 111 | } 112 | 113 | func TestCanBCCMessage(t *testing.T) { 114 | message := basicEmail() 115 | message.SetBcc(bcc) 116 | 117 | assert.Equal(t, bcc, message.Bcc) 118 | } 119 | 120 | func TestCanCCBCCMessage(t *testing.T) { 121 | message := basicEmailNew() 122 | message.SetCc(cc) 123 | message.SetBcc(bcc) 124 | 125 | assert.Equal(t, cc, message.CC) 126 | assert.Equal(t, bcc, message.Bcc) 127 | } 128 | 129 | func TestTemplateMessage(t *testing.T) { 130 | message := basicEmail() 131 | 132 | personalization := []mailersend.Personalization{ 133 | { 134 | Email: toEmail, 135 | Data: map[string]interface{}{ 136 | "Var": "foo", 137 | "Value": "bar", 138 | }, 139 | }, 140 | } 141 | 142 | tags := []string{"foo", "bar"} 143 | 144 | message.SetTemplateID(templateID) 145 | message.SetPersonalization(personalization) 146 | message.SetTags(tags) 147 | 148 | assert.Equal(t, templateID, message.TemplateID) 149 | assert.Equal(t, personalization, message.Personalization) 150 | assert.Equal(t, tags, message.Tags) 151 | } 152 | 153 | func TestFullMessage(t *testing.T) { 154 | message := basicEmail() 155 | 156 | message.SetCc(cc) 157 | message.SetBcc(bcc) 158 | 159 | personalization := []mailersend.Personalization{ 160 | { 161 | Email: toEmail, 162 | Data: map[string]interface{}{ 163 | "Var": "foo", 164 | "Value": "bar", 165 | }, 166 | }, 167 | } 168 | 169 | tags := []string{"foo", "bar"} 170 | 171 | message.SetTemplateID(templateID) 172 | message.SetPersonalization(personalization) 173 | message.SetTags(tags) 174 | 175 | assert.Equal(t, cc, message.CC) 176 | assert.Equal(t, bcc, message.Bcc) 177 | assert.Equal(t, from, message.From) 178 | assert.Equal(t, recipients[0], message.Recipients[0]) 179 | assert.Equal(t, subject, message.Subject) 180 | assert.Equal(t, html, message.HTML) 181 | assert.Equal(t, text, message.Text) 182 | assert.Equal(t, templateID, message.TemplateID) 183 | assert.Equal(t, personalization, message.Personalization) 184 | assert.Equal(t, tags, message.Tags) 185 | assert.Len(t, message.Personalization, 1) 186 | 187 | } 188 | 189 | func TestFullMessageNew(t *testing.T) { 190 | message := basicEmailNew() 191 | 192 | message.SetCc(cc) 193 | message.SetBcc(bcc) 194 | 195 | personalization := []mailersend.Personalization{ 196 | { 197 | Email: toEmail, 198 | Data: map[string]interface{}{ 199 | "Var": "foo", 200 | "Value": "bar", 201 | }, 202 | }, 203 | } 204 | 205 | tags := []string{"foo", "bar"} 206 | 207 | message.SetTemplateID(templateID) 208 | message.SetPersonalization(personalization) 209 | message.SetTags(tags) 210 | 211 | assert.Equal(t, cc, message.CC) 212 | assert.Equal(t, bcc, message.Bcc) 213 | assert.Equal(t, from, message.From) 214 | assert.Equal(t, recipients[0], message.Recipients[0]) 215 | assert.Equal(t, subject, message.Subject) 216 | assert.Equal(t, html, message.HTML) 217 | assert.Equal(t, text, message.Text) 218 | assert.Equal(t, templateID, message.TemplateID) 219 | assert.Equal(t, personalization, message.Personalization) 220 | assert.Equal(t, tags, message.Tags) 221 | assert.Len(t, message.Personalization, 1) 222 | 223 | } 224 | 225 | func TestCanAddAttachments(t *testing.T) { 226 | message := basicEmail() 227 | 228 | f, _ := os.Open("./LICENCE") 229 | 230 | reader := bufio.NewReader(f) 231 | content, _ := io.ReadAll(reader) 232 | 233 | encoded := base64.StdEncoding.EncodeToString(content) 234 | 235 | attachment := mailersend.Attachment{Filename: "test", Content: encoded} 236 | 237 | message.AddAttachment(attachment) 238 | 239 | assert.NotNil(t, message, message.Attachments) 240 | assert.Len(t, message.Attachments, 1) 241 | } 242 | -------------------------------------------------------------------------------- /email_verification.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const emailVerificationBasePath = "/email-verification" 11 | 12 | type EmailVerificationService interface { 13 | List(ctx context.Context, options *ListEmailVerificationOptions) (*EmailVerificationRoot, *Response, error) 14 | Get(ctx context.Context, emailVerificationId string) (*SingleEmailVerificationRoot, *Response, error) 15 | Update(ctx context.Context, options *DomainSettingOptions) (*SingleEmailVerificationRoot, *Response, error) 16 | Delete(ctx context.Context, domainID string) (*Response, error) 17 | Create(ctx context.Context, options *CreateEmailVerificationOptions) (*SingleEmailVerificationRoot, *Response, error) 18 | Verify(ctx context.Context, emailVerificationId string) (*SingleEmailVerificationRoot, *Response, error) 19 | VerifySingle(ctx context.Context, options *SingleEmailVerificationOptions) (*ResultSingleEmailVerification, *Response, error) 20 | GetResults(ctx context.Context, options *GetEmailVerificationOptions) (*ResultEmailVerificationRoot, *Response, error) 21 | } 22 | 23 | type emailVerificationService struct { 24 | *service 25 | } 26 | 27 | // EmailVerificationRoot format of verification response 28 | type EmailVerificationRoot struct { 29 | Data []EmailVerification `json:"data"` 30 | Links Links `json:"links"` 31 | Meta Meta `json:"meta"` 32 | } 33 | 34 | // singleDomainRoot format of single verification response 35 | type SingleEmailVerificationRoot struct { 36 | Data EmailVerification `json:"data"` 37 | } 38 | 39 | type ResultEmailVerificationRoot struct { 40 | Data []Result `json:"data"` 41 | Links Links `json:"links"` 42 | Meta Meta `json:"meta"` 43 | } 44 | 45 | type ResultSingleEmailVerification struct { 46 | Status string `json:"status"` 47 | } 48 | 49 | type EmailVerification struct { 50 | Id string `json:"id"` 51 | Name string `json:"name"` 52 | Total int `json:"total"` 53 | VerificationStarted interface{} `json:"verification_started"` 54 | VerificationEnded interface{} `json:"verification_ended"` 55 | CreatedAt time.Time `json:"created_at"` 56 | UpdatedAt time.Time `json:"updated_at"` 57 | Status Status `json:"status"` 58 | Source string `json:"source"` 59 | Statistics Statistics `json:"statistics"` 60 | } 61 | 62 | type Status struct { 63 | Name string `json:"name"` 64 | Count int `json:"count"` 65 | } 66 | 67 | type Statistics struct { 68 | Valid int `json:"valid"` 69 | CatchAll int `json:"catch_all"` 70 | MailboxFull int `json:"mailbox_full"` 71 | RoleBased int `json:"role_based"` 72 | Unknown int `json:"unknown"` 73 | SyntaxError int `json:"syntax_error"` 74 | Typo int `json:"typo"` 75 | MailboxNotFound int `json:"mailbox_not_found"` 76 | Disposable int `json:"disposable"` 77 | MailboxBlocked int `json:"mailbox_blocked"` 78 | Failed int `json:"failed"` 79 | } 80 | 81 | type Result struct { 82 | Address string `json:"address"` 83 | Result string `json:"result"` 84 | } 85 | 86 | // ListEmailVerificationOptions - modifies the behavior of emailVerificationService.List Method 87 | type ListEmailVerificationOptions struct { 88 | Page int `url:"page,omitempty"` 89 | Limit int `url:"limit,omitempty"` 90 | } 91 | 92 | // CreateEmailVerificationOptions - modifies the behavior of emailVerificationService.Create Method 93 | type CreateEmailVerificationOptions struct { 94 | Name string `json:"name"` 95 | Emails []string `json:"emails"` 96 | } 97 | 98 | // GetEmailVerificationOptions - modifies the behavior of emailVerificationService.List and emailVerificationService.GetResult Method 99 | type GetEmailVerificationOptions struct { 100 | EmailVerificationId string `url:"-"` 101 | Page int `url:"page,omitempty"` 102 | Limit int `url:"limit,omitempty"` 103 | } 104 | 105 | type SingleEmailVerificationOptions struct { 106 | Email string `json:"email"` 107 | } 108 | 109 | func (s *emailVerificationService) List(ctx context.Context, options *ListEmailVerificationOptions) (*EmailVerificationRoot, *Response, error) { 110 | req, err := s.client.newRequest(http.MethodGet, emailVerificationBasePath, options) 111 | if err != nil { 112 | return nil, nil, err 113 | } 114 | 115 | root := new(EmailVerificationRoot) 116 | res, err := s.client.do(ctx, req, root) 117 | if err != nil { 118 | return nil, res, err 119 | } 120 | 121 | return root, res, nil 122 | } 123 | 124 | func (s *emailVerificationService) Get(ctx context.Context, emailVerificationId string) (*SingleEmailVerificationRoot, *Response, error) { 125 | path := fmt.Sprintf("%s/%s", emailVerificationBasePath, emailVerificationId) 126 | 127 | req, err := s.client.newRequest(http.MethodGet, path, nil) 128 | if err != nil { 129 | return nil, nil, err 130 | } 131 | 132 | root := new(SingleEmailVerificationRoot) 133 | res, err := s.client.do(ctx, req, root) 134 | if err != nil { 135 | return nil, res, err 136 | } 137 | 138 | return root, res, nil 139 | } 140 | 141 | func (s *emailVerificationService) Update(ctx context.Context, options *DomainSettingOptions) (*SingleEmailVerificationRoot, *Response, error) { 142 | path := fmt.Sprintf("%s/%s/settings", emailVerificationBasePath, options.DomainID) 143 | 144 | req, err := s.client.newRequest(http.MethodPut, path, options) 145 | if err != nil { 146 | return nil, nil, err 147 | } 148 | 149 | root := new(SingleEmailVerificationRoot) 150 | res, err := s.client.do(ctx, req, root) 151 | if err != nil { 152 | return nil, res, err 153 | } 154 | 155 | return root, res, nil 156 | } 157 | 158 | func (s *emailVerificationService) Delete(ctx context.Context, domainID string) (*Response, error) { 159 | path := fmt.Sprintf("%s/%s", emailVerificationBasePath, domainID) 160 | 161 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 162 | if err != nil { 163 | return nil, err 164 | } 165 | 166 | return s.client.do(ctx, req, nil) 167 | } 168 | 169 | func (s *emailVerificationService) Create(ctx context.Context, options *CreateEmailVerificationOptions) (*SingleEmailVerificationRoot, *Response, error) { 170 | req, err := s.client.newRequest(http.MethodPost, emailVerificationBasePath, options) 171 | if err != nil { 172 | return nil, nil, err 173 | } 174 | 175 | root := new(SingleEmailVerificationRoot) 176 | res, err := s.client.do(ctx, req, root) 177 | if err != nil { 178 | return nil, res, err 179 | } 180 | 181 | return root, res, nil 182 | } 183 | 184 | func (s *emailVerificationService) Verify(ctx context.Context, emailVerificationId string) (*SingleEmailVerificationRoot, *Response, error) { 185 | path := fmt.Sprintf("%s/%s/verify", emailVerificationBasePath, emailVerificationId) 186 | 187 | req, err := s.client.newRequest(http.MethodGet, path, nil) 188 | if err != nil { 189 | return nil, nil, err 190 | } 191 | 192 | root := new(SingleEmailVerificationRoot) 193 | res, err := s.client.do(ctx, req, root) 194 | if err != nil { 195 | return nil, res, err 196 | } 197 | 198 | return root, res, nil 199 | } 200 | 201 | func (s *emailVerificationService) VerifySingle(ctx context.Context, options *SingleEmailVerificationOptions) (*ResultSingleEmailVerification, *Response, error) { 202 | path := fmt.Sprintf("%s/verify", emailVerificationBasePath) 203 | 204 | req, err := s.client.newRequest(http.MethodPost, path, options) 205 | if err != nil { 206 | return nil, nil, err 207 | } 208 | 209 | verification := new(ResultSingleEmailVerification) 210 | res, err := s.client.do(ctx, req, verification) 211 | if err != nil { 212 | return nil, res, err 213 | } 214 | 215 | return verification, res, nil 216 | } 217 | 218 | func (s *emailVerificationService) GetResults(ctx context.Context, options *GetEmailVerificationOptions) (*ResultEmailVerificationRoot, *Response, error) { 219 | path := fmt.Sprintf("%s/%s/results", emailVerificationBasePath, options.EmailVerificationId) 220 | 221 | req, err := s.client.newRequest(http.MethodGet, path, nil) 222 | if err != nil { 223 | return nil, nil, err 224 | } 225 | 226 | root := new(ResultEmailVerificationRoot) 227 | res, err := s.client.do(ctx, req, root) 228 | if err != nil { 229 | return nil, res, err 230 | } 231 | 232 | return root, res, nil 233 | } 234 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mailersend/mailersend-go 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/google/go-querystring v1.1.0 7 | github.com/stretchr/testify v1.10.0 8 | ) 9 | 10 | require ( 11 | github.com/davecgh/go-spew v1.1.1 // indirect 12 | github.com/pmezard/go-difflib v1.0.0 // indirect 13 | gopkg.in/yaml.v3 v3.0.1 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= 5 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 6 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= 7 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 8 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 9 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 10 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 11 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 12 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 13 | github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 14 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 15 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 16 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 17 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 18 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 19 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 20 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 21 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 22 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 23 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 24 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 25 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 26 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 27 | -------------------------------------------------------------------------------- /helpers.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | // Activity-related event constants 4 | const ( 5 | EventActivitySent = "activity.sent" // Fired when your email is sent from our sending servers. 6 | EventActivityDelivered = "activity.delivered" // Fired when your email is successfully delivered with no errors. 7 | EventActivitySoftBounced = "activity.soft_bounced" // Fired when your email is not delivered because it soft bounced. 8 | EventActivityHardBounced = "activity.hard_bounced" // Fired when your email is not delivered. 9 | EventActivityOpened = "activity.opened" // Fired when the recipient receives your email and opens it. 10 | EventActivityOpenedUnique = "activity.opened_unique" // Fired when the recipient receives your email and opens it only for the first time. 11 | EventActivityClicked = "activity.clicked" // Fired when the recipient clicks a link in your email. 12 | EventActivityClickedUnique = "activity.clicked_unique" // Fired when the recipient clicks a link in your email only for the first time. 13 | EventActivityUnsubscribed = "activity.unsubscribed" // Fired when the recipient unsubscribes from your emails. 14 | EventActivitySpamComplaint = "activity.spam_complaint" // Fired when the recipient marks your emails as spam or junk. 15 | EventActivitySurveyOpened = "activity.survey_opened" // Fired when the recipient opens an email containing a survey for the first time. 16 | EventActivitySurveySubmitted = "activity.survey_submitted" // Fired when the recipient answers all available questions in a survey-based email or after an idle time of 30 minutes. 17 | ) 18 | 19 | // Sender identity-related event constants 20 | const ( 21 | EventSenderIdentityVerified = "sender_identity.verified" // Fired when the sender identity has been successfully verified. 22 | ) 23 | 24 | // Maintenance-related event constants 25 | const ( 26 | EventMaintenanceStart = "maintenance.start" // Fired when the maintenance period begins. 27 | EventMaintenanceEnd = "maintenance.end" // Fired when the maintenance period ends. 28 | ) 29 | 30 | // Inbound forward-related event constants 31 | const ( 32 | EventInboundForwardFailed = "inbound_forward.failed" // Fired when an inbound message fails to forward. 33 | ) 34 | -------------------------------------------------------------------------------- /inbound.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | ) 8 | 9 | const inboundBasePath = "/inbound" 10 | 11 | type InboundService interface { 12 | List(ctx context.Context, options *ListInboundOptions) (*InboundRoot, *Response, error) 13 | Get(ctx context.Context, inboundID string) (*SingleInboundRoot, *Response, error) 14 | Create(ctx context.Context, options *CreateInboundOptions) (*SingleInboundRoot, *Response, error) 15 | Update(ctx context.Context, inboundID string, options *UpdateInboundOptions) (*SingleInboundRoot, *Response, error) 16 | Delete(ctx context.Context, inboundID string) (*Response, error) 17 | } 18 | 19 | type inboundService struct { 20 | *service 21 | } 22 | 23 | // InboundRoot - format of webhook response 24 | type InboundRoot struct { 25 | Data []Inbound `json:"data"` 26 | Links Links `json:"links"` 27 | Meta Meta `json:"meta"` 28 | } 29 | 30 | // SingleInboundRoot - format of Inbound response 31 | type SingleInboundRoot struct { 32 | Data Inbound `json:"data"` 33 | } 34 | 35 | type Inbound struct { 36 | ID string `json:"id"` 37 | Name string `json:"name"` 38 | Address string `json:"address"` 39 | Domain string `json:"domain"` 40 | DNSCheckedAt interface{} `json:"dns_checked_at"` 41 | Priority int `json:"priority"` 42 | Enabled bool `json:"enabled"` 43 | Filters []Filters `json:"filters"` 44 | Forwards []Forwards `json:"forwards"` 45 | MxValues mxValues `json:"mxValues"` 46 | } 47 | 48 | type Filters struct { 49 | Type string `json:"type"` 50 | Key interface{} `json:"key"` 51 | Comparer string `json:"comparer"` 52 | Value string `json:"value"` 53 | } 54 | 55 | type Forwards struct { 56 | ID string `json:"id"` 57 | Type string `json:"type"` 58 | Value string `json:"value"` 59 | Secret string `json:"secret"` 60 | } 61 | 62 | type mxValues struct { 63 | Priority string `json:"priority"` 64 | Target string `json:"target"` 65 | } 66 | 67 | // ListInboundOptions - modifies the behavior of *inboundService.List Method 68 | type ListInboundOptions struct { 69 | DomainID string `url:"domain_id"` 70 | Page int `url:"page,omitempty"` 71 | Limit int `url:"limit,omitempty"` 72 | } 73 | 74 | // CreateInboundOptions - the Options to set when creating an inbound resource 75 | type CreateInboundOptions struct { 76 | DomainID string `json:"domain_id"` 77 | Name string `json:"name"` 78 | DomainEnabled bool `json:"domain_enabled"` 79 | InboundDomain string `json:"inbound_domain,omitempty"` 80 | InboundAddress string `json:"inbound_address,omitempty"` 81 | InboundSubdomain string `json:"inbound_subdomain,omitempty"` 82 | InboundPriority int `json:"inbound_priority,omitempty"` 83 | MatchFilter *MatchFilter `json:"match_filter,omitempty"` 84 | CatchFilter *CatchFilter `json:"catch_filter,omitempty"` 85 | Forwards []ForwardsFilter `json:"forwards"` 86 | } 87 | 88 | type MatchFilter struct { 89 | Type string `json:"type,omitempty"` 90 | } 91 | 92 | type CatchFilter struct { 93 | Type string `json:"type,omitempty"` 94 | Filters []Filter `json:"filters,omitempty"` 95 | } 96 | 97 | type ForwardsFilter struct { 98 | Type string `json:"type"` 99 | Value string `json:"value"` 100 | } 101 | 102 | // UpdateInboundOptions - the Options to set when creating an inbound resource 103 | type UpdateInboundOptions CreateInboundOptions 104 | 105 | func (s *inboundService) List(ctx context.Context, options *ListInboundOptions) (*InboundRoot, *Response, error) { 106 | req, err := s.client.newRequest(http.MethodGet, inboundBasePath, options) 107 | if err != nil { 108 | return nil, nil, err 109 | } 110 | 111 | root := new(InboundRoot) 112 | res, err := s.client.do(ctx, req, root) 113 | if err != nil { 114 | return nil, res, err 115 | } 116 | 117 | return root, res, nil 118 | } 119 | 120 | func (s *inboundService) Get(ctx context.Context, inboundID string) (*SingleInboundRoot, *Response, error) { 121 | path := fmt.Sprintf("%s/%s", inboundBasePath, inboundID) 122 | 123 | req, err := s.client.newRequest(http.MethodGet, path, nil) 124 | if err != nil { 125 | return nil, nil, err 126 | } 127 | 128 | root := new(SingleInboundRoot) 129 | res, err := s.client.do(ctx, req, root) 130 | if err != nil { 131 | return nil, res, err 132 | } 133 | 134 | return root, res, nil 135 | } 136 | 137 | func (s *inboundService) Create(ctx context.Context, options *CreateInboundOptions) (*SingleInboundRoot, *Response, error) { 138 | req, err := s.client.newRequest(http.MethodPost, inboundBasePath, options) 139 | if err != nil { 140 | return nil, nil, err 141 | } 142 | 143 | root := new(SingleInboundRoot) 144 | res, err := s.client.do(ctx, req, root) 145 | if err != nil { 146 | return nil, res, err 147 | } 148 | 149 | return root, res, nil 150 | } 151 | 152 | func (s *inboundService) Update(ctx context.Context, inboundID string, options *UpdateInboundOptions) (*SingleInboundRoot, *Response, error) { 153 | path := fmt.Sprintf("%s/%s", inboundBasePath, inboundID) 154 | 155 | req, err := s.client.newRequest(http.MethodPut, path, options) 156 | if err != nil { 157 | return nil, nil, err 158 | } 159 | 160 | root := new(SingleInboundRoot) 161 | res, err := s.client.do(ctx, req, root) 162 | if err != nil { 163 | return nil, res, err 164 | } 165 | 166 | return root, res, nil 167 | } 168 | 169 | func (s *inboundService) Delete(ctx context.Context, inboundID string) (*Response, error) { 170 | path := fmt.Sprintf("%s/%s", inboundBasePath, inboundID) 171 | 172 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 173 | if err != nil { 174 | return nil, err 175 | } 176 | 177 | return s.client.do(ctx, req, nil) 178 | } 179 | -------------------------------------------------------------------------------- /mailersend.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "encoding/json" 7 | "fmt" 8 | "io" 9 | "net/http" 10 | "net/url" 11 | "reflect" 12 | 13 | "github.com/google/go-querystring/query" 14 | ) 15 | 16 | const APIBase string = "https://api.mailersend.com/v1" 17 | 18 | // Mailersend - base mailersend api client 19 | type Mailersend struct { 20 | apiBase string 21 | apiKey string 22 | client *http.Client 23 | 24 | common service // Reuse a single struct. 25 | 26 | // Services 27 | Activity ActivityService 28 | Analytics AnalyticsService 29 | Domain DomainService 30 | Email EmailService 31 | BulkEmail BulkEmailService 32 | Message MessageService 33 | ScheduleMessage ScheduleMessageService 34 | Recipient RecipientService 35 | Template TemplateService 36 | Token TokenService 37 | Webhook WebhookService 38 | Suppression SuppressionService 39 | Inbound InboundService 40 | Sms SmsService 41 | SmsActivity SmsActivityService 42 | SmsNumber SmsNumberService 43 | SmsRecipient SmsRecipientService 44 | SmsWebhook SmsWebhookService 45 | SmsMessage SmsMessageService 46 | SmsInbound SmsInboundService 47 | EmailVerification EmailVerificationService 48 | Identity IdentityService 49 | ApiQuota ApiQuotaService 50 | } 51 | 52 | type service struct { 53 | client *Mailersend 54 | } 55 | 56 | // Response is a Mailersend API response. This wraps the standard http.Response 57 | // returned from Mailersend and provides convenient access to things like 58 | // pagination links. 59 | type Response struct { 60 | *http.Response 61 | } 62 | 63 | type ErrorResponse struct { 64 | Response *http.Response // HTTP response that caused this error 65 | Message string `json:"message"` // error message 66 | } 67 | 68 | func (r *ErrorResponse) Error() string { 69 | return fmt.Sprintf("%v %v: %d %v", 70 | r.Response.Request.Method, r.Response.Request.URL, 71 | r.Response.StatusCode, r.Message) 72 | } 73 | 74 | // AuthError occurs when using HTTP Authentication fails 75 | type AuthError ErrorResponse 76 | 77 | func (r *AuthError) Error() string { return (*ErrorResponse)(r).Error() } 78 | 79 | // Meta - used for api responses 80 | type Meta struct { 81 | CurrentPage json.Number `json:"current_page"` 82 | From json.Number `json:"from"` 83 | Path string `json:"path"` 84 | PerPage json.Number `json:"per_page"` 85 | To json.Number `json:"to"` 86 | } 87 | 88 | // Links - used for api responses 89 | type Links struct { 90 | First string `json:"first"` 91 | Last string `json:"last"` 92 | Prev string `json:"prev"` 93 | Next string `json:"next"` 94 | } 95 | 96 | // Filter - used to filter resources 97 | type Filter struct { 98 | Comparer string `json:"comparer"` 99 | Value string `json:"value"` 100 | Key string `json:"key,omitempty"` 101 | } 102 | 103 | // NewMailersend - creates a new client instance. 104 | func NewMailersend(apiKey string) *Mailersend { 105 | ms := &Mailersend{ 106 | apiBase: APIBase, 107 | apiKey: apiKey, 108 | client: http.DefaultClient, 109 | } 110 | 111 | ms.common.client = ms 112 | ms.Activity = &activityService{&ms.common} 113 | ms.Analytics = &analyticsService{&ms.common} 114 | ms.Domain = &domainService{&ms.common} 115 | ms.Email = &emailService{&ms.common} 116 | ms.BulkEmail = &bulkEmailService{&ms.common} 117 | ms.Message = &messageService{&ms.common} 118 | ms.ScheduleMessage = &scheduleMessageService{&ms.common} 119 | ms.Recipient = &recipientService{&ms.common} 120 | ms.Template = &templateService{&ms.common} 121 | ms.Token = &tokenService{&ms.common} 122 | ms.Webhook = &webhookService{&ms.common} 123 | ms.Suppression = &suppressionService{&ms.common} 124 | ms.Inbound = &inboundService{&ms.common} 125 | ms.Sms = &smsService{&ms.common} 126 | ms.SmsActivity = &smsActivityService{&ms.common} 127 | ms.SmsNumber = &smsNumberService{&ms.common} 128 | ms.SmsRecipient = &smsRecipientService{&ms.common} 129 | ms.SmsWebhook = &smsWebhookService{&ms.common} 130 | ms.SmsMessage = &smsMessageService{&ms.common} 131 | ms.SmsInbound = &smsInboundService{&ms.common} 132 | ms.EmailVerification = &emailVerificationService{&ms.common} 133 | ms.Identity = &identityService{&ms.common} 134 | ms.ApiQuota = &apiQuotaService{&ms.common} 135 | 136 | return ms 137 | } 138 | 139 | // APIKey - Get api key after it has been created 140 | func (ms *Mailersend) APIKey() string { 141 | return ms.apiKey 142 | } 143 | 144 | // Client - Get the current client 145 | func (ms *Mailersend) Client() *http.Client { 146 | return ms.client 147 | } 148 | 149 | // SetClient - Set the client if you want more control over the client implementation 150 | func (ms *Mailersend) SetClient(c *http.Client) { 151 | ms.client = c 152 | } 153 | 154 | // SetAPIKey - Set the client api key 155 | func (ms *Mailersend) SetAPIKey(apikey string) { 156 | ms.apiKey = apikey 157 | } 158 | 159 | func (ms *Mailersend) newRequest(method, path string, body interface{}) (*http.Request, error) { 160 | reqURL := fmt.Sprintf("%s%s", ms.apiBase, path) 161 | reqBodyBytes := new(bytes.Buffer) 162 | 163 | if method == http.MethodPost || 164 | method == http.MethodPut || 165 | method == http.MethodDelete { 166 | err := json.NewEncoder(reqBodyBytes).Encode(body) 167 | if err != nil { 168 | return nil, err 169 | } 170 | } else if method == http.MethodGet { 171 | reqURL, _ = addOptions(reqURL, body) 172 | } 173 | 174 | req, err := http.NewRequest(method, reqURL, reqBodyBytes) 175 | if err != nil { 176 | return nil, err 177 | } 178 | 179 | req.Header.Set("Content-Type", "application/json") 180 | req.Header.Add("Authorization", "Bearer "+ms.apiKey) 181 | req.Header.Set("Accept", "application/json") 182 | req.Header.Set("User-Agent", "Mailersend-Client-Golang-v1") 183 | 184 | return req, nil 185 | } 186 | 187 | func (ms *Mailersend) do(ctx context.Context, req *http.Request, v interface{}) (*Response, error) { 188 | req = req.WithContext(ctx) 189 | resp, err := ms.client.Do(req) 190 | if err != nil { 191 | select { 192 | case <-ctx.Done(): 193 | return nil, ctx.Err() 194 | default: 195 | } 196 | return nil, err 197 | } 198 | 199 | if v != nil { 200 | err = json.NewDecoder(resp.Body).Decode(v) 201 | if err != nil { 202 | return nil, err 203 | } 204 | } 205 | 206 | response := newResponse(resp) 207 | 208 | err = CheckResponse(resp) 209 | if err != nil { 210 | defer resp.Body.Close() 211 | _, readErr := io.ReadAll(resp.Body) 212 | if readErr != nil { 213 | return response, readErr 214 | } 215 | } 216 | 217 | return response, err 218 | } 219 | 220 | // newResponse creates a new Response for the provided http.Response. 221 | // r must not be nil. 222 | func newResponse(r *http.Response) *Response { 223 | response := &Response{Response: r} 224 | return response 225 | } 226 | 227 | // CheckResponse checks the API response for errors, and returns them if 228 | // present. A response is considered an error if it has a status code outside 229 | // the 200 range or equal to 202 Accepted. 230 | func CheckResponse(r *http.Response) error { 231 | if r.StatusCode == http.StatusAccepted { 232 | return nil 233 | } 234 | if c := r.StatusCode; 200 <= c && c <= 299 { 235 | return nil 236 | } 237 | 238 | errorResponse := &ErrorResponse{Response: r} 239 | data, err := io.ReadAll(r.Body) 240 | if err == nil && data != nil { 241 | json.Unmarshal(data, errorResponse) 242 | } 243 | 244 | switch { 245 | case r.StatusCode == http.StatusUnauthorized: 246 | return (*AuthError)(errorResponse) 247 | default: 248 | return errorResponse 249 | } 250 | } 251 | 252 | func addOptions(s string, opt interface{}) (string, error) { 253 | v := reflect.ValueOf(opt) 254 | 255 | if v.Kind() == reflect.Ptr && v.IsNil() { 256 | return s, nil 257 | } 258 | 259 | origURL, err := url.Parse(s) 260 | if err != nil { 261 | return s, err 262 | } 263 | 264 | origValues := origURL.Query() 265 | 266 | newValues, err := query.Values(opt) 267 | if err != nil { 268 | return s, err 269 | } 270 | 271 | for k, v := range newValues { 272 | origValues[k] = v 273 | } 274 | 275 | origURL.RawQuery = origValues.Encode() 276 | return origURL.String(), nil 277 | } 278 | 279 | // Bool is a helper routine that allocates a new bool value 280 | // to store v and returns a pointer to it. 281 | func Bool(v bool) *bool { return &v } 282 | 283 | // Int is a helper routine that allocates a new int value 284 | // to store v and returns a pointer to it. 285 | func Int(v int) *int { return &v } 286 | 287 | // Int64 is a helper routine that allocates a new int64 value 288 | // to store v and returns a pointer to it. 289 | func Int64(v int64) *int64 { return &v } 290 | 291 | // String is a helper routine that allocates a new string value 292 | // to store v and returns a pointer to it. 293 | func String(v string) *string { return &v } 294 | -------------------------------------------------------------------------------- /mailersend_test.go: -------------------------------------------------------------------------------- 1 | package mailersend_test 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "io" 7 | "net/http" 8 | "testing" 9 | 10 | "github.com/mailersend/mailersend-go" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | const ( 15 | testKey = "valid-mailersend-api-key" 16 | ) 17 | 18 | func TestNewMailersend(t *testing.T) { 19 | ms := mailersend.NewMailersend(testKey) 20 | 21 | assert.Equal(t, ms.APIKey(), testKey) 22 | assert.Equal(t, ms.Client(), http.DefaultClient) 23 | 24 | client := new(http.Client) 25 | ms.SetClient(client) 26 | assert.Equal(t, client, ms.Client()) 27 | 28 | } 29 | 30 | func TestCanMakeMockApiCall(t *testing.T) { 31 | 32 | ms := mailersend.NewMailersend(testKey) 33 | 34 | client := NewTestClient(func(req *http.Request) *http.Response { 35 | // Test request parameters 36 | assert.Equal(t, req.URL.String(), "https://api.mailersend.com/v1/email") 37 | return &http.Response{ 38 | StatusCode: http.StatusAccepted, 39 | Body: io.NopCloser(bytes.NewBufferString(`OK`)), 40 | } 41 | }) 42 | 43 | ctx := context.TODO() 44 | 45 | ms.SetClient(client) 46 | 47 | message := ms.Email.NewMessage() 48 | 49 | res, err := ms.Email.Send(ctx, message) 50 | if err != nil { 51 | return 52 | } 53 | 54 | assert.Equal(t, res.StatusCode, http.StatusAccepted) 55 | 56 | } 57 | 58 | func TestWillHandleError(t *testing.T) { 59 | ms := mailersend.NewMailersend(testKey) 60 | 61 | client := NewTestClient(func(req *http.Request) *http.Response { 62 | // return nil to force error from mock server 63 | return nil 64 | }) 65 | 66 | ctx := context.TODO() 67 | 68 | ms.SetClient(client) 69 | 70 | message := ms.Email.NewMessage() 71 | 72 | _, err := ms.Email.Send(ctx, message) 73 | 74 | assert.Error(t, err) 75 | 76 | } 77 | 78 | func TestCanSetApiKey(t *testing.T) { 79 | 80 | ms := mailersend.NewMailersend(testKey) 81 | 82 | client := NewTestClient(func(req *http.Request) *http.Response { 83 | switch req.Header.Get("Authorization") { 84 | case "Bearer valid-mailersend-api-key": 85 | return &http.Response{ 86 | StatusCode: 200, 87 | Body: io.NopCloser(bytes.NewBufferString(`OK`)), 88 | } 89 | case "Bearer new-api-key": 90 | return &http.Response{ 91 | StatusCode: 401, 92 | Body: io.NopCloser(bytes.NewBufferString(`ERROR`)), 93 | } 94 | } 95 | 96 | return nil 97 | }) 98 | 99 | ctx := context.TODO() 100 | 101 | ms.SetClient(client) 102 | 103 | message := ms.Email.NewMessage() 104 | 105 | res, _ := ms.Email.Send(ctx, message) 106 | 107 | assert.Equal(t, res.StatusCode, http.StatusOK) 108 | 109 | ms.SetAPIKey("new-api-key") 110 | 111 | resError, _ := ms.Email.Send(ctx, message) 112 | 113 | assert.NotEqual(t, resError.StatusCode, http.StatusAccepted) 114 | assert.Equal(t, resError.StatusCode, http.StatusUnauthorized) 115 | 116 | } 117 | -------------------------------------------------------------------------------- /messages.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const messageBasePath = "/messages" 11 | 12 | type MessageService interface { 13 | List(ctx context.Context, options *ListMessageOptions) (*MessageRoot, *Response, error) 14 | Get(ctx context.Context, messageID string) (*SingleMessageRoot, *Response, error) 15 | } 16 | 17 | type messageService struct { 18 | *service 19 | } 20 | 21 | // MessageRoot format of message response 22 | type MessageRoot struct { 23 | Data []MessageData `json:"data"` 24 | Links Links `json:"links"` 25 | Meta Meta `json:"meta"` 26 | } 27 | 28 | type MessageData struct { 29 | ID string `json:"id"` 30 | CreatedAt time.Time `json:"created_at"` 31 | UpdatedAt time.Time `json:"updated_at"` 32 | } 33 | 34 | type SingleMessageRoot struct { 35 | Data SingleMessage `json:"data"` 36 | } 37 | 38 | type SingleMessage struct { 39 | ID string `json:"id"` 40 | Emails []Email `json:"emails"` 41 | Domain Domain `json:"domain"` 42 | CreatedAt time.Time `json:"created_at"` 43 | UpdatedAt time.Time `json:"updated_at"` 44 | } 45 | 46 | type Email struct { 47 | ID string `json:"id"` 48 | From string `json:"from"` 49 | Subject string `json:"subject,omitempty"` 50 | Text string `json:"text,omitempty"` 51 | HTML string `json:"html,omitempty"` 52 | Tags []string `json:"tags,omitempty"` 53 | Status string `json:"status,omitempty"` 54 | CreatedAt time.Time `json:"created_at"` 55 | UpdatedAt time.Time `json:"updated_at"` 56 | } 57 | 58 | // ListMessageOptions - modifies the behavior of MessageService.List Method 59 | type ListMessageOptions struct { 60 | Page int `url:"page,omitempty"` 61 | Limit int `url:"limit,omitempty"` 62 | } 63 | 64 | func (s *messageService) List(ctx context.Context, options *ListMessageOptions) (*MessageRoot, *Response, error) { 65 | req, err := s.client.newRequest(http.MethodGet, messageBasePath, options) 66 | if err != nil { 67 | return nil, nil, err 68 | } 69 | 70 | root := new(MessageRoot) 71 | res, err := s.client.do(ctx, req, root) 72 | if err != nil { 73 | return nil, res, err 74 | } 75 | 76 | return root, res, nil 77 | } 78 | 79 | func (s *messageService) Get(ctx context.Context, messageID string) (*SingleMessageRoot, *Response, error) { 80 | path := fmt.Sprintf("%s/%s", messageBasePath, messageID) 81 | 82 | req, err := s.client.newRequest(http.MethodGet, path, nil) 83 | if err != nil { 84 | return nil, nil, err 85 | } 86 | 87 | root := new(SingleMessageRoot) 88 | res, err := s.client.do(ctx, req, root) 89 | if err != nil { 90 | return nil, res, err 91 | } 92 | 93 | return root, res, nil 94 | } 95 | -------------------------------------------------------------------------------- /messages_test.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "encoding/json" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestCanCreateMessagesOptions(t *testing.T) { 12 | options := ListMessageOptions{ 13 | Page: 1, 14 | Limit: 25, 15 | } 16 | 17 | assert.Equal(t, 1, options.Page) 18 | assert.Equal(t, 25, options.Limit) 19 | 20 | } 21 | 22 | func TestCodeMessageGetResponse(t *testing.T) { 23 | response := `{ 24 | "data": { 25 | "id": "654be07896ceecb1b0548728", 26 | "created_at": "2023-11-08T19:24:40.000000Z", 27 | "updated_at": "2023-11-08T19:24:40.000000Z", 28 | "emails": [ 29 | { 30 | "id": "654be078bd7e66234bc9288a", 31 | "from": "johnsmith@domain.com", 32 | "subject": "subject", 33 | "text": null, 34 | "html": null, 35 | "status": "delivered", 36 | "tags": null, 37 | "created_at": "2023-11-08T19:24:40.000000Z", 38 | "updated_at": "2023-11-08T19:24:48.000000Z" 39 | } 40 | ], 41 | "domain": { 42 | "id": "0p7kx4xxr9749yjr", 43 | "name": "domain.com", 44 | "dkim": true, 45 | "spf": true, 46 | "tracking": false, 47 | "is_verified": true, 48 | "is_cname_verified": false, 49 | "is_dns_active": true, 50 | "is_cname_active": false, 51 | "is_tracking_allowed": false, 52 | "has_not_queued_messages": false, 53 | "not_queued_messages_count": 0, 54 | "domain_settings": { 55 | "send_paused": false, 56 | "track_clicks": true, 57 | "track_opens": true, 58 | "track_unsubscribe": false, 59 | "track_unsubscribe_html": "Click here to unsubscribe
", 60 | "track_unsubscribe_html_enabled": false, 61 | "track_unsubscribe_plain": "Click here to unsubscribe: {$unsubscribe}", 62 | "track_unsubscribe_plain_enabled": false, 63 | "track_content": false, 64 | "custom_tracking_enabled": false, 65 | "custom_tracking_subdomain": "email", 66 | "return_path_subdomain": "mta", 67 | "inbound_routing_enabled": false, 68 | "inbound_routing_subdomain": "inbound", 69 | "precedence_bulk": false, 70 | "ignore_duplicated_recipients": false 71 | }, 72 | "created_at": "2023-10-23T00:25:20.000000Z", 73 | "updated_at": "2023-10-23T00:43:28.000000Z", 74 | "totals": { 75 | "sent": 0, 76 | "delivered": 27, 77 | "hard_bounced": 0, 78 | "soft_bounced": 1 79 | } 80 | } 81 | } 82 | }` 83 | 84 | var root SingleMessageRoot 85 | err := json.NewDecoder(strings.NewReader(response)).Decode(&root) 86 | if err != nil { 87 | t.Error(err) 88 | } 89 | if root.Data.ID != "654be07896ceecb1b0548728" { 90 | t.Errorf("root.Data.ID = %s; want 654be07896ceecb1b0548728", root.Data.ID) 91 | } 92 | if len(root.Data.Emails) != 1 { 93 | t.Errorf("len(res.Data.Emails) = %d; want 1", len(root.Data.Emails)) 94 | } 95 | if root.Data.Emails[0].From != "johnsmith@domain.com" { 96 | t.Errorf("res.Data.Emails[0].From = %s; want johnsmith@domain.com", root.Data.Emails[0].From) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /recipients.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | ) 8 | 9 | const recipientBasePath = "/recipients" 10 | 11 | type RecipientService interface { 12 | List(ctx context.Context, options *ListRecipientOptions) (*RecipientRoot, *Response, error) 13 | Get(ctx context.Context, recipientID string) (*SingleRecipientRoot, *Response, error) 14 | Delete(ctx context.Context, recipientID string) (*Response, error) 15 | } 16 | 17 | type recipientService struct { 18 | *service 19 | } 20 | 21 | // RecipientRoot - recipients response 22 | type RecipientRoot struct { 23 | Data []RecipientObject `json:"data"` 24 | Links Links `json:"links"` 25 | Meta Meta `json:"meta"` 26 | } 27 | 28 | // SingleRecipientRoot - single recipient response 29 | type SingleRecipientRoot struct { 30 | Data RecipientData `json:"data"` 31 | } 32 | 33 | type RecipientData struct { 34 | ID string `json:"id"` 35 | Email string `json:"email"` 36 | CreatedAt string `json:"created_at"` 37 | UpdatedAt string `json:"updated_at"` 38 | DeletedAt string `json:"deleted_at"` 39 | Emails []interface{} `json:"emails"` 40 | Domain Domain `json:"domain"` 41 | } 42 | 43 | // RecipientObject - a single RecipientObject 44 | type RecipientObject struct { 45 | ID string `json:"id"` 46 | Email string `json:"email"` 47 | CreatedAt string `json:"created_at"` 48 | UpdatedAt string `json:"updated_at"` 49 | DeletedAt string `json:"deleted_at"` 50 | } 51 | 52 | // ListRecipientOptions - modifies the behavior of RecipientService.List method 53 | type ListRecipientOptions struct { 54 | DomainID string `url:"domain_id,omitempty"` 55 | Page int `url:"page,omitempty"` 56 | Limit int `url:"limit,omitempty"` 57 | } 58 | 59 | func (s *recipientService) List(ctx context.Context, options *ListRecipientOptions) (*RecipientRoot, *Response, error) { 60 | req, err := s.client.newRequest(http.MethodGet, recipientBasePath, options) 61 | if err != nil { 62 | return nil, nil, err 63 | } 64 | 65 | root := new(RecipientRoot) 66 | res, err := s.client.do(ctx, req, root) 67 | if err != nil { 68 | return nil, res, err 69 | } 70 | 71 | return root, res, nil 72 | } 73 | 74 | func (s *recipientService) Get(ctx context.Context, recipientID string) (*SingleRecipientRoot, *Response, error) { 75 | path := fmt.Sprintf("%s/%s", recipientBasePath, recipientID) 76 | 77 | req, err := s.client.newRequest(http.MethodGet, path, nil) 78 | if err != nil { 79 | return nil, nil, err 80 | } 81 | 82 | root := new(SingleRecipientRoot) 83 | res, err := s.client.do(ctx, req, root) 84 | if err != nil { 85 | return nil, res, err 86 | } 87 | 88 | return root, res, nil 89 | } 90 | 91 | func (s *recipientService) Delete(ctx context.Context, recipientID string) (*Response, error) { 92 | path := fmt.Sprintf("%s/%s", recipientBasePath, recipientID) 93 | 94 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 95 | if err != nil { 96 | return nil, err 97 | } 98 | 99 | return s.client.do(ctx, req, nil) 100 | 101 | } 102 | -------------------------------------------------------------------------------- /schedule_message.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const messageScheduleBasePath = "/message-schedules" 11 | 12 | type ScheduleMessageService interface { 13 | List(ctx context.Context, options *ListScheduleMessageOptions) (*ScheduleMessageRoot, *Response, error) 14 | Get(ctx context.Context, messageID string) (*ScheduleMessageSingleRoot, *Response, error) 15 | Delete(ctx context.Context, messageID string) (*Response, error) 16 | } 17 | 18 | type scheduleMessageService struct { 19 | *service 20 | } 21 | 22 | type ScheduleMessageRoot struct { 23 | Data []ScheduleMessageData `json:"data"` 24 | Links Links `json:"links"` 25 | Meta Meta `json:"meta"` 26 | } 27 | 28 | type ScheduleMessageData struct { 29 | MessageID string `json:"message_id"` 30 | Subject string `json:"subject"` 31 | SendAt time.Time `json:"send_at"` 32 | Status string `json:"status"` 33 | StatusMessage interface{} `json:"status_message"` 34 | CreatedAt string `json:"created_at"` 35 | } 36 | 37 | type ScheduleMessageSingleRoot struct { 38 | Data ScheduleMessageSingleData `json:"data"` 39 | } 40 | 41 | type ScheduleDomain struct { 42 | ID string `json:"id"` 43 | Name string `json:"name"` 44 | CreatedAt time.Time `json:"created_at"` 45 | UpdatedAt time.Time `json:"updated_at"` 46 | } 47 | 48 | type ScheduleMessage struct { 49 | ID string `json:"id"` 50 | CreatedAt time.Time `json:"created_at"` 51 | UpdatedAt time.Time `json:"updated_at"` 52 | } 53 | 54 | type ScheduleMessageSingleData struct { 55 | MessageID string `json:"message_id"` 56 | Subject string `json:"subject"` 57 | SendAt time.Time `json:"send_at"` 58 | Status string `json:"status"` 59 | StatusMessage interface{} `json:"status_message"` 60 | CreatedAt time.Time `json:"created_at"` 61 | Domain ScheduleDomain `json:"domain"` 62 | Message ScheduleMessage `json:"message"` 63 | } 64 | 65 | // ListScheduleMessageOptions - modifies the behavior of MessageService.List Method 66 | type ListScheduleMessageOptions struct { 67 | DomainID string `url:"domain_id,omitempty"` 68 | Status string `url:"status,omitempty"` 69 | Page int `url:"page,omitempty"` 70 | Limit int `url:"limit,omitempty"` 71 | } 72 | 73 | func (s *scheduleMessageService) List(ctx context.Context, options *ListScheduleMessageOptions) (*ScheduleMessageRoot, *Response, error) { 74 | req, err := s.client.newRequest(http.MethodGet, messageScheduleBasePath, options) 75 | if err != nil { 76 | return nil, nil, err 77 | } 78 | 79 | root := new(ScheduleMessageRoot) 80 | res, err := s.client.do(ctx, req, root) 81 | if err != nil { 82 | return nil, res, err 83 | } 84 | 85 | return root, res, nil 86 | } 87 | 88 | func (s *scheduleMessageService) Get(ctx context.Context, messageID string) (*ScheduleMessageSingleRoot, *Response, error) { 89 | path := fmt.Sprintf("%s/%s", messageScheduleBasePath, messageID) 90 | 91 | req, err := s.client.newRequest(http.MethodGet, path, nil) 92 | if err != nil { 93 | return nil, nil, err 94 | } 95 | 96 | root := new(ScheduleMessageSingleRoot) 97 | res, err := s.client.do(ctx, req, root) 98 | if err != nil { 99 | return nil, res, err 100 | } 101 | 102 | return root, res, nil 103 | } 104 | 105 | func (s *scheduleMessageService) Delete(ctx context.Context, messageID string) (*Response, error) { 106 | path := fmt.Sprintf("%s/%s", messageScheduleBasePath, messageID) 107 | 108 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 109 | if err != nil { 110 | return nil, err 111 | } 112 | 113 | return s.client.do(ctx, req, nil) 114 | } 115 | -------------------------------------------------------------------------------- /sender_identities.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const identitiesBasePath = "/identities" 11 | 12 | type IdentityService interface { 13 | List(ctx context.Context, options *ListIdentityOptions) (*IdentityRoot, *Response, error) 14 | Get(ctx context.Context, identityID string) (*SingleIdentityRoot, *Response, error) 15 | GetByEmail(ctx context.Context, identityEmail string) (*SingleIdentityRoot, *Response, error) 16 | Create(ctx context.Context, options *CreateIdentityOptions) (*SingleIdentityRoot, *Response, error) 17 | Update(ctx context.Context, identityID string, options *UpdateIdentityOptions) (*SingleIdentityRoot, *Response, error) 18 | UpdateByEmail(ctx context.Context, identityEmail string, options *UpdateIdentityOptions) (*SingleIdentityRoot, *Response, error) 19 | Delete(ctx context.Context, identityID string) (*Response, error) 20 | DeleteByEmail(ctx context.Context, identityEmail string) (*Response, error) 21 | } 22 | 23 | type identityService struct { 24 | *service 25 | } 26 | 27 | // IdentityRoot - format of identity response 28 | type IdentityRoot struct { 29 | Data []Identity `json:"data"` 30 | Links Links `json:"links"` 31 | Meta Meta `json:"meta"` 32 | } 33 | 34 | // SingleIdentityRoot - format of inbound response 35 | type SingleIdentityRoot struct { 36 | Data Identity `json:"data"` 37 | } 38 | 39 | type Identity struct { 40 | ID string `json:"id"` 41 | Email string `json:"email"` 42 | Name string `json:"name"` 43 | ReplyToEmail interface{} `json:"reply_to_email"` 44 | ReplyToName interface{} `json:"reply_to_name"` 45 | IsVerified bool `json:"is_verified"` 46 | Resends int `json:"resends"` 47 | AddNote bool `json:"add_note"` 48 | PersonalNote interface{} `json:"personal_note"` 49 | Domain IdentityDomain `json:"domain"` 50 | } 51 | 52 | type IdentityDomain struct { 53 | ID string `json:"id"` 54 | Name string `json:"name"` 55 | CreatedAt time.Time `json:"created_at"` 56 | UpdatedAt time.Time `json:"updated_at"` 57 | } 58 | 59 | // ListIdentityOptions - modifies the behavior of *IdentityService.List Method 60 | type ListIdentityOptions struct { 61 | DomainID string `url:"domain_id"` 62 | Page int `url:"page,omitempty"` 63 | Limit int `url:"limit,omitempty"` 64 | } 65 | 66 | type CreateIdentityOptions struct { 67 | DomainID string `json:"domain_id"` 68 | Name string `json:"name"` 69 | Email string `json:"email"` 70 | PersonalNote string `json:"personal_note"` 71 | ReplyToName string `json:"reply_to_name"` 72 | ReplyToEmail string `json:"reply_to_email"` 73 | AddNote bool `json:"add_note"` 74 | } 75 | 76 | // UpdateIdentityOptions - the Options to set when creating an Identity resource 77 | type UpdateIdentityOptions CreateIdentityOptions 78 | 79 | func (s *identityService) List(ctx context.Context, options *ListIdentityOptions) (*IdentityRoot, *Response, error) { 80 | req, err := s.client.newRequest(http.MethodGet, identitiesBasePath, options) 81 | if err != nil { 82 | return nil, nil, err 83 | } 84 | 85 | root := new(IdentityRoot) 86 | res, err := s.client.do(ctx, req, root) 87 | if err != nil { 88 | return nil, res, err 89 | } 90 | 91 | return root, res, nil 92 | } 93 | 94 | func (s *identityService) Get(ctx context.Context, identityID string) (*SingleIdentityRoot, *Response, error) { 95 | path := fmt.Sprintf("%s/%s", identitiesBasePath, identityID) 96 | 97 | req, err := s.client.newRequest(http.MethodGet, path, nil) 98 | if err != nil { 99 | return nil, nil, err 100 | } 101 | 102 | root := new(SingleIdentityRoot) 103 | res, err := s.client.do(ctx, req, root) 104 | if err != nil { 105 | return nil, res, err 106 | } 107 | 108 | return root, res, nil 109 | } 110 | 111 | func (s *identityService) GetByEmail(ctx context.Context, identityEmail string) (*SingleIdentityRoot, *Response, error) { 112 | path := fmt.Sprintf("%s/email/%s", identitiesBasePath, identityEmail) 113 | 114 | req, err := s.client.newRequest(http.MethodGet, path, nil) 115 | if err != nil { 116 | return nil, nil, err 117 | } 118 | 119 | root := new(SingleIdentityRoot) 120 | res, err := s.client.do(ctx, req, root) 121 | if err != nil { 122 | return nil, res, err 123 | } 124 | 125 | return root, res, nil 126 | } 127 | 128 | func (s *identityService) Create(ctx context.Context, options *CreateIdentityOptions) (*SingleIdentityRoot, *Response, error) { 129 | req, err := s.client.newRequest(http.MethodPost, identitiesBasePath, options) 130 | if err != nil { 131 | return nil, nil, err 132 | } 133 | 134 | root := new(SingleIdentityRoot) 135 | res, err := s.client.do(ctx, req, root) 136 | if err != nil { 137 | return nil, res, err 138 | } 139 | 140 | return root, res, nil 141 | } 142 | 143 | func (s *identityService) Update(ctx context.Context, identityID string, options *UpdateIdentityOptions) (*SingleIdentityRoot, *Response, error) { 144 | path := fmt.Sprintf("%s/%s", identitiesBasePath, identityID) 145 | 146 | req, err := s.client.newRequest(http.MethodPut, path, options) 147 | if err != nil { 148 | return nil, nil, err 149 | } 150 | 151 | root := new(SingleIdentityRoot) 152 | res, err := s.client.do(ctx, req, root) 153 | if err != nil { 154 | return nil, res, err 155 | } 156 | 157 | return root, res, nil 158 | } 159 | 160 | func (s *identityService) UpdateByEmail(ctx context.Context, identityEmail string, options *UpdateIdentityOptions) (*SingleIdentityRoot, *Response, error) { 161 | path := fmt.Sprintf("%s/email/%s", identitiesBasePath, identityEmail) 162 | 163 | req, err := s.client.newRequest(http.MethodPut, path, options) 164 | if err != nil { 165 | return nil, nil, err 166 | } 167 | 168 | root := new(SingleIdentityRoot) 169 | res, err := s.client.do(ctx, req, root) 170 | if err != nil { 171 | return nil, res, err 172 | } 173 | 174 | return root, res, nil 175 | } 176 | 177 | func (s *identityService) Delete(ctx context.Context, identityID string) (*Response, error) { 178 | path := fmt.Sprintf("%s/%s", identitiesBasePath, identityID) 179 | 180 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 181 | if err != nil { 182 | return nil, err 183 | } 184 | 185 | return s.client.do(ctx, req, nil) 186 | } 187 | 188 | func (s *identityService) DeleteByEmail(ctx context.Context, identityEmail string) (*Response, error) { 189 | path := fmt.Sprintf("%s/email/%s", identitiesBasePath, identityEmail) 190 | 191 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 192 | if err != nil { 193 | return nil, err 194 | } 195 | 196 | return s.client.do(ctx, req, nil) 197 | } 198 | -------------------------------------------------------------------------------- /sms.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | const smsBasePath = "/sms" 10 | 11 | type SmsService interface { 12 | NewMessage() *Sms 13 | Send(ctx context.Context, sms *Sms) (*Response, error) 14 | } 15 | 16 | type smsService struct { 17 | *service 18 | } 19 | 20 | type Sms struct { 21 | From string `json:"from"` 22 | To []string `json:"to"` 23 | Text string `json:"text"` 24 | Personalization []SmsPersonalization `json:"personalization,omitempty"` 25 | } 26 | 27 | // SmsPersonalization - you can set multiple SmsPersonalization for each Recipient 28 | type SmsPersonalization struct { 29 | PhoneNumber string `json:"phone_number"` 30 | Data map[string]interface{} `json:"data"` 31 | } 32 | 33 | type SmsMessageRoot struct { 34 | Data SmsMessageData `json:"data"` 35 | } 36 | 37 | type SmsMessageData struct { 38 | Id string `json:"id"` 39 | From string `json:"from"` 40 | To []string `json:"to"` 41 | Text string `json:"text"` 42 | Paused bool `json:"paused"` 43 | CreatedAt time.Time `json:"created_at"` 44 | SmsMessage []SmsMessage `json:"sms"` 45 | SmsActivityData []SmsActivityData `json:"sms_activity"` 46 | } 47 | 48 | type SmsMessage struct { 49 | Id string `json:"id"` 50 | From string `json:"from"` 51 | To string `json:"to"` 52 | Text string `json:"text"` 53 | Status string `json:"status"` 54 | SegmentCount int `json:"segment_count"` 55 | ErrorType interface{} `json:"error_type"` 56 | ErrorDescription interface{} `json:"error_description"` 57 | } 58 | 59 | // NewMessage - Setup a new Sms message ready to be sent. 60 | func (s *smsService) NewMessage() *Sms { 61 | return &Sms{} 62 | } 63 | 64 | // SetFrom - Set from. 65 | func (m *Sms) SetFrom(from string) { 66 | m.From = from 67 | } 68 | 69 | // SetTo - Set to. 70 | func (m *Sms) SetTo(to []string) { 71 | m.To = to 72 | } 73 | 74 | // SetText - Set the text content of the email, required if not using a template. 75 | func (m *Sms) SetText(text string) { 76 | m.Text = text 77 | } 78 | 79 | // SetPersonalization - Set the template personalization. 80 | func (m *Sms) SetPersonalization(personalization []SmsPersonalization) { 81 | m.Personalization = personalization 82 | } 83 | 84 | // Send - send the message 85 | func (s *smsService) Send(ctx context.Context, sms *Sms) (*Response, error) { 86 | req, err := s.client.newRequest(http.MethodPost, smsBasePath, sms) 87 | if err != nil { 88 | return nil, err 89 | } 90 | 91 | return s.client.do(ctx, req, nil) 92 | } 93 | -------------------------------------------------------------------------------- /sms_activity.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const smsActivityPath = "/sms-activity" 11 | 12 | type SmsActivityService interface { 13 | List(ctx context.Context, options *SmsActivityOptions) (*SmsListActivityRoot, *Response, error) 14 | Get(ctx context.Context, smsMessageID string) (*SmsMessageRoot, *Response, error) 15 | } 16 | 17 | type smsActivityService struct { 18 | *service 19 | } 20 | 21 | // SmsListActivityRoot - format of activity response 22 | type SmsListActivityRoot struct { 23 | Data []SmsActivityData `json:"data"` 24 | Links Links `json:"links"` 25 | Meta Meta `json:"meta"` 26 | } 27 | 28 | // SmsActivityData - format of sms activity data 29 | type SmsActivityData struct { 30 | From string `json:"from"` 31 | To string `json:"to"` 32 | CreatedAt time.Time `json:"created_at"` 33 | Status string `json:"status"` 34 | SmsMessageId string `json:"sms_message_id"` 35 | } 36 | 37 | // SmsActivityOptions - modifies the behavior of SmsService.Activity method 38 | type SmsActivityOptions struct { 39 | SmsNumberId string `url:"sms_number_id,omitempty"` 40 | Status []string `url:"status[],omitempty"` 41 | Page int `url:"page,omitempty"` 42 | DateFrom int64 `url:"date_from,omitempty"` 43 | DateTo int64 `url:"date_to,omitempty"` 44 | Limit int `url:"limit,omitempty"` 45 | } 46 | 47 | func (s *smsActivityService) List(ctx context.Context, options *SmsActivityOptions) (*SmsListActivityRoot, *Response, error) { 48 | req, err := s.client.newRequest(http.MethodGet, smsActivityPath, options) 49 | if err != nil { 50 | return nil, nil, err 51 | } 52 | 53 | root := new(SmsListActivityRoot) 54 | res, err := s.client.do(ctx, req, root) 55 | if err != nil { 56 | return nil, res, err 57 | } 58 | 59 | return root, res, nil 60 | } 61 | 62 | func (s *smsActivityService) Get(ctx context.Context, smsMessageID string) (*SmsMessageRoot, *Response, error) { 63 | path := fmt.Sprintf("%s/%s", smsMessagesPath, smsMessageID) 64 | 65 | req, err := s.client.newRequest(http.MethodGet, path, nil) 66 | if err != nil { 67 | return nil, nil, err 68 | } 69 | 70 | root := new(SmsMessageRoot) 71 | res, err := s.client.do(ctx, req, root) 72 | if err != nil { 73 | return nil, res, err 74 | } 75 | 76 | return root, res, nil 77 | } 78 | -------------------------------------------------------------------------------- /sms_inbound.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const smsInboundPath = "/sms-inbounds" 11 | 12 | type SmsInboundService interface { 13 | List(ctx context.Context, options *ListSmsInboundOptions) (*SmsInboundRoot, *Response, error) 14 | Get(ctx context.Context, smsInboundId string) (*SingleSmsInboundRoot, *Response, error) 15 | Create(ctx context.Context, options *CreateSmsInboundOptions) (*SingleSmsInboundRoot, *Response, error) 16 | Update(ctx context.Context, options *UpdateSmsInboundOptions) (*SingleSmsInboundRoot, *Response, error) 17 | Delete(ctx context.Context, smsInboundId string) (*Response, error) 18 | } 19 | 20 | type smsInboundService struct { 21 | *service 22 | } 23 | 24 | // SmsInboundRoot - format of activity response 25 | type SmsInboundRoot struct { 26 | Data []SmsInbound `json:"data"` 27 | Links Links `json:"links"` 28 | Meta Meta `json:"meta"` 29 | } 30 | 31 | // SingleSmsInboundRoot - format of activity response 32 | type SingleSmsInboundRoot struct { 33 | Data SmsInbound `json:"data"` 34 | } 35 | 36 | type SmsInbound struct { 37 | Id string `json:"id"` 38 | Name string `json:"name"` 39 | Filter Filter 40 | ForwardUrl string `json:"forward_url"` 41 | Enabled bool `json:"enabled"` 42 | Secret string `json:"secret"` 43 | CreatedAt time.Time `json:"created_at"` 44 | } 45 | 46 | // CreateSmsInboundOptions - modifies the behavior of *WebhookService.Create Method 47 | type CreateSmsInboundOptions struct { 48 | SmsNumberId string `json:"sms_number_id"` 49 | Name string `json:"name"` 50 | ForwardUrl string `json:"forward_url"` 51 | Filter Filter `json:"filter"` 52 | Enabled *bool `json:"enabled"` 53 | } 54 | 55 | // UpdateSmsInboundOptions - modifies the behavior of SmsNumbersService.Update method 56 | type UpdateSmsInboundOptions struct { 57 | Id string `json:"-"` 58 | SmsNumberId string `json:"sms_number_id,omitempty"` 59 | Name string `json:"name,omitempty"` 60 | ForwardUrl string `json:"forward_url,omitempty"` 61 | Filter Filter `json:"filter,omitempty"` 62 | Enabled *bool `json:"enabled,omitempty"` 63 | } 64 | 65 | // ListSmsInboundOptions - modifies the behavior of SmsNumbersService.List method 66 | type ListSmsInboundOptions struct { 67 | SmsNumberId string `url:"sms_number_id,omitempty"` 68 | Enabled *bool `url:"enabled,omitempty"` 69 | Page int `url:"page,omitempty"` 70 | Limit int `url:"limit,omitempty"` 71 | } 72 | 73 | func (s *smsInboundService) List(ctx context.Context, options *ListSmsInboundOptions) (*SmsInboundRoot, *Response, error) { 74 | req, err := s.client.newRequest(http.MethodGet, smsInboundPath, options) 75 | if err != nil { 76 | return nil, nil, err 77 | } 78 | 79 | root := new(SmsInboundRoot) 80 | res, err := s.client.do(ctx, req, root) 81 | if err != nil { 82 | return nil, res, err 83 | } 84 | 85 | return root, res, nil 86 | } 87 | 88 | func (s *smsInboundService) Get(ctx context.Context, smsInboundId string) (*SingleSmsInboundRoot, *Response, error) { 89 | path := fmt.Sprintf("%s/%s", smsInboundPath, smsInboundId) 90 | 91 | req, err := s.client.newRequest(http.MethodGet, path, nil) 92 | if err != nil { 93 | return nil, nil, err 94 | } 95 | 96 | root := new(SingleSmsInboundRoot) 97 | res, err := s.client.do(ctx, req, root) 98 | if err != nil { 99 | return nil, res, err 100 | } 101 | 102 | return root, res, nil 103 | } 104 | 105 | func (s *smsInboundService) Create(ctx context.Context, options *CreateSmsInboundOptions) (*SingleSmsInboundRoot, *Response, error) { 106 | req, err := s.client.newRequest(http.MethodPost, smsInboundPath, options) 107 | if err != nil { 108 | return nil, nil, err 109 | } 110 | 111 | root := new(SingleSmsInboundRoot) 112 | res, err := s.client.do(ctx, req, root) 113 | if err != nil { 114 | return nil, res, err 115 | } 116 | 117 | return root, res, nil 118 | } 119 | 120 | func (s *smsInboundService) Update(ctx context.Context, options *UpdateSmsInboundOptions) (*SingleSmsInboundRoot, *Response, error) { 121 | path := fmt.Sprintf("%s/%s", smsInboundPath, options.Id) 122 | 123 | req, err := s.client.newRequest(http.MethodPut, path, options) 124 | if err != nil { 125 | return nil, nil, err 126 | } 127 | 128 | root := new(SingleSmsInboundRoot) 129 | res, err := s.client.do(ctx, req, root) 130 | if err != nil { 131 | return nil, res, err 132 | } 133 | 134 | return root, res, nil 135 | } 136 | 137 | func (s *smsInboundService) Delete(ctx context.Context, smsInboundId string) (*Response, error) { 138 | path := fmt.Sprintf("%s/%s", smsInboundPath, smsInboundId) 139 | 140 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 141 | if err != nil { 142 | return nil, err 143 | } 144 | 145 | return s.client.do(ctx, req, nil) 146 | } 147 | -------------------------------------------------------------------------------- /sms_messages.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | ) 8 | 9 | const smsMessagesPath = "/sms-messages" 10 | 11 | type SmsMessageService interface { 12 | List(ctx context.Context, options *ListSmsMessageOptions) (*SmsListMessagesRoot, *Response, error) 13 | Get(ctx context.Context, smsMessageID string) (*SmsSingleMessagesRoot, *Response, error) 14 | } 15 | 16 | type smsMessageService struct { 17 | *service 18 | } 19 | 20 | // SmsListMessagesRoot - format of activity response 21 | type SmsListMessagesRoot struct { 22 | Data []SmsMessageData `json:"data"` 23 | Links Links `json:"links"` 24 | Meta Meta `json:"meta"` 25 | } 26 | 27 | // SmsSingleMessagesRoot - format of activity response 28 | type SmsSingleMessagesRoot SmsMessageRoot 29 | 30 | // ListSmsMessageOptions - modifies the behavior of SmsMessagesService.List method 31 | type ListSmsMessageOptions struct { 32 | Page int `url:"page,omitempty"` 33 | Limit int `url:"limit,omitempty"` 34 | } 35 | 36 | func (s *smsMessageService) List(ctx context.Context, options *ListSmsMessageOptions) (*SmsListMessagesRoot, *Response, error) { 37 | req, err := s.client.newRequest(http.MethodGet, smsMessagesPath, options) 38 | if err != nil { 39 | return nil, nil, err 40 | } 41 | 42 | root := new(SmsListMessagesRoot) 43 | res, err := s.client.do(ctx, req, root) 44 | if err != nil { 45 | return nil, res, err 46 | } 47 | 48 | return root, res, nil 49 | } 50 | 51 | func (s *smsMessageService) Get(ctx context.Context, smsMessageID string) (*SmsSingleMessagesRoot, *Response, error) { 52 | path := fmt.Sprintf("%s/%s", smsMessagesPath, smsMessageID) 53 | 54 | req, err := s.client.newRequest(http.MethodGet, path, nil) 55 | if err != nil { 56 | return nil, nil, err 57 | } 58 | 59 | root := new(SmsSingleMessagesRoot) 60 | res, err := s.client.do(ctx, req, root) 61 | if err != nil { 62 | return nil, res, err 63 | } 64 | 65 | return root, res, nil 66 | } 67 | -------------------------------------------------------------------------------- /sms_numbers.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const smsNumbersPath = "/sms-numbers" 11 | 12 | type SmsNumberService interface { 13 | List(ctx context.Context, options *SmsNumberOptions) (*SmsNumberRoot, *Response, error) 14 | Get(ctx context.Context, numberID string) (*SingleSmsNumberRoot, *Response, error) 15 | Update(ctx context.Context, options *SmsNumberSettingOptions) (*SingleSmsNumberRoot, *Response, error) 16 | Delete(ctx context.Context, numberID string) (*Response, error) 17 | } 18 | 19 | type smsNumberService struct { 20 | *service 21 | } 22 | 23 | // SmsNumberRoot - format of activity response 24 | type SmsNumberRoot struct { 25 | Data []Number `json:"data"` 26 | Links Links `json:"links"` 27 | Meta Meta `json:"meta"` 28 | } 29 | 30 | // SingleSmsNumberRoot - format of activity response 31 | type SingleSmsNumberRoot struct { 32 | Data Number `json:"data"` 33 | } 34 | 35 | type Number struct { 36 | Id string `json:"id"` 37 | TelephoneNumber string `json:"telephone_number"` 38 | Paused bool `json:"paused"` 39 | CreatedAt time.Time `json:"created_at"` 40 | } 41 | 42 | // SmsNumberSettingOptions - modifies the behavior of SmsNumbersService.Update method 43 | type SmsNumberSettingOptions struct { 44 | Id string `json:"-"` 45 | Paused *bool `json:"paused,omitempty"` 46 | } 47 | 48 | // SmsNumberOptions - modifies the behavior of SmsNumbersService.List method 49 | type SmsNumberOptions struct { 50 | Paused bool `url:"paused,omitempty"` 51 | Page int `url:"page,omitempty"` 52 | Limit int `url:"limit,omitempty"` 53 | } 54 | 55 | func (s *smsNumberService) List(ctx context.Context, options *SmsNumberOptions) (*SmsNumberRoot, *Response, error) { 56 | req, err := s.client.newRequest(http.MethodGet, smsNumbersPath, options) 57 | if err != nil { 58 | return nil, nil, err 59 | } 60 | 61 | root := new(SmsNumberRoot) 62 | res, err := s.client.do(ctx, req, root) 63 | if err != nil { 64 | return nil, res, err 65 | } 66 | 67 | return root, res, nil 68 | } 69 | 70 | func (s *smsNumberService) Get(ctx context.Context, numberID string) (*SingleSmsNumberRoot, *Response, error) { 71 | path := fmt.Sprintf("%s/%s", smsNumbersPath, numberID) 72 | 73 | req, err := s.client.newRequest(http.MethodGet, path, nil) 74 | if err != nil { 75 | return nil, nil, err 76 | } 77 | 78 | root := new(SingleSmsNumberRoot) 79 | res, err := s.client.do(ctx, req, root) 80 | if err != nil { 81 | return nil, res, err 82 | } 83 | 84 | return root, res, nil 85 | } 86 | 87 | func (s *smsNumberService) Update(ctx context.Context, options *SmsNumberSettingOptions) (*SingleSmsNumberRoot, *Response, error) { 88 | path := fmt.Sprintf("%s/%s", smsNumbersPath, options.Id) 89 | 90 | req, err := s.client.newRequest(http.MethodPut, path, options) 91 | if err != nil { 92 | return nil, nil, err 93 | } 94 | 95 | root := new(SingleSmsNumberRoot) 96 | res, err := s.client.do(ctx, req, root) 97 | if err != nil { 98 | return nil, res, err 99 | } 100 | 101 | return root, res, nil 102 | } 103 | 104 | func (s *smsNumberService) Delete(ctx context.Context, numberID string) (*Response, error) { 105 | path := fmt.Sprintf("%s/%s", smsNumbersPath, numberID) 106 | 107 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 108 | if err != nil { 109 | return nil, err 110 | } 111 | 112 | return s.client.do(ctx, req, nil) 113 | } 114 | -------------------------------------------------------------------------------- /sms_recipients.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const smsRecipientPath = "/sms-recipients" 11 | 12 | type SmsRecipientService interface { 13 | List(ctx context.Context, options *SmsRecipientOptions) (*SmsRecipientRoot, *Response, error) 14 | Get(ctx context.Context, smsRecipientId string) (*SingleSmsRecipientRoot, *Response, error) 15 | Update(ctx context.Context, options *SmsRecipientSettingOptions) (*SingleSmsRecipientUpdateRoot, *Response, error) 16 | } 17 | 18 | type smsRecipientService struct { 19 | *service 20 | } 21 | 22 | // SmsRecipientRoot - format of activity response 23 | type SmsRecipientRoot struct { 24 | Data []SmsRecipient `json:"data"` 25 | Links Links `json:"links"` 26 | Meta Meta `json:"meta"` 27 | } 28 | 29 | // singleSmsNumberRoot - format of activity response 30 | type SingleSmsRecipientRoot struct { 31 | Data SmsRecipientData `json:"data"` 32 | } 33 | 34 | // SingleSmsRecipientUpdateRoot - format of activity response 35 | type SingleSmsRecipientUpdateRoot struct { 36 | Data SmsRecipientDataUpdate `json:"data"` 37 | } 38 | 39 | type SmsRecipient struct { 40 | Id string `json:"id"` 41 | Number string `json:"number"` 42 | Status string `json:"status"` 43 | CreatedAt time.Time `json:"created_at"` 44 | } 45 | 46 | type SmsRecipientData struct { 47 | Id string `json:"id"` 48 | Number string `json:"number"` 49 | Status string `json:"status"` 50 | CreatedAt time.Time `json:"created_at"` 51 | Sms []SmsMessage 52 | } 53 | 54 | type SmsRecipientDataUpdate struct { 55 | Id string `json:"id"` 56 | Number string `json:"number"` 57 | Status string `json:"status"` 58 | CreatedAt time.Time `json:"created_at"` 59 | } 60 | 61 | // SmsRecipientSettingOptions - modifies the behavior of SmsNumbersService.Update method 62 | type SmsRecipientSettingOptions struct { 63 | Id string `json:"-"` 64 | Status string `json:"status,omitempty"` 65 | } 66 | 67 | // SmsRecipientOptions - modifies the behavior of SmsNumbersService.List method 68 | type SmsRecipientOptions struct { 69 | Status bool `url:"status,omitempty"` 70 | SmsNumberId string `url:"sms_number_id,omitempty"` 71 | Page int `url:"page,omitempty"` 72 | Limit int `url:"limit,omitempty"` 73 | } 74 | 75 | func (s *smsRecipientService) List(ctx context.Context, options *SmsRecipientOptions) (*SmsRecipientRoot, *Response, error) { 76 | req, err := s.client.newRequest(http.MethodGet, smsRecipientPath, options) 77 | if err != nil { 78 | return nil, nil, err 79 | } 80 | 81 | root := new(SmsRecipientRoot) 82 | res, err := s.client.do(ctx, req, root) 83 | if err != nil { 84 | return nil, res, err 85 | } 86 | 87 | return root, res, nil 88 | } 89 | 90 | func (s *smsRecipientService) Get(ctx context.Context, smsRecipientId string) (*SingleSmsRecipientRoot, *Response, error) { 91 | path := fmt.Sprintf("%s/%s", smsRecipientPath, smsRecipientId) 92 | 93 | req, err := s.client.newRequest(http.MethodGet, path, nil) 94 | if err != nil { 95 | return nil, nil, err 96 | } 97 | 98 | root := new(SingleSmsRecipientRoot) 99 | res, err := s.client.do(ctx, req, root) 100 | if err != nil { 101 | return nil, res, err 102 | } 103 | 104 | return root, res, nil 105 | } 106 | 107 | func (s *smsRecipientService) Update(ctx context.Context, options *SmsRecipientSettingOptions) (*SingleSmsRecipientUpdateRoot, *Response, error) { 108 | path := fmt.Sprintf("%s/%s", smsRecipientPath, options.Id) 109 | 110 | req, err := s.client.newRequest(http.MethodPut, path, options) 111 | if err != nil { 112 | return nil, nil, err 113 | } 114 | 115 | root := new(SingleSmsRecipientUpdateRoot) 116 | res, err := s.client.do(ctx, req, root) 117 | if err != nil { 118 | return nil, res, err 119 | } 120 | 121 | return root, res, nil 122 | } 123 | -------------------------------------------------------------------------------- /sms_webhooks.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const smsWebhookPath = "/sms-webhooks" 11 | 12 | type SmsWebhookService interface { 13 | List(ctx context.Context, options *ListSmsWebhookOptions) (*SmsWebhookRoot, *Response, error) 14 | Get(ctx context.Context, smsWebhookId string) (*SingleSmsWebhookRoot, *Response, error) 15 | Create(ctx context.Context, options *CreateSmsWebhookOptions) (*SingleSmsWebhookRoot, *Response, error) 16 | Update(ctx context.Context, options *UpdateSmsWebhookOptions) (*SingleSmsWebhookRoot, *Response, error) 17 | Delete(ctx context.Context, smsWebhookId string) (*Response, error) 18 | } 19 | 20 | type smsWebhookService struct { 21 | *service 22 | } 23 | 24 | // SmsWebhookRoot - format of activity response 25 | type SmsWebhookRoot struct { 26 | Data []SmsWebhook `json:"data"` 27 | Links Links `json:"links"` 28 | Meta Meta `json:"meta"` 29 | } 30 | 31 | // singleSmsNumberRoot - format of activity response 32 | type SingleSmsWebhookRoot struct { 33 | Data SmsWebhook `json:"data"` 34 | } 35 | 36 | type SmsWebhook struct { 37 | Id string `json:"id"` 38 | Url string `json:"url"` 39 | Events []string `json:"events"` 40 | Name string `json:"name"` 41 | Enabled bool `json:"enabled"` 42 | CreatedAt time.Time `json:"created_at"` 43 | UpdatedAt time.Time `json:"updated_at"` 44 | SmsNumber Number `json:"sms_number"` 45 | } 46 | 47 | // CreateSmsWebhookOptions - modifies the behavior of *WebhookService.Create Method 48 | type CreateSmsWebhookOptions struct { 49 | SmsNumberId string `json:"sms_number_id"` 50 | Name string `json:"name"` 51 | URL string `json:"url"` 52 | Enabled *bool `json:"enabled,omitempty"` 53 | Events []string `json:"events"` 54 | } 55 | 56 | // UpdateSmsWebhookOptions - modifies the behavior of SmsNumbersService.Update method 57 | type UpdateSmsWebhookOptions struct { 58 | Id string `json:"-"` 59 | URL string `json:"url,omitempty"` 60 | Name string `json:"name,omitempty"` 61 | Events []string `json:"events,omitempty"` 62 | Status string `json:"status,omitempty"` 63 | Enabled *bool `json:"enabled,omitempty"` 64 | } 65 | 66 | // ListSmsWebhookOptions - modifies the behavior of SmsNumbersService.List method 67 | type ListSmsWebhookOptions struct { 68 | SmsNumberId string `url:"sms_number_id,omitempty"` 69 | Page int `url:"page,omitempty"` 70 | Limit int `url:"limit,omitempty"` 71 | } 72 | 73 | func (s *smsWebhookService) List(ctx context.Context, options *ListSmsWebhookOptions) (*SmsWebhookRoot, *Response, error) { 74 | req, err := s.client.newRequest(http.MethodGet, smsWebhookPath, options) 75 | if err != nil { 76 | return nil, nil, err 77 | } 78 | 79 | root := new(SmsWebhookRoot) 80 | res, err := s.client.do(ctx, req, root) 81 | if err != nil { 82 | return nil, res, err 83 | } 84 | 85 | return root, res, nil 86 | } 87 | 88 | func (s *smsWebhookService) Get(ctx context.Context, smsWebhookId string) (*SingleSmsWebhookRoot, *Response, error) { 89 | path := fmt.Sprintf("%s/%s", smsWebhookPath, smsWebhookId) 90 | 91 | req, err := s.client.newRequest(http.MethodGet, path, nil) 92 | if err != nil { 93 | return nil, nil, err 94 | } 95 | 96 | root := new(SingleSmsWebhookRoot) 97 | res, err := s.client.do(ctx, req, root) 98 | if err != nil { 99 | return nil, res, err 100 | } 101 | 102 | return root, res, nil 103 | } 104 | 105 | func (s *smsWebhookService) Create(ctx context.Context, options *CreateSmsWebhookOptions) (*SingleSmsWebhookRoot, *Response, error) { 106 | req, err := s.client.newRequest(http.MethodPost, smsWebhookPath, options) 107 | if err != nil { 108 | return nil, nil, err 109 | } 110 | 111 | root := new(SingleSmsWebhookRoot) 112 | res, err := s.client.do(ctx, req, root) 113 | if err != nil { 114 | return nil, res, err 115 | } 116 | 117 | return root, res, nil 118 | } 119 | 120 | func (s *smsWebhookService) Update(ctx context.Context, options *UpdateSmsWebhookOptions) (*SingleSmsWebhookRoot, *Response, error) { 121 | path := fmt.Sprintf("%s/%s", smsWebhookPath, options.Id) 122 | 123 | req, err := s.client.newRequest(http.MethodPut, path, options) 124 | if err != nil { 125 | return nil, nil, err 126 | } 127 | 128 | root := new(SingleSmsWebhookRoot) 129 | res, err := s.client.do(ctx, req, root) 130 | if err != nil { 131 | return nil, res, err 132 | } 133 | 134 | return root, res, nil 135 | } 136 | 137 | func (s *smsWebhookService) Delete(ctx context.Context, smsWebhookId string) (*Response, error) { 138 | path := fmt.Sprintf("%s/%s", smsWebhookPath, smsWebhookId) 139 | 140 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 141 | if err != nil { 142 | return nil, err 143 | } 144 | 145 | return s.client.do(ctx, req, nil) 146 | } 147 | -------------------------------------------------------------------------------- /suppressions.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const ( 11 | suppressionBasePath = "/suppressions" 12 | 13 | BlockList string = "blocklist" 14 | HardBounces string = "hard-bounces" 15 | SpamComplaints string = "spam-complaints" 16 | Unsubscribes string = "unsubscribes" 17 | ) 18 | 19 | type SuppressionService interface { 20 | ListBlockList(ctx context.Context, options *SuppressionOptions) (*SuppressionBlockListRoot, *Response, error) 21 | ListHardBounces(ctx context.Context, options *SuppressionOptions) (*SuppressionHardBouncesRoot, *Response, error) 22 | ListSpamComplaints(ctx context.Context, options *SuppressionOptions) (*SuppressionSpamComplaintsRoot, *Response, error) 23 | ListUnsubscribes(ctx context.Context, options *SuppressionOptions) (*SuppressionUnsubscribesRoot, *Response, error) 24 | CreateBlock(ctx context.Context, options *CreateSuppressionBlockOptions) (*SuppressionBlockResponse, *Response, error) 25 | CreateHardBounce(ctx context.Context, options *CreateSuppressionOptions) (*SuppressionHardBouncesRoot, *Response, error) 26 | CreateSpamComplaint(ctx context.Context, options *CreateSuppressionOptions) (*SuppressionSpamComplaintsRoot, *Response, error) 27 | CreateUnsubscribe(ctx context.Context, options *CreateSuppressionOptions) (*SuppressionUnsubscribesRoot, *Response, error) 28 | Delete(ctx context.Context, options *DeleteSuppressionOptions, suppressionType string) (*Response, error) 29 | DeleteAll(ctx context.Context, domainID string, suppressionType string) (*Response, error) 30 | } 31 | 32 | type suppressionService struct { 33 | *service 34 | } 35 | 36 | // SuppressionBlockListRoot - recipients response 37 | type SuppressionBlockListRoot struct { 38 | Data []SuppressionBlockListData `json:"data"` 39 | Links `json:"links"` 40 | Meta `json:"meta"` 41 | } 42 | 43 | type SuppressionBlockListData struct { 44 | ID string `json:"id"` 45 | Type string `json:"type"` 46 | Pattern string `json:"pattern"` 47 | Domain Domain `json:"domain"` 48 | CreatedAt time.Time `json:"created_at"` 49 | UpdatedAt time.Time `json:"updated_at"` 50 | } 51 | 52 | // SuppressionHardBouncesRoot - recipients response 53 | type SuppressionHardBouncesRoot struct { 54 | Data []SuppressionHardBouncesData `json:"data"` 55 | Links `json:"links"` 56 | Meta `json:"meta"` 57 | } 58 | 59 | type SuppressionHardBouncesData struct { 60 | ID string `json:"id"` 61 | Reason string `json:"reason"` 62 | CreatedAt time.Time `json:"created_at"` 63 | Recipient SuppressionRecipient `json:"recipient"` 64 | } 65 | 66 | // SuppressionSpamComplaintsRoot - recipients response 67 | type SuppressionSpamComplaintsRoot struct { 68 | Data []SuppressionSpamComplaintsData `json:"data"` 69 | Links `json:"links"` 70 | Meta `json:"meta"` 71 | } 72 | 73 | type SuppressionSpamComplaintsData struct { 74 | ID string `json:"id"` 75 | Recipient SuppressionRecipient `json:"recipient"` 76 | CreatedAt time.Time `json:"created_at"` 77 | } 78 | 79 | // SuppressionUnsubscribesRoot - recipients response 80 | type SuppressionUnsubscribesRoot struct { 81 | Data []SuppressionUnsubscribesData `json:"data"` 82 | Links `json:"links"` 83 | Meta `json:"meta"` 84 | } 85 | 86 | type SuppressionUnsubscribesData struct { 87 | ID string `json:"id"` 88 | Reason string `json:"reason"` 89 | ReadableReason string `json:"readable_reason"` 90 | Recipient SuppressionRecipient `json:"recipient"` 91 | CreatedAt time.Time `json:"created_at"` 92 | } 93 | 94 | type SuppressionRecipient struct { 95 | ID string `json:"id"` 96 | Email string `json:"email"` 97 | CreatedAt time.Time `json:"created_at"` 98 | UpdatedAt time.Time `json:"updated_at"` 99 | DeletedAt string `json:"deleted_at"` 100 | Domain Domain `json:"domain"` 101 | } 102 | 103 | type SuppressionBlockResponse struct { 104 | Data []SuppressionBlockData `json:"data"` 105 | } 106 | 107 | type SuppressionBlockData struct { 108 | ID string `json:"id"` 109 | Type string `json:"type"` 110 | Pattern string `json:"pattern"` 111 | CreatedAt time.Time `json:"created_at"` 112 | UpdatedAt time.Time `json:"updated_at"` 113 | } 114 | 115 | type CreateSuppressionBlockOptions struct { 116 | DomainID string `json:"domain_id"` 117 | Recipients []string `json:"recipients,omitempty"` 118 | Patterns []string `json:"patterns,omitempty"` 119 | } 120 | 121 | type CreateSuppressionOptions struct { 122 | DomainID string `json:"domain_id"` 123 | Recipients []string `json:"recipients"` 124 | } 125 | 126 | // SuppressionOptions - modifies the behavior of SuppressionService.List methods 127 | type SuppressionOptions struct { 128 | DomainID string `url:"domain_id,omitempty"` 129 | Page int `url:"page,omitempty"` 130 | Limit int `url:"limit,omitempty"` 131 | } 132 | 133 | type DeleteSuppressionOptions struct { 134 | DomainID string `json:"domain_id"` 135 | Ids []string `json:"ids"` 136 | } 137 | 138 | type DeleteAll struct { 139 | DomainID string `json:"domain_id"` 140 | All bool `json:"all"` 141 | } 142 | 143 | func (s *suppressionService) ListBlockList(ctx context.Context, options *SuppressionOptions) (*SuppressionBlockListRoot, *Response, error) { 144 | path := fmt.Sprintf("%s/%s", suppressionBasePath, BlockList) 145 | 146 | req, err := s.client.newRequest(http.MethodGet, path, options) 147 | if err != nil { 148 | return nil, nil, err 149 | } 150 | 151 | root := new(SuppressionBlockListRoot) 152 | 153 | res, err := s.client.do(ctx, req, root) 154 | if err != nil { 155 | return nil, res, err 156 | } 157 | 158 | return root, res, nil 159 | } 160 | 161 | func (s *suppressionService) ListHardBounces(ctx context.Context, options *SuppressionOptions) (*SuppressionHardBouncesRoot, *Response, error) { 162 | path := fmt.Sprintf("%s/%s", suppressionBasePath, HardBounces) 163 | 164 | req, err := s.client.newRequest(http.MethodGet, path, options) 165 | if err != nil { 166 | return nil, nil, err 167 | } 168 | 169 | root := new(SuppressionHardBouncesRoot) 170 | 171 | res, err := s.client.do(ctx, req, root) 172 | if err != nil { 173 | return nil, res, err 174 | } 175 | 176 | return root, res, nil 177 | } 178 | 179 | func (s *suppressionService) ListSpamComplaints(ctx context.Context, options *SuppressionOptions) (*SuppressionSpamComplaintsRoot, *Response, error) { 180 | path := fmt.Sprintf("%s/%s", suppressionBasePath, SpamComplaints) 181 | 182 | req, err := s.client.newRequest(http.MethodGet, path, options) 183 | if err != nil { 184 | return nil, nil, err 185 | } 186 | 187 | root := new(SuppressionSpamComplaintsRoot) 188 | 189 | res, err := s.client.do(ctx, req, root) 190 | if err != nil { 191 | return nil, res, err 192 | } 193 | 194 | return root, res, nil 195 | } 196 | 197 | func (s *suppressionService) ListUnsubscribes(ctx context.Context, options *SuppressionOptions) (*SuppressionUnsubscribesRoot, *Response, error) { 198 | path := fmt.Sprintf("%s/%s", suppressionBasePath, Unsubscribes) 199 | 200 | req, err := s.client.newRequest(http.MethodGet, path, options) 201 | if err != nil { 202 | return nil, nil, err 203 | } 204 | 205 | root := new(SuppressionUnsubscribesRoot) 206 | 207 | res, err := s.client.do(ctx, req, root) 208 | if err != nil { 209 | return nil, res, err 210 | } 211 | 212 | return root, res, nil 213 | } 214 | 215 | func (s *suppressionService) CreateBlock(ctx context.Context, options *CreateSuppressionBlockOptions) (*SuppressionBlockResponse, *Response, error) { 216 | path := fmt.Sprintf("%s/%s", suppressionBasePath, BlockList) 217 | req, err := s.client.newRequest(http.MethodPost, path, options) 218 | if err != nil { 219 | return nil, nil, err 220 | } 221 | 222 | root := new(SuppressionBlockResponse) 223 | res, err := s.client.do(ctx, req, root) 224 | if err != nil { 225 | return nil, res, err 226 | } 227 | 228 | return root, res, nil 229 | } 230 | 231 | func (s *suppressionService) CreateHardBounce(ctx context.Context, options *CreateSuppressionOptions) (*SuppressionHardBouncesRoot, *Response, error) { 232 | path := fmt.Sprintf("%s/%s", suppressionBasePath, HardBounces) 233 | req, err := s.client.newRequest(http.MethodPost, path, options) 234 | if err != nil { 235 | return nil, nil, err 236 | } 237 | 238 | root := new(SuppressionHardBouncesRoot) 239 | res, err := s.client.do(ctx, req, root) 240 | if err != nil { 241 | return nil, res, err 242 | } 243 | 244 | return root, res, nil 245 | } 246 | 247 | func (s *suppressionService) CreateSpamComplaint(ctx context.Context, options *CreateSuppressionOptions) (*SuppressionSpamComplaintsRoot, *Response, error) { 248 | path := fmt.Sprintf("%s/%s", suppressionBasePath, SpamComplaints) 249 | req, err := s.client.newRequest(http.MethodPost, path, options) 250 | if err != nil { 251 | return nil, nil, err 252 | } 253 | 254 | root := new(SuppressionSpamComplaintsRoot) 255 | res, err := s.client.do(ctx, req, root) 256 | if err != nil { 257 | return nil, res, err 258 | } 259 | 260 | return root, res, nil 261 | } 262 | 263 | func (s *suppressionService) CreateUnsubscribe(ctx context.Context, options *CreateSuppressionOptions) (*SuppressionUnsubscribesRoot, *Response, error) { 264 | path := fmt.Sprintf("%s/%s", suppressionBasePath, Unsubscribes) 265 | req, err := s.client.newRequest(http.MethodPost, path, options) 266 | if err != nil { 267 | return nil, nil, err 268 | } 269 | 270 | root := new(SuppressionUnsubscribesRoot) 271 | res, err := s.client.do(ctx, req, root) 272 | if err != nil { 273 | return nil, res, err 274 | } 275 | 276 | return root, res, nil 277 | } 278 | 279 | func (s *suppressionService) Delete(ctx context.Context, options *DeleteSuppressionOptions, suppressionType string) (*Response, error) { 280 | path := fmt.Sprintf("%s/%s", suppressionBasePath, suppressionType) 281 | 282 | req, err := s.client.newRequest(http.MethodDelete, path, options) 283 | if err != nil { 284 | return nil, err 285 | } 286 | 287 | return s.client.do(ctx, req, nil) 288 | 289 | } 290 | 291 | func (s *suppressionService) DeleteAll(ctx context.Context, domainID string, suppressionType string) (*Response, error) { 292 | path := fmt.Sprintf("%s/%s", suppressionBasePath, suppressionType) 293 | 294 | options := DeleteAll{All: true, DomainID: domainID} 295 | 296 | req, err := s.client.newRequest(http.MethodDelete, path, options) 297 | if err != nil { 298 | return nil, err 299 | } 300 | 301 | return s.client.do(ctx, req, nil) 302 | } 303 | -------------------------------------------------------------------------------- /templates.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const templateBasePath = "/templates" 11 | 12 | type TemplateService interface { 13 | List(ctx context.Context, options *ListTemplateOptions) (*TemplateRoot, *Response, error) 14 | Get(ctx context.Context, templateID string) (*SingleTemplateRoot, *Response, error) 15 | Delete(ctx context.Context, templateID string) (*Response, error) 16 | } 17 | 18 | type templateService struct { 19 | *service 20 | } 21 | 22 | // TemplateRoot format of template response 23 | type TemplateRoot struct { 24 | Data []Template `json:"data"` 25 | Links Links `json:"links"` 26 | Meta Meta `json:"meta"` 27 | } 28 | 29 | type Template struct { 30 | ID string `json:"id"` 31 | Name string `json:"name"` 32 | Type string `json:"type"` 33 | ImagePath string `json:"image_path"` 34 | CreatedAt string `json:"created_at"` 35 | } 36 | 37 | type SingleTemplateRoot struct { 38 | Data SingleTemplate `json:"data"` 39 | } 40 | 41 | type SingleTemplate struct { 42 | ID string `json:"id"` 43 | Name string `json:"name"` 44 | Type string `json:"type"` 45 | ImagePath string `json:"image_path"` 46 | CreatedAt time.Time `json:"created_at"` 47 | Category interface{} `json:"category"` 48 | Domain Domain `json:"domain"` 49 | TemplateStats TemplateStats `json:"template_stats"` 50 | } 51 | 52 | type TemplateStats struct { 53 | Total int `json:"total"` 54 | Queued int `json:"queued"` 55 | Sent int `json:"sent"` 56 | Rejected int `json:"rejected"` 57 | Delivered int `json:"delivered"` 58 | LastEmailSentAt time.Time `json:"last_email_sent_at"` 59 | } 60 | 61 | // ListTemplateOptions - modifies the behavior of TemplateService.List Method 62 | type ListTemplateOptions struct { 63 | DomainID string `url:"domain_id,omitempty"` 64 | Page int `url:"page,omitempty"` 65 | Limit int `url:"limit,omitempty"` 66 | } 67 | 68 | func (s *templateService) List(ctx context.Context, options *ListTemplateOptions) (*TemplateRoot, *Response, error) { 69 | req, err := s.client.newRequest(http.MethodGet, templateBasePath, options) 70 | if err != nil { 71 | return nil, nil, err 72 | } 73 | 74 | root := new(TemplateRoot) 75 | res, err := s.client.do(ctx, req, root) 76 | if err != nil { 77 | return nil, res, err 78 | } 79 | 80 | return root, res, nil 81 | } 82 | 83 | func (s *templateService) Get(ctx context.Context, templateID string) (*SingleTemplateRoot, *Response, error) { 84 | path := fmt.Sprintf("%s/%s", templateBasePath, templateID) 85 | 86 | req, err := s.client.newRequest(http.MethodGet, path, nil) 87 | if err != nil { 88 | return nil, nil, err 89 | } 90 | 91 | root := new(SingleTemplateRoot) 92 | res, err := s.client.do(ctx, req, root) 93 | if err != nil { 94 | return nil, res, err 95 | } 96 | 97 | return root, res, nil 98 | } 99 | 100 | func (s *templateService) Delete(ctx context.Context, templateID string) (*Response, error) { 101 | path := fmt.Sprintf("%s/%s", templateBasePath, templateID) 102 | 103 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 104 | if err != nil { 105 | return nil, err 106 | } 107 | 108 | return s.client.do(ctx, req, nil) 109 | } 110 | -------------------------------------------------------------------------------- /tokens.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | ) 8 | 9 | const tokenBasePath = "/token" 10 | 11 | type TokenService interface { 12 | Create(ctx context.Context, options *CreateTokenOptions) (*TokenRoot, *Response, error) 13 | Update(ctx context.Context, options *UpdateTokenOptions) (*TokenRoot, *Response, error) 14 | Delete(ctx context.Context, tokenID string) (*Response, error) 15 | } 16 | 17 | type tokenService struct { 18 | *service 19 | } 20 | 21 | // TokenRoot - format of token response 22 | type TokenRoot struct { 23 | Data Token `json:"data"` 24 | } 25 | 26 | type Token struct { 27 | ID string `json:"id,omitempty"` 28 | AccessToken string `json:"accessToken,omitempty"` 29 | Name string `json:"name,omitempty"` 30 | Status string `json:"status,omitempty"` 31 | CreatedAt string `json:"created_at,omitempty"` 32 | } 33 | 34 | // CreateTokenOptions - modifies the behavior of TokenService.Create Method 35 | type CreateTokenOptions struct { 36 | Name string `json:"name"` 37 | DomainID string `json:"domain_id"` 38 | Scopes []string `json:"scopes"` 39 | } 40 | 41 | // UpdateTokenOptions - modifies the behavior of TokenService.Update Method 42 | type UpdateTokenOptions struct { 43 | TokenID string `json:"-"` 44 | Status string `json:"status"` 45 | } 46 | 47 | func (s *tokenService) Create(ctx context.Context, options *CreateTokenOptions) (*TokenRoot, *Response, error) { 48 | req, err := s.client.newRequest(http.MethodPost, tokenBasePath, options) 49 | if err != nil { 50 | return nil, nil, err 51 | } 52 | 53 | root := new(TokenRoot) 54 | res, err := s.client.do(ctx, req, root) 55 | if err != nil { 56 | return nil, res, err 57 | } 58 | 59 | return root, res, nil 60 | } 61 | 62 | func (s *tokenService) Update(ctx context.Context, options *UpdateTokenOptions) (*TokenRoot, *Response, error) { 63 | path := fmt.Sprintf("%s/%s/settings", tokenBasePath, options.TokenID) 64 | 65 | req, err := s.client.newRequest(http.MethodPut, path, options) 66 | if err != nil { 67 | return nil, nil, err 68 | } 69 | 70 | root := new(TokenRoot) 71 | res, err := s.client.do(ctx, req, root) 72 | if err != nil { 73 | return nil, res, err 74 | } 75 | 76 | return root, res, nil 77 | } 78 | 79 | func (s *tokenService) Delete(ctx context.Context, tokenID string) (*Response, error) { 80 | path := fmt.Sprintf("%s/%s", tokenBasePath, tokenID) 81 | 82 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 83 | if err != nil { 84 | return nil, err 85 | } 86 | 87 | return s.client.do(ctx, req, nil) 88 | } 89 | -------------------------------------------------------------------------------- /webhooks.go: -------------------------------------------------------------------------------- 1 | package mailersend 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | const webhookBasePath = "/webhooks" 11 | 12 | type WebhookService interface { 13 | List(ctx context.Context, options *ListWebhookOptions) (*WebhookRoot, *Response, error) 14 | Get(ctx context.Context, webhookID string) (*SingleWebhookRoot, *Response, error) 15 | Create(ctx context.Context, options *CreateWebhookOptions) (*SingleWebhookRoot, *Response, error) 16 | Update(ctx context.Context, options *UpdateWebhookOptions) (*SingleWebhookRoot, *Response, error) 17 | Delete(ctx context.Context, webhookID string) (*Response, error) 18 | } 19 | 20 | type webhookService struct { 21 | *service 22 | } 23 | 24 | // WebhookRoot - format of webhook response 25 | type WebhookRoot struct { 26 | Data []Webhook `json:"data"` 27 | Links Links `json:"links"` 28 | Meta Meta `json:"meta"` 29 | } 30 | 31 | // SingleWebhookRoot - format of webhook response 32 | type SingleWebhookRoot struct { 33 | Data Webhook `json:"data"` 34 | } 35 | 36 | type Webhook struct { 37 | ID string `json:"id"` 38 | URL string `json:"url"` 39 | Events []string `json:"events"` 40 | Name string `json:"name"` 41 | Enabled bool `json:"enabled"` 42 | Editable bool `json:"editable"` 43 | CreatedAt time.Time `json:"created_at"` 44 | UpdatedAt time.Time `json:"updated_at"` 45 | Domain Domain `json:"domain"` 46 | } 47 | 48 | // ListWebhookOptions - modifies the behavior of *WebhookService.List Method 49 | type ListWebhookOptions struct { 50 | DomainID string `url:"domain_id"` 51 | Limit int `url:"limit,omitempty"` 52 | } 53 | 54 | // CreateWebhookOptions - modifies the behavior of *WebhookService.Create Method 55 | type CreateWebhookOptions struct { 56 | Name string `json:"name"` 57 | DomainID string `json:"domain_id"` 58 | URL string `json:"url"` 59 | Enabled *bool `json:"enabled,omitempty"` 60 | Events []string `json:"events"` 61 | } 62 | 63 | // UpdateWebhookOptions - modifies the behavior of *WebhookService.Update Method 64 | type UpdateWebhookOptions struct { 65 | WebhookID string `json:"-"` 66 | Name string `json:"name,omitempty"` 67 | URL string `json:"url,omitempty"` 68 | Enabled *bool `json:"enabled,omitempty"` 69 | Events []string `json:"events,omitempty"` 70 | } 71 | 72 | func (s *webhookService) List(ctx context.Context, options *ListWebhookOptions) (*WebhookRoot, *Response, error) { 73 | req, err := s.client.newRequest(http.MethodGet, webhookBasePath, options) 74 | if err != nil { 75 | return nil, nil, err 76 | } 77 | 78 | root := new(WebhookRoot) 79 | res, err := s.client.do(ctx, req, root) 80 | if err != nil { 81 | return nil, res, err 82 | } 83 | 84 | return root, res, nil 85 | } 86 | 87 | func (s *webhookService) Get(ctx context.Context, webhookID string) (*SingleWebhookRoot, *Response, error) { 88 | path := fmt.Sprintf("%s/%s", webhookBasePath, webhookID) 89 | 90 | req, err := s.client.newRequest(http.MethodGet, path, nil) 91 | if err != nil { 92 | return nil, nil, err 93 | } 94 | 95 | root := new(SingleWebhookRoot) 96 | res, err := s.client.do(ctx, req, root) 97 | if err != nil { 98 | return nil, res, err 99 | } 100 | 101 | return root, res, nil 102 | } 103 | 104 | func (s *webhookService) Create(ctx context.Context, options *CreateWebhookOptions) (*SingleWebhookRoot, *Response, error) { 105 | req, err := s.client.newRequest(http.MethodPost, webhookBasePath, options) 106 | if err != nil { 107 | return nil, nil, err 108 | } 109 | 110 | root := new(SingleWebhookRoot) 111 | res, err := s.client.do(ctx, req, root) 112 | if err != nil { 113 | return nil, res, err 114 | } 115 | 116 | return root, res, nil 117 | } 118 | 119 | func (s *webhookService) Update(ctx context.Context, options *UpdateWebhookOptions) (*SingleWebhookRoot, *Response, error) { 120 | path := fmt.Sprintf("%s/%s", webhookBasePath, options.WebhookID) 121 | 122 | req, err := s.client.newRequest(http.MethodPut, path, options) 123 | if err != nil { 124 | return nil, nil, err 125 | } 126 | 127 | root := new(SingleWebhookRoot) 128 | res, err := s.client.do(ctx, req, root) 129 | if err != nil { 130 | return nil, res, err 131 | } 132 | 133 | return root, res, nil 134 | } 135 | 136 | func (s *webhookService) Delete(ctx context.Context, webhookID string) (*Response, error) { 137 | path := fmt.Sprintf("%s/%s", webhookBasePath, webhookID) 138 | 139 | req, err := s.client.newRequest(http.MethodDelete, path, nil) 140 | if err != nil { 141 | return nil, err 142 | } 143 | 144 | return s.client.do(ctx, req, nil) 145 | } 146 | --------------------------------------------------------------------------------