diff --git a/CLAUDE.md b/CLAUDE.md index b8d5925..4c4c56a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -148,6 +148,8 @@ Include code samples in this order: 5. Ruby 6. .NET (C#) 7. Java +8. Go (`lang: go`, `label: Go`) +9. Terraform (`lang: hcl`, `label: Terraform`) - HCL, not an API call; see below ### Code Sample Format @@ -175,18 +177,60 @@ x-codeSamples: - **Use official Mailtrap SDKs** for language-specific examples - **If SDK doesn't support a method**, either let GitBook generate the example or add a comment noting SDK limitations +- **For Go and Terraform, omit the entry entirely** when the tool cannot express the operation. A tab that + says "unsupported" is worse than an absent tab, so `inbound.openapi.yml` gets no Go or Terraform samples + at all, and the tracking opt-out operations keep their cURL-only sample. - **Use environment variables** for API keys (e.g., `process.env.MAILTRAP_API_KEY`) - **Use Context7 MCP** to query SDK capabilities when unsure +#### Go samples + +- Full compilable `package main` programs: Go has no top-level-statement form, and a complete program can + be compile-checked, which is the point. +- Read the token from `os.Getenv("MAILTRAP_API_TOKEN")`, the idiom used by every example in + `mailtrap/mailtrap-go`. +- Every method takes a `context.Context` first and returns `(payload, *mailtrap.Response, error)`; discard + the response as `_` and handle errors as `if err != nil { log.Fatal(err) }`. +- Set optional pointer fields with `mailtrap.Ptr(...)`, and prefer the SDK's exported constants + (`mailtrap.WebhookTypeEmailSending`, `mailtrap.SendingStreamTransactional`, ...) over string literals. +- Target the latest **released** SDK version. Verify a sample by extracting it to its own package and + running `gofmt -l`, `go vet` and `go build` against that version - not by reading it. +- `gofmt` indents with tabs. Tabs are legal inside a YAML block scalar's content (only block + *indentation* must be spaces), so a `source: |` block indented with 12 spaces followed by tabs + round-trips correctly. + +#### Terraform samples + +- Use `lang: hcl` with `label: Terraform`. GitBook highlights with Prism, which has an `hcl` component and + no `terraform` one; `lang` resolves through Prism identifiers rather than GitBook's documented linguist + list, as the existing `csharp` and `shell` samples show. The dropdown tab is titled by `label`, so it + reads "Terraform" regardless. +- **Cover only creates and genuine data-source reads.** A `resource` block is the create; its update, + delete and import paths are native Terraform lifecycle and are documented once by the provider, so + those operations get no Terraform sample. A `data` block goes on a read operation only when the + provider has a matching data source. Do not fake a read with a `resource` block plus `terraform import`. +- An HCL block is not an API call: a `resource` block declares desired state and the endpoint fires as a + side effect of a lifecycle command. Every sample therefore opens with a comment naming both the command + and the operation, e.g. `# terraform apply creates the domain: POST /api/domains`. Create samples add a + second comment line linking the provider docs + (`# Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs`), which is + where the lifecycle operations live. +- Each sample is self-contained, including the `terraform { required_providers { ... } }` and + `provider "mailtrap" {}` blocks, because the sample tab is where a reader learns the source string. +- Take attribute names from the provider schema, not from its published examples. Verify with + `terraform fmt -check` plus `terraform validate` against a locally built provider binary under `dev_overrides`. + ### SDK Repositories Reference SDK repos for accurate code examples: - Node.js: `mailtrap/mailtrap-nodejs` -- PHP: `railsware/mailtrap-php` -- Python: `railsware/mailtrap-python` -- Ruby: `railsware/mailtrap-ruby` -- .NET: Future reference -- Java: Future reference +- PHP: `mailtrap/mailtrap-php` +- Python: `mailtrap/mailtrap-python` +- Ruby: `mailtrap/mailtrap-ruby` +- .NET: `mailtrap/mailtrap-dotnet` +- Java: `mailtrap/mailtrap-java` +- Go: `mailtrap/mailtrap-go` +- Terraform provider: `mailtrap/terraform-provider-mailtrap` ## OpenAPI Extensions diff --git a/specs/account-management.openapi.yml b/specs/account-management.openapi.yml index 51237f7..fb01eeb 100644 --- a/specs/account-management.openapi.yml +++ b/specs/account-management.openapi.yml @@ -135,6 +135,58 @@ paths: System.out.println("ID: " + account.getId()); System.out.println("Access Level: " + account.getAccessLevels().get(0)); } + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + accounts, _, err := client.Accounts.List(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, account := range accounts { + fmt.Printf("%d %s (access levels %v)\n", account.ID, account.Name, account.AccessLevels) + } + } + - lang: hcl + label: Terraform + source: | + # looking an account up lists them: GET /api/accounts + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + # With no filters the token must map to exactly one account. + data "mailtrap_account" "current" { + name = "Acme Corp" + } + + output "account_id" { + value = data.mailtrap_account.current.id + } responses: '200': description: 'Returns the list of accounts to which the API token has access. **access_levels** can return 1000 (account owner), 100 (admin), 10 (viewer).' @@ -252,6 +304,38 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.generalApi().accountAccesses().listUserAndInviteAccountAccesses(accountId, ListAccountAccessQueryParams.empty()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Pass nil for no filters. Requires account admin or owner permissions. + accesses, _, err := client.AccountAccesses.List(context.Background(), &mailtrap.AccountAccessListOptions{ + DomainIDs: []int64{1000001}, + }) + if err != nil { + log.Fatal(err) + } + + for _, access := range accesses { + fmt.Printf("%d %s (%s)\n", access.ID, access.Specifier.Email, access.SpecifierType) + } + } parameters: - name: project_ids description: The identifiers of the projects for which to include the results @@ -372,6 +456,32 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); client.generalApi().accountAccesses().removeAccountAccess(accessId, accountId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + if _, err := client.AccountAccesses.Delete(context.Background(), 1000001); err != nil { + log.Fatal(err) + } + + fmt.Println("account access removed") + } responses: '200': description: Returns confirmation of successful deletion and id of the deleted access. @@ -534,6 +644,46 @@ paths: )); client.generalApi().permissions().managePermissions(accessId, accountId, request); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // A resource_type/resource_id pair that already exists is updated, otherwise it + // is created. Set Destroy to remove a permission instead. + _, err = client.Permissions.BulkUpdate(context.Background(), 1000001, []*mailtrap.PermissionUpdate{ + { + ResourceID: "3000001", + ResourceType: mailtrap.ResourceTypeSandbox, + AccessLevel: mailtrap.PermissionLevelAdmin, + }, + { + ResourceID: "3000002", + ResourceType: mailtrap.ResourceTypeSandbox, + Destroy: true, + }, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Println("permissions updated") + } requestBody: content: application/json: @@ -682,6 +832,36 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.generalApi().permissions().getResources(accountId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + resources, _, err := client.Permissions.Resources(context.Background()) + if err != nil { + log.Fatal(err) + } + + // The response is a hierarchy: an account holds projects, which hold sandboxes. + for _, resource := range resources { + fmt.Printf("%s %d %s (%d child resource(s))\n", resource.Type, resource.ID, resource.Name, len(resource.Resources)) + } + } responses: '200': description: |- @@ -799,6 +979,35 @@ paths: long accountId = 1000001L; var tokens = client.generalApi().apiTokens().getAllApiTokens(accountId); System.out.println(tokens); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + tokens, _, err := client.APITokens.List(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, token := range tokens { + fmt.Printf("%d %s (...%s, expires %s)\n", token.ID, token.Name, token.Last4Digits, token.ExpiresAt) + } + } responses: '200': description: List of API tokens @@ -949,6 +1158,76 @@ paths: // The full token value is returned only once — store it securely. var token = client.generalApi().apiTokens().createApiToken(accountId, request); System.out.println(token); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + token, _, err := client.APITokens.Create(context.Background(), &mailtrap.CreateAPITokenRequest{ + Name: "CI deploy token", + Resources: []*mailtrap.APITokenPermission{ + { + ResourceType: mailtrap.ResourceTypeSandbox, + ResourceID: 3000001, + AccessLevel: mailtrap.AccessLevelAdmin, + }, + }, + }) + if err != nil { + log.Fatal(err) + } + + // The full token value is returned only here: store it securely. + fmt.Printf("created token %d: %s\n", token.ID, token.Token) + } + - lang: hcl + label: Terraform + source: | + # terraform apply creates the token: POST /api/api_tokens + # Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + resource "mailtrap_api_token" "ci" { + name = "CI deploy token" + + resources = [ + { + resource_type = "sandbox" + resource_id = 3000001 + access_level = 100 + }, + ] + } + + # token is returned only on create, and is unavailable after an import. + output "api_token" { + value = mailtrap_api_token.ci.token + sensitive = true + } requestBody: required: true content: @@ -1054,6 +1333,34 @@ paths: long apiTokenId = 123L; var token = client.generalApi().apiTokens().getApiToken(accountId, apiTokenId); System.out.println(token); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The full token value is not included; it is returned only on create and reset. + token, _, err := client.APITokens.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s (...%s), created by %s\n", token.Name, token.Last4Digits, token.CreatedBy) + } parameters: - $ref: '#/components/parameters/api_token_id' responses: @@ -1147,6 +1454,32 @@ paths: long accountId = 1000001L; long apiTokenId = 123L; client.generalApi().apiTokens().deleteApiToken(accountId, apiTokenId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + if _, err := client.APITokens.Delete(context.Background(), 1000001); err != nil { + log.Fatal(err) + } + + fmt.Println("API token deleted") + } parameters: - $ref: '#/components/parameters/api_token_id' responses: @@ -1259,6 +1592,36 @@ paths: // The new token value is returned only once — store it securely. var token = client.generalApi().apiTokens().resetApiToken(accountId, apiTokenId); System.out.println(token); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Reset expires the token and issues a replacement with the same permissions. + // Pass nil to send no body and apply the server default expiration. + token, _, err := client.APITokens.Reset(context.Background(), 1000001, nil) + if err != nil { + log.Fatal(err) + } + + // The new token value is returned only here: store it securely. + fmt.Printf("token %d reset: %s\n", token.ID, token.Token) + } parameters: - $ref: '#/components/parameters/api_token_id' requestBody: @@ -1369,6 +1732,38 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.generalApi().billing().getCurrentBillingCycleUsage(accountId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + usage, _, err := client.Billing.Usage(context.Background()) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("cycle %s to %s\n", usage.Billing.CycleStart, usage.Billing.CycleEnd) + // A product is nil when the account has no plan for it. + if usage.Sending != nil { + sent := usage.Sending.Usage.SentMessagesCount + fmt.Printf("sending (%s): %d of %d\n", usage.Sending.Plan.Name, sent.Current, sent.Limit) + } + } responses: '200': description: Returns an object with current billing cycle usage for Sandbox, Email Sending (Email API/SMTP), and Email Marketing if available. @@ -1560,6 +1955,36 @@ paths: long organizationId = 2000002L; var subAccounts = client.organizationsApi().subAccounts().getSubAccounts(organizationId); System.out.println(subAccounts); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN"), mailtrap.WithOrganizationID(2000001)) + if err != nil { + log.Fatal(err) + } + + // The sub-account endpoints target the organization set with WithOrganizationID. + subAccounts, _, err := client.SubAccounts.List(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, subAccount := range subAccounts { + fmt.Printf("%d %s\n", subAccount.ID, subAccount.Name) + } + } responses: '200': description: Returns the list of sub accounts belonging to the organization. @@ -1683,6 +2108,34 @@ paths: var subAccount = client.organizationsApi().subAccounts() .createSubAccount(organizationId, request); System.out.println(subAccount); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN"), mailtrap.WithOrganizationID(2000001)) + if err != nil { + log.Fatal(err) + } + + // The sub-account endpoints target the organization set with WithOrganizationID. + subAccount, _, err := client.SubAccounts.Create(context.Background(), "Acme Corp") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("created sub-account %d (%s)\n", subAccount.ID, subAccount.Name) + } requestBody: required: true content: diff --git a/specs/contacts.openapi.yml b/specs/contacts.openapi.yml index 20e8d8a..dacda6e 100644 --- a/specs/contacts.openapi.yml +++ b/specs/contacts.openapi.yml @@ -217,6 +217,37 @@ paths: var contact = client.contactsApi().contacts() .createContact(accountId, request); System.out.println("Contact created: " + contact.getEmail()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + contact, _, err := client.Contacts.Create(context.Background(), &mailtrap.CreateContactRequest{ + Email: "john.smith@example.com", + Fields: map[string]any{"first_name": "John", "last_name": "Smith"}, + ListIDs: []int64{1, 2}, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("created contact %s (%s)\n", contact.ID, contact.Email) + } requestBody: content: application/json: @@ -399,6 +430,34 @@ paths: System.out.println("Contact: " + contact.getEmail()); System.out.println("Status: " + contact.getStatus()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The identifier is either the contact's UUID or its email address. + contact, _, err := client.Contacts.Get(context.Background(), "john.smith@example.com") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s (%s), lists %v\n", contact.Email, contact.Status, contact.ListIDs) + } responses: '200': description: OK. @@ -511,6 +570,39 @@ paths: var request = new UpdateContactRequest(new UpdateContact("new@example.com", Map.of("first_name", "John"), List.of(), List.of(), false)); var response = client.contactsApi().contacts().updateContact(accountId, "contact_id_or_email", request); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Update is an upsert and reports which action the API took. + result, _, err := client.Contacts.Update(context.Background(), "john.smith@example.com", &mailtrap.UpdateContactRequest{ + Email: "john.smith@example.com", + Fields: map[string]any{"first_name": "John"}, + ListIDsIncluded: []int64{3}, + ListIDsExcluded: []int64{1}, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s contact %s\n", result.Action, result.Contact.ID) + } summary: Update contact tags: - Contacts @@ -614,6 +706,32 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); client.contactsApi().contacts().deleteContact(accountId, "contact_id_or_email"); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + if _, err := client.Contacts.Delete(context.Background(), "john.smith@example.com"); err != nil { + log.Fatal(err) + } + + fmt.Println("contact deleted") + } summary: Delete contact tags: - Contacts @@ -740,6 +858,36 @@ paths: Map params = Map.of("user_id", 101, "is_active", true); var request = new CreateContactEventRequest("UserLogin", params); var response = client.contactsApi().contactEvents().createContactEvent(accountId, "contact_id", request); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + event, _, err := client.ContactEvents.Create(context.Background(), "john.smith@example.com", &mailtrap.CreateContactEventRequest{ + Name: "purchase_completed", + Params: map[string]any{"order_id": "A-1024", "total": 49.99}, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("recorded %q for %s\n", event.Name, event.ContactEmail) + } requestBody: content: application/json: @@ -876,6 +1024,40 @@ paths: var idsFilter = ContactExportFilter.listIds(ContactExportFilterOperator.EQUAL, 1L, 2L); var request = new CreateContactsExportRequest(List.of(idsFilter)); var response = client.contactsApi().contactExports().createContactExport(accountId, request); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Pass nil to export every contact. + export, _, err := client.ContactExports.Create(context.Background(), []*mailtrap.ContactExportFilter{ + { + Name: mailtrap.ContactExportFilterListID, + Operator: mailtrap.ContactExportOperatorEqual, + Value: []int64{1, 2}, + }, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("export %d is %s\n", export.ID, export.Status) + } requestBody: content: application/json: @@ -988,6 +1170,38 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.contactsApi().exports().get(accountId, exportId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Poll until the status is "finished", at which point URL is set. + export, _, err := client.ContactExports.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + if export.Status == mailtrap.ContactExportFinished { + fmt.Printf("download: %s\n", *export.URL) + } else { + fmt.Printf("export %d is %s\n", export.ID, export.Status) + } + } responses: '200': description: OK. @@ -1125,6 +1339,44 @@ paths: var contact = new Contact("user1@example.com", Map.of("first_name", "John"), Collections.emptyList(), Collections.emptyList()); var importContactsRequest = new ImportContactsRequest(List.of(contact)); client.contactsApi().contactImports().importContacts(accountId, importContactsRequest); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + result, _, err := client.ContactImports.Create(context.Background(), []*mailtrap.ImportContact{ + { + Email: "john.smith@example.com", + Fields: map[string]any{"first_name": "John"}, + ListIDsIncluded: []int64{1}, + }, + { + Email: "jane.doe@example.com", + ListIDsIncluded: []int64{1}, + ListIDsExcluded: []int64{2}, + }, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("import %d is %s\n", result.ID, result.Status) + } requestBody: content: application/json: @@ -1236,6 +1488,34 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.contactsApi().contactImports().getContactImport(accountId, importId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The counts are populated once the status is "finished". + result, _, err := client.ContactImports.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s: %d created, %d updated, %d over limit\n", result.Status, result.CreatedContactsCount, result.UpdatedContactsCount, result.ContactsOverLimitCount) + } responses: '200': description: OK. @@ -1348,6 +1628,37 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.contactsApi().contactLists().findAll(accountId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + lists, _, err := client.ContactLists.List(context.Background(), &mailtrap.ContactListListOptions{ + Search: "newsletter", + }) + if err != nil { + log.Fatal(err) + } + + for _, list := range lists { + fmt.Printf("%d %s\n", list.ID, list.Name) + } + } responses: '200': description: OK. @@ -1442,6 +1753,52 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.contactsApi().contactLists().createContactList(accountId, new CreateUpdateContactListRequest("Customers")); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + list, _, err := client.ContactLists.Create(context.Background(), "Monthly newsletter") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("created list %d (%s)\n", list.ID, list.Name) + } + - lang: hcl + label: Terraform + source: | + # terraform apply creates the list: POST /api/contacts/lists + # Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + resource "mailtrap_contact_list" "newsletter" { + name = "Monthly newsletter" + } requestBody: content: application/json: @@ -1539,6 +1896,33 @@ paths: long listId = 1L; var response = client.contactsApi().contactLists().getContactList(accountId, listId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + list, _, err := client.ContactLists.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%d %s\n", list.ID, list.Name) + } responses: '200': description: Returns attributes of the contact list. @@ -1629,6 +2013,33 @@ paths: long listId = 1L; var response = client.contactsApi().contactLists().updateContactList(accountId, listId, new CreateUpdateContactListRequest("Former Customers")); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + list, _, err := client.ContactLists.Update(context.Background(), 1000001, "Weekly newsletter") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("renamed list %d to %s\n", list.ID, list.Name) + } requestBody: content: application/json: @@ -1726,6 +2137,32 @@ paths: long listId = 1L; client.contactsApi().contactLists().deleteContactList(accountId, listId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + if _, err := client.ContactLists.Delete(context.Background(), 1000001); err != nil { + log.Fatal(err) + } + + fmt.Println("contact list deleted") + } responses: '204': description: Contact List successfully deleted @@ -1808,6 +2245,35 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.contactsApi().contactFields().getAllContactFields(accountId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + fields, _, err := client.ContactFields.List(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, field := range fields { + fmt.Printf("%d %s (%s, merge tag %s)\n", field.ID, field.Name, field.DataType, field.MergeTag) + } + } responses: '200': description: OK. @@ -1914,6 +2380,58 @@ paths: var request = new CreateContactFieldRequest("Company", ContactFieldDataType.TEXT, "company"); var response = client.contactsApi().contactFields().createContactField(accountId, request); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + field, _, err := client.ContactFields.Create(context.Background(), &mailtrap.CreateContactFieldRequest{ + Name: "First name", + DataType: mailtrap.ContactFieldTypeText, + MergeTag: "first_name", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("created field %d (%s)\n", field.ID, field.MergeTag) + } + - lang: hcl + label: Terraform + source: | + # terraform apply creates the field: POST /api/contacts/fields + # Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + resource "mailtrap_contact_field" "first_name" { + name = "First name" + data_type = "text" + merge_tag = "first_name" + } requestBody: content: application/json: @@ -2043,6 +2561,33 @@ paths: long fieldId = 2L; var response = client.contactsApi().contactFields().getContactField(accountId, fieldId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + field, _, err := client.ContactFields.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s (%s), merge tag %s\n", field.Name, field.DataType, field.MergeTag) + } responses: '200': description: Returns attributes of the contact field. @@ -2136,6 +2681,37 @@ paths: var request = new UpdateContactFieldRequest("Updated Name", "updated_name"); var response = client.contactsApi().contactFields().updateContactField(accountId, fieldId, request); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The data type is immutable: only the name and merge tag can change. + field, _, err := client.ContactFields.Update(context.Background(), 1000001, &mailtrap.UpdateContactFieldRequest{ + Name: "Given name", + MergeTag: "given_name", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("updated field %d: %s (%s)\n", field.ID, field.Name, field.MergeTag) + } requestBody: content: application/json: @@ -2254,6 +2830,32 @@ paths: long fieldId = 2L; client.contactsApi().contactFields().deleteContactField(accountId, fieldId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + if _, err := client.ContactFields.Delete(context.Background(), 1000001); err != nil { + log.Fatal(err) + } + + fmt.Println("contact field deleted") + } responses: '204': description: Contact Field successfully deleted diff --git a/specs/email-campaigns.openapi.yml b/specs/email-campaigns.openapi.yml index 0f26dc5..01b4f23 100644 --- a/specs/email-campaigns.openapi.yml +++ b/specs/email-campaigns.openapi.yml @@ -58,6 +58,48 @@ paths: source: | curl -X GET "https://mailtrap.io/api/email_campaigns?per_page=50&token=1" \ -H 'Api-Token: YOUR_API_KEY' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + page, _, err := client.EmailCampaigns.List(context.Background(), &mailtrap.EmailCampaignListOptions{ + PerPage: 50, + Search: "newsletter", + }) + if err != nil { + log.Fatal(err) + } + + for _, campaign := range page.Data { + fmt.Printf("%d %s (%s)\n", campaign.ID, campaign.Name, campaign.CurrentState) + } + + // To walk every page instead of one, use the iterator, which follows + // pagination.next_token for you: + // + // for campaign, err := range client.EmailCampaigns.All(context.Background(), nil) { + // if err != nil { + // log.Fatal(err) + // } + // fmt.Println(campaign.Name) + // } + } post: operationId: createEmailCampaign summary: Create an email campaign @@ -107,6 +149,53 @@ paths: }, "template_attributes": { "subject": "Spring is here — 30% off" } }' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // A campaign is always created as a draft; scheduling and starting it are + // separate actions. + campaign, _, err := client.EmailCampaigns.Create(context.Background(), &mailtrap.CreateEmailCampaignRequest{ + Name: "March newsletter", + DomainID: 1000001, + FromDisplayName: "Acme Corp", + FromLocalPart: "news", + ReplyTo: &mailtrap.EmailCampaignReplyTo{ + DisplayName: "Acme Support", + LocalPart: "support", + Domain: "mail.example.com", + }, + TemplateAttributes: &mailtrap.EmailCampaignTemplateAttributes{ + Subject: "Hi {{first_name}}, here is March", + BodyHTML: "

Hello {{first_name}}

Unsubscribe", + MergeTags: []string{"first_name"}, + }, + DeliveryMode: mailtrap.EmailCampaignDeliveryModeGradual, + DeliveryOptions: &mailtrap.EmailCampaignDeliveryOptions{EmailsPerHour: mailtrap.Ptr(5000)}, + ContactListIDs: []int64{1, 2}, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("created campaign %d (%s)\n", campaign.ID, campaign.CurrentState) + } "/api/email_campaigns/{email_campaign_id}": get: operationId: getEmailCampaign @@ -133,6 +222,33 @@ paths: source: | curl -X GET "https://mailtrap.io/api/email_campaigns/4567" \ -H 'Api-Token: YOUR_API_KEY' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + campaign, _, err := client.EmailCampaigns.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s: %s, subject %q\n", campaign.Name, campaign.CurrentState, campaign.Template.Subject) + } patch: operationId: updateEmailCampaign summary: Update an email campaign @@ -186,6 +302,43 @@ paths: "body_html": "

Hi {{first_name}}!

Unsubscribe

" } }' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Only a draft campaign can be updated, and only the fields you set change. + // The list and segment fields are pointers: nil leaves them unchanged, while a + // pointer to an empty slice clears them. + campaign, _, err := client.EmailCampaigns.Update(context.Background(), 1000001, &mailtrap.UpdateEmailCampaignRequest{ + Name: "March newsletter (final)", + TemplateAttributes: &mailtrap.EmailCampaignTemplateAttributes{ + Subject: "Hi {{first_name}}, March is here", + }, + ContactListIDs: mailtrap.Ptr([]int64{3}), + ContactSegmentIDs: mailtrap.Ptr([]int64{}), + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("updated campaign %d: %s\n", campaign.ID, campaign.Name) + } delete: operationId: deleteEmailCampaign summary: Delete an email campaign @@ -219,6 +372,33 @@ paths: source: | curl -X DELETE "https://mailtrap.io/api/email_campaigns/4567" \ -H 'Api-Token: YOUR_API_KEY' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Only a campaign in the draft state can be deleted. + if _, err := client.EmailCampaigns.Delete(context.Background(), 1000001); err != nil { + log.Fatal(err) + } + + fmt.Println("campaign deleted") + } "/api/email_campaigns/{email_campaign_id}/start": post: operationId: startEmailCampaign @@ -252,6 +432,33 @@ paths: source: | curl -X POST "https://mailtrap.io/api/email_campaigns/4567/start" \ -H 'Api-Token: YOUR_API_KEY' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + campaign, _, err := client.EmailCampaigns.Start(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("campaign %d is %s\n", campaign.ID, campaign.CurrentState) + } "/api/email_campaigns/{email_campaign_id}/schedule": post: operationId: scheduleEmailCampaign @@ -294,6 +501,34 @@ paths: -H 'Api-Token: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "datetime": "2026-06-01T09:00:00.000Z" }' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The datetime is ISO 8601, must be in the future and no more than a month ahead. + campaign, _, err := client.EmailCampaigns.Schedule(context.Background(), 1000001, "2026-10-01T09:00:00Z") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("campaign %d is %s for %s\n", campaign.ID, campaign.CurrentState, campaign.CurrentStateMetadata.ScheduledAt) + } "/api/email_campaigns/{email_campaign_id}/cancel": post: operationId: cancelEmailCampaign @@ -325,6 +560,34 @@ paths: source: | curl -X POST "https://mailtrap.io/api/email_campaigns/4567/cancel" \ -H 'Api-Token: YOUR_API_KEY' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Cancel returns a scheduled campaign to the draft state. + campaign, _, err := client.EmailCampaigns.Cancel(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("campaign %d is %s\n", campaign.ID, campaign.CurrentState) + } "/api/email_campaigns/{email_campaign_id}/terminate": post: operationId: terminateEmailCampaign @@ -356,6 +619,34 @@ paths: source: | curl -X POST "https://mailtrap.io/api/email_campaigns/4567/terminate" \ -H 'Api-Token: YOUR_API_KEY' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Terminate aborts a campaign that is started, queued or paused. + campaign, _, err := client.EmailCampaigns.Terminate(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("campaign %d is %s\n", campaign.ID, campaign.CurrentState) + } "/api/email_campaigns/{email_campaign_id}/reset": post: operationId: resetEmailCampaign @@ -386,6 +677,34 @@ paths: source: | curl -X POST "https://mailtrap.io/api/email_campaigns/4567/reset" \ -H 'Api-Token: YOUR_API_KEY' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Reset returns a scheduled campaign to the draft state. + campaign, _, err := client.EmailCampaigns.Reset(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("campaign %d is %s\n", campaign.ID, campaign.CurrentState) + } "/api/email_campaigns/{email_campaign_id}/stats": get: operationId: getEmailCampaignStats @@ -424,6 +743,39 @@ paths: source: | curl -X GET "https://mailtrap.io/api/email_campaigns/4567/stats?start_date=2026-05-01&end_date=2026-05-31" \ -H 'Api-Token: YOUR_API_KEY' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Pass nil for the default window, which is the period since the campaign was + // last started. + stats, _, err := client.EmailCampaigns.Stats(context.Background(), 1000001, &mailtrap.EmailCampaignStatsOptions{ + StartDate: "2026-03-01", + EndDate: "2026-03-31", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("delivered %d (%.2f), opened %d (%.2f), clicked %d (%.2f)\n", + stats.DeliveryCount, stats.DeliveryRate, stats.OpenCount, stats.OpenRate, stats.ClickCount, stats.ClickRate) + } components: securitySchemes: HeaderAuth: diff --git a/specs/email-sending-bulk.openapi.yml b/specs/email-sending-bulk.openapi.yml index 2cc0b73..8a4ca17 100644 --- a/specs/email-sending-bulk.openapi.yml +++ b/specs/email-sending-bulk.openapi.yml @@ -212,6 +212,40 @@ paths: .build(); client.bulkSendingApi().emails().send(mail); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN"), mailtrap.WithBulk(true)) + if err != nil { + log.Fatal(err) + } + + // WithBulk(true) routes Send and SendBatch to the bulk host. + response, _, err := client.Send(context.Background(), &mailtrap.SendRequest{ + From: mailtrap.Address{Email: "sender@mail.example.com", Name: "Mailtrap Test"}, + To: []mailtrap.Address{{Email: "recipient@example.com"}}, + Subject: "You are awesome!", + Text: "Congrats for sending test email with Mailtrap!", + Category: "Bulk Test", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("sent: %v\n", response.MessageIDs) + } requestBody: required: true content: @@ -447,6 +481,47 @@ paths: .build(); client.bulkSendingApi().emails().batchSend(batchMail); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN"), mailtrap.WithBulk(true)) + if err != nil { + log.Fatal(err) + } + + // Base holds the fields shared by every message; per-request fields override it. + response, _, err := client.SendBatch(context.Background(), &mailtrap.BatchSendRequest{ + Base: &mailtrap.SendRequest{ + From: mailtrap.Address{Email: "sender@mail.example.com", Name: "Mailtrap Test"}, + Subject: "You are awesome!", + Text: "Congrats for sending test email with Mailtrap!", + Category: "Bulk Test", + }, + Requests: []mailtrap.SendRequest{ + {To: []mailtrap.Address{{Email: "first@example.com"}}}, + {To: []mailtrap.Address{{Email: "second@example.com"}}}, + }, + }) + if err != nil { + log.Fatal(err) + } + + for i, item := range response.Responses { + fmt.Printf("message %d: success=%t ids=%v errors=%v\n", i, item.Success, item.MessageIDs, item.Errors) + } + } requestBody: required: true content: diff --git a/specs/email-sending-transactional.openapi.yml b/specs/email-sending-transactional.openapi.yml index b554bf3..26523e6 100644 --- a/specs/email-sending-transactional.openapi.yml +++ b/specs/email-sending-transactional.openapi.yml @@ -182,6 +182,40 @@ paths: .build(); client.sendingApi().emails().send(mail); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The default client targets the transactional host. + response, _, err := client.Send(context.Background(), &mailtrap.SendRequest{ + From: mailtrap.Address{Email: "sender@mail.example.com", Name: "Mailtrap Test"}, + To: []mailtrap.Address{{Email: "recipient@example.com"}}, + Subject: "You are awesome!", + Text: "Congrats for sending test email with Mailtrap!", + Category: "Integration Test", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("sent: %v\n", response.MessageIDs) + } requestBody: required: true content: @@ -416,6 +450,47 @@ paths: .build(); client.sendingApi().emails().batchSend(batchMail); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Base holds the fields shared by every message; per-request fields override it. + response, _, err := client.SendBatch(context.Background(), &mailtrap.BatchSendRequest{ + Base: &mailtrap.SendRequest{ + From: mailtrap.Address{Email: "sender@mail.example.com", Name: "Mailtrap Test"}, + Subject: "You are awesome!", + Text: "Congrats for sending test email with Mailtrap!", + Category: "Integration Test", + }, + Requests: []mailtrap.SendRequest{ + {To: []mailtrap.Address{{Email: "first@example.com"}}}, + {To: []mailtrap.Address{{Email: "second@example.com"}}}, + }, + }) + if err != nil { + log.Fatal(err) + } + + for i, item := range response.Responses { + fmt.Printf("message %d: success=%t ids=%v errors=%v\n", i, item.Success, item.MessageIDs, item.Errors) + } + } requestBody: required: true content: diff --git a/specs/email-sending.openapi.yml b/specs/email-sending.openapi.yml index 4fffb5b..500a2ce 100644 --- a/specs/email-sending.openapi.yml +++ b/specs/email-sending.openapi.yml @@ -186,6 +186,59 @@ paths: .create(YOUR_ACCOUNT_ID, request); System.out.println(domain); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + domain, _, err := client.SendingDomains.Create(context.Background(), "mail.example.com") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("created domain %d (%s)\n", domain.ID, domain.DomainName) + for _, record := range domain.DNSRecords { + fmt.Printf(" %s %s %q -> %q\n", record.Key, record.Type, record.Name, record.Value) + } + } + - lang: hcl + label: Terraform + source: | + # terraform apply creates the domain: POST /api/domains + # Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + # Create only accepts domain_name. The tracking flags below make the same apply + # follow up with a PATCH. + resource "mailtrap_domain" "example" { + domain_name = "mail.example.com" + open_tracking_enabled = true + click_tracking_enabled = true + } requestBody: required: true content: @@ -324,6 +377,35 @@ paths: domains.forEach(domain -> System.out.println("Domain: " + domain.getDomainName()) ); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + domains, _, err := client.SendingDomains.List(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, domain := range domains { + fmt.Printf("%d %s (DNS verified: %t, compliance: %s)\n", domain.ID, domain.DomainName, domain.DNSVerified, domain.ComplianceStatus) + } + } responses: '200': $ref: '#/components/responses/DomainsResponse' @@ -436,6 +518,56 @@ paths: .getSendingDomain(YOUR_ACCOUNT_ID, domainId); System.out.println("Domain: " + domain.getDomainName()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + domain, _, err := client.SendingDomains.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s: DNS verified %t, open tracking %t\n", domain.DomainName, domain.DNSVerified, domain.OpenTrackingEnabled) + } + - lang: hcl + label: Terraform + source: | + # terraform apply reads the domain: GET /api/domains/{domain_id} + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + # The domain data source can only be looked up by id: there is no name lookup. + data "mailtrap_domain" "example" { + id = 1000001 + } + + output "dns_verified" { + value = data.mailtrap_domain.example.dns_verified + } parameters: - $ref: '#/components/parameters/domain_id' responses: @@ -548,6 +680,32 @@ paths: .deleteSendingDomain(YOUR_ACCOUNT_ID, domainId); System.out.println("Domain deleted successfully"); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + if _, err := client.SendingDomains.Delete(context.Background(), 1000001); err != nil { + log.Fatal(err) + } + + fmt.Println("domain deleted") + } parameters: - $ref: '#/components/parameters/domain_id' responses: @@ -599,6 +757,39 @@ paths: click_tracking_enabled: true, auto_unsubscribe_link_enabled: false ) + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The tracking flags are pointers: a nil field keeps its current value, so use + // mailtrap.Ptr to send an explicit true or false. + domain, _, err := client.SendingDomains.Update(context.Background(), 1000001, &mailtrap.UpdateDomainRequest{ + OpenTrackingEnabled: mailtrap.Ptr(true), + ClickTrackingEnabled: mailtrap.Ptr(true), + AutoUnsubscribeLinkEnabled: mailtrap.Ptr(false), + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s: open tracking %t, click tracking %t\n", domain.DomainName, domain.OpenTrackingEnabled, domain.ClickTrackingEnabled) + } parameters: - $ref: '#/components/parameters/domain_id' requestBody: @@ -759,6 +950,32 @@ paths: ); System.out.println("Setup instructions sent"); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + if _, err := client.SendingDomains.SendSetupInstructions(context.Background(), 1000001, "devops@example.com"); err != nil { + log.Fatal(err) + } + + fmt.Println("setup instructions sent") + } parameters: - $ref: '#/components/parameters/domain_id' requestBody: @@ -813,6 +1030,33 @@ paths: domain_id = 12345 puts company_info.get(domain_id) + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + info, _, err := client.SendingDomains.CompanyInfo(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s (%s), %s %s, %s\n", info.Name, info.InfoLevel, info.ZipCode, info.City, info.Country) + } parameters: - $ref: '#/components/parameters/domain_id' responses: @@ -874,6 +1118,41 @@ paths: website_url: 'https://mailtrap.io', info_level: 'business' ) + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + info, _, err := client.SendingDomains.CreateCompanyInfo(context.Background(), 1000001, &mailtrap.CompanyInfoRequest{ + Name: "Example Inc.", + Address: "1 Example Street", + City: "Dublin", + Country: "Ireland", + ZipCode: "D01 F5P2", + WebsiteURL: "https://example.com", + InfoLevel: mailtrap.InfoLevelBusiness, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("company info set for %s\n", info.Name) + } parameters: - $ref: '#/components/parameters/domain_id' requestBody: @@ -943,6 +1222,37 @@ paths: domain_id = 12345 puts company_info.update(domain_id, city: 'New York', zip_code: '10001') + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Only the fields you set are changed. + info, _, err := client.SendingDomains.UpdateCompanyInfo(context.Background(), 1000001, &mailtrap.CompanyInfoRequest{ + Phone: "+353 1 234 5678", + PrivacyPolicyURL: "https://example.com/privacy", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("company info updated for %s\n", info.Name) + } parameters: - $ref: '#/components/parameters/domain_id' requestBody: @@ -1130,6 +1440,38 @@ paths: filtered.forEach(filteredSuppression -> System.out.println("Email: " + filteredSuppression.getEmail()) ); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + suppressions, _, err := client.Suppressions.List(context.Background(), &mailtrap.SuppressionListOptions{ + StartTime: "2026-01-01T00:00:00Z", + EndTime: "2026-02-01T00:00:00Z", + }) + if err != nil { + log.Fatal(err) + } + + for _, suppression := range suppressions { + fmt.Printf("%s %s (%s, %s)\n", suppression.ID, suppression.Email, suppression.Type, suppression.SendingStream) + } + } parameters: - name: email in: query @@ -1196,6 +1538,38 @@ paths: "sending_stream": "transactional", "type": "manual import" }' + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + suppression, _, err := client.Suppressions.Create(context.Background(), &mailtrap.CreateSuppressionRequest{ + Email: "bounced@example.com", + DomainID: 1000001, + SendingStream: mailtrap.SendingStreamTransactional, + Type: mailtrap.SuppressionTypeHardBounce, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("suppressed %s (%s)\n", suppression.Email, suppression.Type) + } requestBody: required: true content: @@ -1348,6 +1722,34 @@ paths: .deleteSuppression(YOUR_ACCOUNT_ID, suppressionId); System.out.println("Suppression removed: " + result.getEmail()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Delete returns the suppression it removed. + suppression, _, err := client.Suppressions.Delete(context.Background(), "018dd3e0-1d2f-7a4b-9c8e-3f5a6b7c8d9e") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("unsuppressed %s\n", suppression.Email) + } parameters: - $ref: '#/components/parameters/suppression_id' responses: @@ -1592,6 +1994,37 @@ paths: var filter = StatsFilter.builder().startDate("2026-01-01").endDate("2026-01-31").build(); var stats = client.sendingApi().stats().getStats(accountId, filter); System.out.println(stats); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // StartDate and EndDate are required; the other fields narrow the query. + stats, _, err := client.Stats.Get(context.Background(), &mailtrap.StatsOptions{ + StartDate: "2026-01-01", + EndDate: "2026-01-31", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("delivered %d (%.2f), opened %d (%.2f)\n", stats.DeliveryCount, stats.DeliveryRate, stats.OpenCount, stats.OpenRate) + } parameters: - $ref: '#/components/parameters/StartDateQueryFilter' - $ref: '#/components/parameters/EndDateQueryFilter' @@ -1698,6 +2131,39 @@ paths: var filter = StatsFilter.builder().startDate("2026-01-01").endDate("2026-01-31").build(); var stats = client.sendingApi().stats().byDomain(accountId, filter); System.out.println(stats); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + stats, _, err := client.Stats.ByDomain(context.Background(), &mailtrap.StatsOptions{ + StartDate: "2026-01-01", + EndDate: "2026-01-31", + SendingStreams: []string{mailtrap.SendingStreamTransactional}, + }) + if err != nil { + log.Fatal(err) + } + + for _, entry := range stats { + fmt.Printf("domain %d: delivered %d, bounced %d\n", entry.DomainID, entry.Stats.DeliveryCount, entry.Stats.BounceCount) + } + } parameters: - $ref: '#/components/parameters/StartDateQueryFilter' - $ref: '#/components/parameters/EndDateQueryFilter' @@ -1819,6 +2285,39 @@ paths: var filter = StatsFilter.builder().startDate("2026-01-01").endDate("2026-01-31").build(); var stats = client.sendingApi().stats().byCategory(accountId, filter); System.out.println(stats); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + stats, _, err := client.Stats.ByCategory(context.Background(), &mailtrap.StatsOptions{ + StartDate: "2026-01-01", + EndDate: "2026-01-31", + Categories: []string{"Password Reset"}, + }) + if err != nil { + log.Fatal(err) + } + + for _, entry := range stats { + fmt.Printf("%s: delivered %d, opened %d\n", entry.Category, entry.Stats.DeliveryCount, entry.Stats.OpenCount) + } + } parameters: - $ref: '#/components/parameters/StartDateQueryFilter' - $ref: '#/components/parameters/EndDateQueryFilter' @@ -1933,6 +2432,38 @@ paths: var filter = StatsFilter.builder().startDate("2026-01-01").endDate("2026-01-31").build(); var stats = client.sendingApi().stats().byEmailServiceProvider(accountId, filter); System.out.println(stats); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + stats, _, err := client.Stats.ByEmailServiceProvider(context.Background(), &mailtrap.StatsOptions{ + StartDate: "2026-01-01", + EndDate: "2026-01-31", + }) + if err != nil { + log.Fatal(err) + } + + for _, entry := range stats { + fmt.Printf("%s: delivered %d (%.2f)\n", entry.EmailServiceProvider, entry.Stats.DeliveryCount, entry.Stats.DeliveryRate) + } + } parameters: - $ref: '#/components/parameters/StartDateQueryFilter' - $ref: '#/components/parameters/EndDateQueryFilter' @@ -2047,6 +2578,39 @@ paths: var filter = StatsFilter.builder().startDate("2026-01-01").endDate("2026-01-31").build(); var stats = client.sendingApi().stats().byDate(accountId, filter); System.out.println(stats); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + stats, _, err := client.Stats.ByDate(context.Background(), &mailtrap.StatsOptions{ + StartDate: "2026-01-01", + EndDate: "2026-01-31", + SendingDomainIDs: []int64{1000001}, + }) + if err != nil { + log.Fatal(err) + } + + for _, entry := range stats { + fmt.Printf("%s: delivered %d, clicked %d\n", entry.Date, entry.Stats.DeliveryCount, entry.Stats.ClickCount) + } + } parameters: - $ref: '#/components/parameters/StartDateQueryFilter' - $ref: '#/components/parameters/EndDateQueryFilter' @@ -2163,6 +2727,50 @@ paths: long accountId = 1000001L; var response = client.sendingApi().emailLogs().list(accountId, null, null); System.out.println(response.getTotalCount()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + logs, _, err := client.EmailLogs.List(context.Background(), &mailtrap.EmailLogsListOptions{ + SentAfter: "2026-01-01T00:00:00Z", + Filters: map[string]mailtrap.LogFilter{ + "status": {Operator: "equal", Values: []string{mailtrap.EmailLogStatusDelivered}}, + }, + }) + if err != nil { + log.Fatal(err) + } + + for _, message := range logs.Messages { + fmt.Printf("%s %s -> %s (%s)\n", message.MessageID, message.From, message.To, message.Status) + } + + // To walk every page instead of one, use the iterator, which follows + // next_page_cursor for you: + // + // for message, err := range client.EmailLogs.All(context.Background(), nil) { + // if err != nil { + // log.Fatal(err) + // } + // fmt.Println(message.MessageID) + // } + } parameters: - name: search_after in: query @@ -2281,6 +2889,36 @@ paths: String messageId = "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"; var message = client.sendingApi().emailLogs().get(accountId, messageId); System.out.println(message.getSubject()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + message, _, err := client.EmailLogs.Get(context.Background(), "018dd3e0-1d2f-7a4b-9c8e-3f5a6b7c8d9e") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s (%s), %d open(s)\n", message.Subject, message.Status, message.OpensCount) + for _, event := range message.Events { + fmt.Printf(" %s at %s\n", event.EventType, event.CreatedAt) + } + } parameters: - $ref: '#/components/parameters/sending_message_id' responses: @@ -2452,6 +3090,75 @@ paths: // signing_secret is returned only on creation — store it securely. var webhook = client.generalApi().webhooks().createWebhook(accountId, request); System.out.println(webhook); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The API requires sending_stream for email_sending webhooks. + webhook, _, err := client.Webhooks.Create(context.Background(), &mailtrap.CreateWebhookRequest{ + URL: "https://example.com/mailtrap/webhook", + WebhookType: mailtrap.WebhookTypeEmailSending, + SendingStream: mailtrap.SendingStreamTransactional, + PayloadFormat: mailtrap.PayloadFormatJSON, + DomainID: mailtrap.Ptr(int64(1000001)), + EventTypes: []string{mailtrap.WebhookEventDelivery, mailtrap.WebhookEventBounce, mailtrap.WebhookEventOpen}, + Active: mailtrap.Ptr(true), + }) + if err != nil { + log.Fatal(err) + } + + // The signing secret is returned only here: store it to verify payloads. + fmt.Printf("created webhook %d, signing secret %s\n", webhook.ID, webhook.SigningSecret) + } + - lang: hcl + label: Terraform + source: | + # terraform apply creates the webhook: POST /api/webhooks + # Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + # The API requires sending_stream for email_sending webhooks. + resource "mailtrap_webhook" "delivery" { + url = "https://example.com/mailtrap/webhook" + webhook_type = "email_sending" + sending_stream = "transactional" + domain_id = 1000001 + payload_format = "json" + event_types = ["delivery", "bounce", "open"] + active = true + } + + # signing_secret is returned only on create, and is unavailable after an import. + output "signing_secret" { + value = mailtrap_webhook.delivery.signing_secret + sensitive = true + } requestBody: required: true content: @@ -2642,6 +3349,35 @@ paths: long accountId = 1000001L; var webhooks = client.generalApi().webhooks().getAllWebhooks(accountId); System.out.println(webhooks); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + webhooks, _, err := client.Webhooks.List(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, webhook := range webhooks { + fmt.Printf("%d %s (%s, active: %t)\n", webhook.ID, webhook.URL, webhook.WebhookType, webhook.Active) + } + } responses: '200': description: List of webhooks @@ -2761,6 +3497,33 @@ paths: long webhookId = 123L; var webhook = client.generalApi().webhooks().getWebhook(accountId, webhookId); System.out.println(webhook); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + webhook, _, err := client.Webhooks.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s (%s): %v\n", webhook.URL, webhook.PayloadFormat, webhook.EventTypes) + } parameters: - $ref: '#/components/parameters/webhook_id' responses: @@ -2891,6 +3654,39 @@ paths: var request = new UpdateWebhookRequest(WebhookInput.builder().active(false).build()); var webhook = client.generalApi().webhooks().updateWebhook(accountId, webhookId, request); System.out.println(webhook); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Only url, active, payload_format and event_types are mutable. + webhook, _, err := client.Webhooks.Update(context.Background(), 1000001, &mailtrap.UpdateWebhookRequest{ + URL: "https://example.com/mailtrap/webhook/v2", + Active: mailtrap.Ptr(false), + PayloadFormat: mailtrap.PayloadFormatJSONLines, + EventTypes: []string{mailtrap.WebhookEventDelivery, mailtrap.WebhookEventSpamComplaint}, + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("updated webhook %d: %s (active: %t)\n", webhook.ID, webhook.URL, webhook.Active) + } parameters: - $ref: '#/components/parameters/webhook_id' requestBody: @@ -3058,6 +3854,34 @@ paths: long accountId = 1000001L; long webhookId = 123L; client.generalApi().webhooks().deleteWebhook(accountId, webhookId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Delete returns the webhook it removed. + webhook, _, err := client.Webhooks.Delete(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("deleted webhook %d (%s)\n", webhook.ID, webhook.URL) + } parameters: - $ref: '#/components/parameters/webhook_id' responses: diff --git a/specs/sandbox-sending.openapi.yml b/specs/sandbox-sending.openapi.yml index c6bc9b5..b4dc973 100644 --- a/specs/sandbox-sending.openapi.yml +++ b/specs/sandbox-sending.openapi.yml @@ -186,6 +186,39 @@ paths: .build(); client.testingApi().emails().send(mail, config.getInboxId()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN"), mailtrap.WithSandbox(true), mailtrap.WithSandboxID(3000001)) + if err != nil { + log.Fatal(err) + } + + response, _, err := client.Send(context.Background(), &mailtrap.SendRequest{ + From: mailtrap.Address{Email: "sender@example.com", Name: "Mailtrap Test"}, + To: []mailtrap.Address{{Email: "recipient@example.com"}}, + Subject: "You are awesome!", + Text: "Congrats for sending test email with Mailtrap!", + Category: "Integration Test", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("captured by the sandbox: %v\n", response.MessageIDs) + } requestBody: content: application/json: @@ -460,6 +493,46 @@ paths: .batchSend(batchMail, config.getInboxId()); System.out.println(response); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN"), mailtrap.WithSandbox(true), mailtrap.WithSandboxID(3000001)) + if err != nil { + log.Fatal(err) + } + + // Base holds the fields shared by every message; per-request fields override it. + response, _, err := client.SendBatch(context.Background(), &mailtrap.BatchSendRequest{ + Base: &mailtrap.SendRequest{ + From: mailtrap.Address{Email: "sender@example.com", Name: "Mailtrap Test"}, + Subject: "You are awesome!", + Text: "Congrats for sending test email with Mailtrap!", + }, + Requests: []mailtrap.SendRequest{ + {To: []mailtrap.Address{{Email: "first@example.com"}}}, + {To: []mailtrap.Address{{Email: "second@example.com"}}}, + }, + }) + if err != nil { + log.Fatal(err) + } + + for i, item := range response.Responses { + fmt.Printf("message %d: success=%t ids=%v errors=%v\n", i, item.Success, item.MessageIDs, item.Errors) + } + } requestBody: content: application/json: diff --git a/specs/sandbox.openapi.yml b/specs/sandbox.openapi.yml index dfe05bd..7bd80a3 100644 --- a/specs/sandbox.openapi.yml +++ b/specs/sandbox.openapi.yml @@ -161,6 +161,57 @@ paths: .getInboxes(accountId); System.out.println(inboxes); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + sandboxes, _, err := client.Sandboxes.List(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, sandbox := range sandboxes { + fmt.Printf("%d %s (%d message(s), %d unread)\n", sandbox.ID, sandbox.Name, sandbox.EmailsCount, sandbox.EmailsUnreadCount) + } + } + - lang: hcl + label: Terraform + source: | + # looking a sandbox up by name lists them: GET /api/sandboxes + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + data "mailtrap_sandbox" "staging" { + name = "Staging inbox" + } + + output "sandbox_id" { + value = data.mailtrap_sandbox.staging.id + } operationId: getSandboxes '/api/projects': post: @@ -303,6 +354,52 @@ paths: .createProject(accountId, request); System.out.println(project); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + project, _, err := client.Projects.Create(context.Background(), "My project") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("created project %d (%s)\n", project.ID, project.Name) + } + - lang: hcl + label: Terraform + source: | + # terraform apply creates the project: POST /api/projects + # Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + resource "mailtrap_project" "testing" { + name = "My project" + } get: summary: Get a list of projects description: List projects and their sandboxes to which the API token has access. @@ -419,6 +516,57 @@ paths: System.out.println("Project: " + project.getName() + ", ID: " + project.getId()); } + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + projects, _, err := client.Projects.List(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, project := range projects { + fmt.Printf("%d %s (%d sandbox(es))\n", project.ID, project.Name, len(project.Sandboxes)) + } + } + - lang: hcl + label: Terraform + source: | + # looking a project up by name lists them: GET /api/projects + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + data "mailtrap_project" "testing" { + name = "My project" + } + + output "project_id" { + value = data.mailtrap_project.testing.id + } '/api/projects/{project_id}': get: summary: Get project by ID @@ -539,6 +687,55 @@ paths: .getProject(accountId, projectId); System.out.println("Project: " + project.getName()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + project, _, err := client.Projects.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%d %s\n", project.ID, project.Name) + } + - lang: hcl + label: Terraform + source: | + # terraform apply reads the project: GET /api/projects/{project_id} + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + data "mailtrap_project" "testing" { + id = 1000001 + } + + output "project_name" { + value = data.mailtrap_project.testing.name + } patch: summary: Update project description: Update project name. The project name is min 2 characters and max 100 characters long. @@ -671,6 +868,33 @@ paths: .updateProject(accountId, projectId, request); System.out.println("Project updated: " + updatedProject.getName()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + project, _, err := client.Projects.Update(context.Background(), 1000001, "Renamed project") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("renamed project %d to %s\n", project.ID, project.Name) + } requestBody: content: application/json: @@ -803,6 +1027,32 @@ paths: .deleteProject(accountId, projectId); System.out.println("Project deleted: " + deletedProject.getId()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + if _, err := client.Projects.Delete(context.Background(), 1000001); err != nil { + log.Fatal(err) + } + + fmt.Println("project deleted") + } responses: '200': description: Returns id of the deleted project. @@ -977,6 +1227,59 @@ paths: System.out.println("Inbox created: " + inbox.getName()); System.out.println("SMTP credentials - User: " + inbox.getUsername()); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + sandbox, _, err := client.Sandboxes.Create(context.Background(), 1000001, "Staging inbox") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("created sandbox %d (%s)\n", sandbox.ID, sandbox.Name) + } + - lang: hcl + label: Terraform + source: | + # terraform apply creates the sandbox: POST /api/projects/{project_id}/sandboxes + # Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + resource "mailtrap_project" "testing" { + name = "My project" + } + + # Create only accepts name and project_id. Setting email_username makes the same + # apply follow up with a PATCH. + resource "mailtrap_sandbox" "staging" { + name = "Staging inbox" + project_id = mailtrap_project.testing.id + } parameters: - $ref: '#/components/parameters/project_id' '/api/sandboxes/{sandbox_id}': @@ -1092,6 +1395,55 @@ paths: .getInboxAttributes(accountId, inboxId); System.out.println(inboxAttributes); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + sandbox, _, err := client.Sandboxes.Get(context.Background(), 3000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s: %s@%s, SMTP %v\n", sandbox.Name, sandbox.Username, sandbox.Domain, sandbox.SMTPPorts) + } + - lang: hcl + label: Terraform + source: | + # terraform apply reads the sandbox: GET /api/sandboxes/{sandbox_id} + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + data "mailtrap_sandbox" "staging" { + id = 3000001 + } + + output "smtp_host" { + value = data.mailtrap_sandbox.staging.domain + } operationId: getSandboxAttributes delete: summary: Delete a sandbox @@ -1203,6 +1555,34 @@ paths: .deleteInbox(ACCOUNT_ID, inboxId); System.out.println(deletedInbox); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Unlike most deletes, this one returns the deleted sandbox. + sandbox, _, err := client.Sandboxes.Delete(context.Background(), 3000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("deleted sandbox %d (%s)\n", sandbox.ID, sandbox.Name) + } operationId: deleteSandbox patch: summary: Update a sandbox @@ -1361,6 +1741,36 @@ paths: .updateInbox(accountId, inboxId, updateRequest); System.out.println(updatedInbox); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + sandbox, _, err := client.Sandboxes.Update(context.Background(), 3000001, &mailtrap.SandboxUpdateRequest{ + Name: "Renamed inbox", + EmailUsername: "staging", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("updated sandbox %d: %s\n", sandbox.ID, sandbox.Name) + } operationId: updateSandbox parameters: - $ref: '#/components/parameters/sandbox_id' @@ -1477,6 +1887,33 @@ paths: .cleanInbox(accountId, inboxId); System.out.println(cleanedInbox); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + sandbox, _, err := client.Sandboxes.Clean(context.Background(), 3000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("sandbox %d now holds %d message(s)\n", sandbox.ID, sandbox.EmailsCount) + } operationId: cleanSandbox parameters: - $ref: '#/components/parameters/sandbox_id' @@ -1593,6 +2030,33 @@ paths: .markAsRead(accountId, inboxId); System.out.println(markedInbox); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + sandbox, _, err := client.Sandboxes.MarkAllRead(context.Background(), 3000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("sandbox %d has %d unread message(s)\n", sandbox.ID, sandbox.EmailsUnreadCount) + } operationId: markAsReadSandbox parameters: - $ref: '#/components/parameters/sandbox_id' @@ -1709,6 +2173,33 @@ paths: .resetCredentials(accountId, inboxId); System.out.println(updatedInbox); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + sandbox, _, err := client.Sandboxes.ResetCredentials(context.Background(), 3000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("new SMTP credentials: %s / %s\n", sandbox.Username, sandbox.Password) + } operationId: resetSandboxCredentials parameters: - $ref: '#/components/parameters/sandbox_id' @@ -1827,6 +2318,33 @@ paths: .enableEmailAddress(accountId, inboxId); System.out.println(updatedInbox); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + sandbox, _, err := client.Sandboxes.ToggleEmailAddress(context.Background(), 3000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("email address enabled: %t (%s@%s)\n", sandbox.EmailUsernameEnabled, sandbox.EmailUsername, sandbox.EmailDomain) + } operationId: enableSandboxEmailAddresses parameters: - $ref: '#/components/parameters/sandbox_id' @@ -1946,6 +2464,33 @@ paths: .resetEmailAddresses(accountId, inboxId); System.out.println(updatedInbox); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + sandbox, _, err := client.Sandboxes.ResetEmailAddress(context.Background(), 3000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("email address reset to %s@%s\n", sandbox.EmailUsername, sandbox.EmailDomain) + } operationId: resetEmailUserNamePerSandbox parameters: - $ref: '#/components/parameters/sandbox_id' @@ -2118,6 +2663,33 @@ paths: .getMessage(accountId, inboxId, messageId); System.out.println(message); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + message, _, err := client.SandboxMessages.Get(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s -> %s: %s (read: %t)\n", message.FromEmail, message.ToEmail, message.Subject, message.IsRead) + } operationId: showSandboxEmailMessage patch: summary: Update message @@ -2367,6 +2939,33 @@ paths: .updateMessage(accountId, inboxId, messageId, updateRequest); System.out.println(updatedMessage); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + message, _, err := client.SandboxMessages.Update(context.Background(), 3000001, 4000001, true) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("message %d read: %t\n", message.ID, message.IsRead) + } operationId: updateSandboxEmailMessage delete: summary: Delete message @@ -2576,6 +3175,34 @@ paths: .deleteMessage(accountId, inboxId, messageId); System.out.println(deletedMessage); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Delete returns the message it removed. + message, _, err := client.SandboxMessages.Delete(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("deleted message %d (%s)\n", message.ID, message.Subject) + } operationId: deleteSandboxEmailMessage parameters: - $ref: '#/components/parameters/sandbox_id' @@ -2758,6 +3385,47 @@ paths: System.out.println("Subject: " + message.getSubject()); System.out.println("Received: " + message.getCreatedAt()); } + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + messages, _, err := client.SandboxMessages.List(context.Background(), 3000001, &mailtrap.MessageListOptions{ + Search: "welcome", + Page: 1, + }) + if err != nil { + log.Fatal(err) + } + + for _, message := range messages { + fmt.Printf("%d %s (from %s)\n", message.ID, message.Subject, message.FromEmail) + } + + // To walk every page instead of one, use the iterator: + // + // for message, err := range client.SandboxMessages.All(context.Background(), 3000001, nil) { + // if err != nil { + // log.Fatal(err) + // } + // fmt.Println(message.Subject) + // } + } parameters: - schema: type: string @@ -2945,6 +3613,33 @@ paths: .forwardMessage(accountId, inboxId, messageId, forwardRequest); System.out.println(forwardedMessage); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The recipient must have confirmed forwarding to this address in advance. + if _, err := client.SandboxMessages.Forward(context.Background(), 3000001, 4000001, "qa@example.com"); err != nil { + log.Fatal(err) + } + + fmt.Println("message forwarded") + } operationId: forwardSandboxEmailMessage parameters: - $ref: '#/components/parameters/sandbox_id' @@ -3105,6 +3800,36 @@ paths: var spamReport = client.testingApi().messages().getSpamScore(accountId, inboxId, messageId); System.out.println(spamReport); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + report, _, err := client.SandboxMessages.SpamReport(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("score %.2f of %.2f, spam: %t\n", report.Score, report.Threshold, report.Spam) + for _, detail := range report.Details { + fmt.Printf(" %+.2f %s: %s\n", detail.Pts, detail.RuleName, detail.Description) + } + } operationId: getSandboxEmailMessageSpamReport parameters: - $ref: '#/components/parameters/sandbox_id' @@ -3285,6 +4010,35 @@ paths: long inboxId = 12345L; var htmlAnalysis = client.testingApi().messages().getMessageHtmlAnalysis(accountId, inboxId, messageId); System.out.println(htmlAnalysis); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + report, _, err := client.SandboxMessages.HTMLAnalysis(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + for _, issue := range report.Errors { + fmt.Printf("line %d: %s (desktop: %v)\n", issue.ErrorLine, issue.RuleName, issue.EmailClients.Desktop) + } + } operationId: getSandboxEmailMessageHTMLAnalysis parameters: - $ref: '#/components/parameters/sandbox_id' @@ -3416,6 +4170,35 @@ paths: String textBody = client.testingApi().messages().getTextMessage(accountId, inboxId, messageId); System.out.println(textBody); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The body endpoints return the raw bytes. + body, _, err := client.SandboxMessages.Text(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + // body holds the plain-text body. + fmt.Println(string(body)) + } operationId: getSandboxEmailMessageBodyAsTxt parameters: - $ref: '#/components/parameters/sandbox_id' @@ -3591,6 +4374,35 @@ paths: String rawBody = client.testingApi().messages().getRawMessage(accountId, inboxId, messageId); System.out.println(rawBody); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The body endpoints return the raw bytes. + body, _, err := client.SandboxMessages.Raw(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + // body holds the raw MIME source. + fmt.Println(string(body)) + } operationId: getSandboxEmailMessageBodyAsRaw parameters: - $ref: '#/components/parameters/sandbox_id' @@ -3741,6 +4553,35 @@ paths: String htmlSource = client.testingApi().messages().getMessageSource(accountId, inboxId, messageId); System.out.println(htmlSource); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The body endpoints return the raw bytes. + body, _, err := client.SandboxMessages.HTMLSource(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + // body holds the HTML source. + fmt.Println(string(body)) + } operationId: getSandboxEmailMessageBodyAsHtmlSource parameters: - $ref: '#/components/parameters/sandbox_id' @@ -3894,6 +4735,35 @@ paths: long messageId = 12345L; String htmlBody = client.testingApi().messages().getHtmlMessage(accountId, inboxId, messageId); System.out.println(htmlBody); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The body endpoints return the raw bytes. + body, _, err := client.SandboxMessages.HTML(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + // body holds the formatted HTML body. + fmt.Println(string(body)) + } operationId: getSandboxEmailMessageBodyAsHtml parameters: - $ref: '#/components/parameters/sandbox_id' @@ -4070,6 +4940,35 @@ paths: String emlContent = client.testingApi().messages().getMessageAsEml(accountId, inboxId, messageId); System.out.println(emlContent); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // The body endpoints return the raw bytes. + body, _, err := client.SandboxMessages.EML(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + // body holds the message in .eml format. + fmt.Println(string(body)) + } operationId: getSandboxEmailMessageBodyAsEml parameters: - $ref: '#/components/parameters/sandbox_id' @@ -4196,6 +5095,35 @@ paths: var mailHeaders = client.testingApi().messages().getMailHeaders(accountId, inboxId, messageId); System.out.println(mailHeaders); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + headers, _, err := client.SandboxMessages.Headers(context.Background(), 3000001, 4000001) + if err != nil { + log.Fatal(err) + } + + for name, value := range headers { + fmt.Printf("%s: %s\n", name, value) + } + } operationId: getMailHeadersOfEmailMessage parameters: - $ref: '#/components/parameters/sandbox_id' @@ -4361,6 +5289,37 @@ paths: long messageId = 67890L; var attachments = client.testingApi().attachments().getAttachments(accountId, inboxId, messageId, null); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + attachments, _, err := client.SandboxAttachments.List(context.Background(), 3000001, 4000001, &mailtrap.AttachmentListOptions{ + Type: "attachment", + }) + if err != nil { + log.Fatal(err) + } + + for _, attachment := range attachments { + fmt.Printf("%d %s (%s, %s)\n", attachment.ID, attachment.Filename, attachment.ContentType, attachment.AttachmentHumanSize) + } + } parameters: - $ref: '#/components/parameters/sandbox_id' - $ref: '#/components/parameters/message_id' @@ -4518,6 +5477,33 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var attachment = client.testingApi().attachments().getSingleAttachment(accountId, inboxId, messageId, attachmentId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + attachment, _, err := client.SandboxAttachments.Get(context.Background(), 3000001, 4000001, 5000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s (%s): %s\n", attachment.Filename, attachment.ContentType, attachment.DownloadPath) + } parameters: - $ref: '#/components/parameters/sandbox_id' - $ref: '#/components/parameters/message_id' diff --git a/specs/templates.openapi.yml b/specs/templates.openapi.yml index 859cd2c..24a9a8b 100644 --- a/specs/templates.openapi.yml +++ b/specs/templates.openapi.yml @@ -107,6 +107,35 @@ paths: var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.emailTemplatesApi().emailTemplates().getAllTemplates(accountId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + templates, _, err := client.EmailTemplates.List(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, template := range templates { + fmt.Printf("%d %s (%s)\n", template.ID, template.Name, template.Category) + } + } responses: '200': description: OK. @@ -246,6 +275,62 @@ paths: "Welcome {{user_name}}!", "

Welcome {{user_name}}!

") ); var template = client.emailTemplatesApi().emailTemplates().createEmailTemplate(accountId, request); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + template, _, err := client.EmailTemplates.Create(context.Background(), &mailtrap.EmailTemplateRequest{ + Name: "Welcome email", + Category: "Onboarding", + Subject: "Welcome to Mailtrap", + BodyHTML: "

Welcome, {{name}}!

", + BodyText: "Welcome, {{name}}!", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("created template %d (uuid %s)\n", template.ID, template.UUID) + } + - lang: hcl + label: Terraform + source: | + # terraform apply creates the template: POST /api/email_templates + # Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs + terraform { + required_providers { + mailtrap = { + source = "mailtrap/mailtrap" + } + } + } + + # The token is read from the MAILTRAP_API_TOKEN environment variable. + provider "mailtrap" {} + + resource "mailtrap_email_template" "welcome" { + name = "Welcome email" + category = "Onboarding" + subject = "Welcome to Mailtrap" + body_html = "

Welcome, {{name}}!

" + body_text = "Welcome, {{name}}!" + } requestBody: content: application/json: @@ -357,6 +442,33 @@ paths: var template = client.emailTemplatesApi().emailTemplates() .getEmailTemplate(accountId, templateId); System.out.println(template); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + template, _, err := client.EmailTemplates.Get(context.Background(), 1000001) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s: %s\n", template.Name, template.Subject) + } responses: '200': description: Returns attributes of the email template. @@ -496,6 +608,38 @@ paths: var template = client.emailTemplatesApi().emailTemplates() .updateEmailTemplate(accountId, templateId, request); System.out.println(template); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + // Only the fields you set are changed. A body that has been set cannot be + // cleared, only replaced. + template, _, err := client.EmailTemplates.Update(context.Background(), 1000001, &mailtrap.EmailTemplateRequest{ + Subject: "Welcome aboard", + BodyHTML: "

Welcome aboard, {{name}}!

", + }) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("updated template %d: %s\n", template.ID, template.Subject) + } requestBody: content: application/json: @@ -603,6 +747,32 @@ paths: long accountId = 1000001L; long templateId = 12345L; client.emailTemplatesApi().emailTemplates().deleteEmailTemplate(accountId, templateId); + - lang: go + label: Go + source: | + package main + + import ( + "context" + "fmt" + "log" + "os" + + "github.com/mailtrap/mailtrap-go" + ) + + func main() { + client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) + if err != nil { + log.Fatal(err) + } + + if _, err := client.EmailTemplates.Delete(context.Background(), 1000001); err != nil { + log.Fatal(err) + } + + fmt.Println("template deleted") + } responses: '204': description: No Content