func generateDomainApiUrl(m Mailgun, endpoint string) string {
	return fmt.Sprintf("%s/domains/%s/%s", m.APIBase(), m.Domain(), endpoint)
}
generateDomainApiUrl renders a URL as generateApiUrl, but
addresses a family of functions which have a non-standard URL structure.
Most URLs consume a domain in the 2nd position, but some endpoints
require the word "domains" to be there instead.
package mailgun
import (
	"context"
	"errors"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)
var Debug = false
const (
	APIBase              = "https://api.mailgun.net/v3"
	APIBaseUS            = APIBase
	APIBaseEU            = "https://api.eu.mailgun.net/v3"
	messagesEndpoint     = "messages"
	mimeMessagesEndpoint = "messages.mime"
	bouncesEndpoint      = "bounces"
	statsTotalEndpoint   = "stats/total"
	domainsEndpoint      = "domains"
	tagsEndpoint         = "tags"
	eventsEndpoint       = "events"
	unsubscribesEndpoint = "unsubscribes"
	routesEndpoint       = "routes"
	ipsEndpoint          = "ips"
	exportsEndpoint      = "exports"
	webhooksEndpoint     = "webhooks"
	listsEndpoint        = "lists"
	basicAuthUser        = "api"
	templatesEndpoint    = "templates"
)
type Mailgun interface {
	APIBase() string
	Domain() string
	APIKey() string
	Client() *http.Client
	SetClient(client *http.Client)
	SetAPIBase(url string)
	Send(ctx context.Context, m *Message) (string, string, error)
	ReSend(ctx context.Context, id string, recipients ...string) (string, string, error)
	NewMessage(from, subject, text string, to ...string) *Message
	NewMIMEMessage(body io.ReadCloser, to ...string) *Message
	ListBounces(opts *ListOptions) *BouncesIterator
	GetBounce(ctx context.Context, address string) (Bounce, error)
	AddBounce(ctx context.Context, address, code, err string) error
	DeleteBounce(ctx context.Context, address string) error
	DeleteBounceList(ctx context.Context) error
	GetStats(ctx context.Context, events []string, opts *GetStatOptions) ([]Stats, error)
	GetTag(ctx context.Context, tag string) (Tag, error)
	DeleteTag(ctx context.Context, tag string) error
	ListTags(*ListTagOptions) *TagIterator
	ListDomains(opts *ListOptions) *DomainsIterator
	GetDomain(ctx context.Context, domain string) (DomainResponse, error)
	CreateDomain(ctx context.Context, name string, opts *CreateDomainOptions) (DomainResponse, error)
	DeleteDomain(ctx context.Context, name string) error
	VerifyDomain(ctx context.Context, name string) (string, error)
	UpdateDomainConnection(ctx context.Context, domain string, dc DomainConnection) error
	GetDomainConnection(ctx context.Context, domain string) (DomainConnection, error)
	GetDomainTracking(ctx context.Context, domain string) (DomainTracking, error)
	UpdateClickTracking(ctx context.Context, domain, active string) error
	UpdateUnsubscribeTracking(ctx context.Context, domain, active, htmlFooter, textFooter string) error
	UpdateOpenTracking(ctx context.Context, domain, active string) error
	GetStoredMessage(ctx context.Context, url string) (StoredMessage, error)
	GetStoredMessageRaw(ctx context.Context, id string) (StoredMessageRaw, error)
	GetStoredAttachment(ctx context.Context, url string) ([]byte, error)
	GetStoredMessageForURL(ctx context.Context, url string) (StoredMessage, error)
	GetStoredMessageRawForURL(ctx context.Context, url string) (StoredMessageRaw, error)
	ListCredentials(opts *ListOptions) *CredentialsIterator
	CreateCredential(ctx context.Context, login, password string) error
	ChangeCredentialPassword(ctx context.Context, login, password string) error
	DeleteCredential(ctx context.Context, login string) error
	ListUnsubscribes(opts *ListOptions) *UnsubscribesIterator
	GetUnsubscribe(ctx context.Context, address string) (Unsubscribe, error)
	CreateUnsubscribe(ctx context.Context, address, tag string) error
	DeleteUnsubscribe(ctx context.Context, address string) error
	DeleteUnsubscribeWithTag(ctx context.Context, a, t string) error
	ListComplaints(opts *ListOptions) *ComplaintsIterator
	GetComplaint(ctx context.Context, address string) (Complaint, error)
	CreateComplaint(ctx context.Context, address string) error
	DeleteComplaint(ctx context.Context, address string) error
	ListRoutes(opts *ListOptions) *RoutesIterator
	GetRoute(ctx context.Context, address string) (Route, error)
	CreateRoute(ctx context.Context, address Route) (Route, error)
	DeleteRoute(ctx context.Context, address string) error
	UpdateRoute(ctx context.Context, address string, r Route) (Route, error)
	ListWebhooks(ctx context.Context) (map[string][]string, error)
	CreateWebhook(ctx context.Context, kind string, url []string) error
	DeleteWebhook(ctx context.Context, kind string) error
	GetWebhook(ctx context.Context, kind string) ([]string, error)
	UpdateWebhook(ctx context.Context, kind string, url []string) error
	VerifyWebhookRequest(req *http.Request) (verified bool, err error)
	VerifyWebhookSignature(sig Signature) (verified bool, err error)
	ListMailingLists(opts *ListOptions) *ListsIterator
	CreateMailingList(ctx context.Context, address MailingList) (MailingList, error)
	DeleteMailingList(ctx context.Context, address string) error
	GetMailingList(ctx context.Context, address string) (MailingList, error)
	UpdateMailingList(ctx context.Context, address string, ml MailingList) (MailingList, error)
	ListMembers(address string, opts *ListOptions) *MemberListIterator
	GetMember(ctx context.Context, MemberAddr, listAddr string) (Member, error)
	CreateMember(ctx context.Context, merge bool, addr string, prototype Member) error
	CreateMemberList(ctx context.Context, subscribed *bool, addr string, newMembers []interface{}) error
	UpdateMember(ctx context.Context, Member, list string, prototype Member) (Member, error)
	DeleteMember(ctx context.Context, Member, list string) error
	ListEventsWithDomain(opts *ListEventOptions, domain string) *EventIterator
	ListEvents(*ListEventOptions) *EventIterator
	PollEvents(*ListEventOptions) *EventPoller
	ListIPS(ctx context.Context, dedicated bool) ([]IPAddress, error)
	GetIP(ctx context.Context, ip string) (IPAddress, error)
	ListDomainIPS(ctx context.Context) ([]IPAddress, error)
	AddDomainIP(ctx context.Context, ip string) error
	DeleteDomainIP(ctx context.Context, ip string) error
	ListExports(ctx context.Context, url string) ([]Export, error)
	GetExport(ctx context.Context, id string) (Export, error)
	GetExportLink(ctx context.Context, id string) (string, error)
	CreateExport(ctx context.Context, url string) error
	GetTagLimits(ctx context.Context, domain string) (TagLimits, error)
	CreateTemplate(ctx context.Context, template *Template) error
	GetTemplate(ctx context.Context, name string) (Template, error)
	UpdateTemplate(ctx context.Context, template *Template) error
	DeleteTemplate(ctx context.Context, name string) error
	ListTemplates(opts *ListTemplateOptions) *TemplatesIterator
	AddTemplateVersion(ctx context.Context, templateName string, version *TemplateVersion) error
	GetTemplateVersion(ctx context.Context, templateName, tag string) (TemplateVersion, error)
	UpdateTemplateVersion(ctx context.Context, templateName string, version *TemplateVersion) error
	DeleteTemplateVersion(ctx context.Context, templateName, tag string) error
	ListTemplateVersions(templateName string, opts *ListOptions) *TemplateVersionsIterator
}
type MailgunImpl struct {
	apiBase string
	domain  string
	apiKey  string
	client  *http.Client
	baseURL string
}
func NewMailgun(domain, apiKey string) *MailgunImpl {
	return &MailgunImpl{
		apiBase: APIBase,
		domain:  domain,
		apiKey:  apiKey,
		client:  http.DefaultClient,
	}
}
func NewMailgunFromEnv() (*MailgunImpl, error) {
	apiKey := os.Getenv("MG_API_KEY")
	if apiKey == "" {
		return nil, errors.New("required environment variable MG_API_KEY not defined")
	}
	domain := os.Getenv("MG_DOMAIN")
	if domain == "" {
		return nil, errors.New("required environment variable MG_DOMAIN not defined")
	}
	mg := NewMailgun(domain, apiKey)
	url := os.Getenv("MG_URL")
	if url != "" {
		mg.SetAPIBase(url)
	}
	return mg, nil
}
func (mg *MailgunImpl) APIBase() string {
	return mg.apiBase
}
func (mg *MailgunImpl) Domain() string {
	return mg.domain
}
func (mg *MailgunImpl) APIKey() string {
	return mg.apiKey
}
func (mg *MailgunImpl) Client() *http.Client {
	return mg.client
}
func (mg *MailgunImpl) SetClient(c *http.Client) {
	mg.client = c
}
func (mg *MailgunImpl) SetAPIBase(address string) {
	mg.apiBase = address
}
func generateApiUrl(m Mailgun, endpoint string) string {
	return fmt.Sprintf("%s/%s/%s", m.APIBase(), m.Domain(), endpoint)
}
func generateApiUrlWithDomain(m Mailgun, endpoint, domain string) string {
	return fmt.Sprintf("%s/%s/%s", m.APIBase(), domain, endpoint)
}
func generateMemberApiUrl(m Mailgun, endpoint, address string) string {
	return fmt.Sprintf("%s/%s/%s/members", m.APIBase(), endpoint, address)
}
func generateApiUrlWithTarget(m Mailgun, endpoint, target string) string {
	tail := ""
	if target != "" {
		tail = fmt.Sprintf("/%s", target)
	}
	return fmt.Sprintf("%s%s", generateApiUrl(m, endpoint), tail)
}