gosparkpost

package module
v0.0.0-...-8508aec Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2016 License: Apache-2.0 Imports: 16 Imported by: 0

README

.. image:: https://www.sparkpost.com/sites/default/files/attachments/SparkPost_Logo_2-Color_Gray-Orange_RGB.svg
    :target: https://www.sparkpost.com
    :width: 200px

`Sign up`_ for a SparkPost account and visit our `Developer Hub`_ for even more content.

.. _Sign up: https://app.sparkpost.com/sign-up?src=Dev-Website&sfdcid=70160000000pqBb
.. _Developer Hub: https://developers.sparkpost.com

SparkPost Go API client
=======================

.. image:: http://slack.sparkpost.com/badge.svg
    :target: http://slack.sparkpost.com
    :alt: Slack Community

The official Go package for using the SparkPost API.

Installation
------------

Install from GitHub using `go get`_:

.. code-block:: bash

    $ go get github.com/SparkPost/gosparkpost

.. _go get: https://golang.org/cmd/go/#hdr-Download_and_install_packages_and_dependencies

Get a key
---------

Go to `API & SMTP`_ in the SparkPost app and create an API key. We recommend using the ``SPARKPOST_API_KEY`` environment variable. The example code below shows how to set this up.

.. _API & SMTP: https://app.sparkpost.com/#/configuration/credentials

Send a message
--------------

Here at SparkPost, our "send some messages" api is called the `transmissions API`_ - let's use it to send a friendly test message:

.. code-block:: go

    package main

    import (
      "log"
      "os"

      sp "github.com/SparkPost/gosparkpost"
    )

    func main() {
      // Get our API key from the environment; configure.
      apiKey := os.Getenv("SPARKPOST_API_KEY")
      cfg := &sp.Config{
        BaseUrl:    "https://api.sparkpost.com",
        ApiKey:     apiKey,
        ApiVersion: 1,
      }
      var client sp.Client
      err := client.Init(cfg)
      if err != nil {
        log.Fatalf("SparkPost client init failed: %s\n", err)
      }

      // Create a Transmission using an inline Recipient List
      // and inline email Content.
      tx := &sp.Transmission{
        Recipients: []string{"someone@somedomain.com"},
        Content: sp.Content{
          HTML:    "<p>Hello world</p>",
          From:    "test@sparkpostbox.com",
          Subject: "Hello from gosparkpost",
        },
      }
      id, _, err := client.Send(tx)
      if err != nil {
        log.Fatal(err)
      }

      // The second value returned from Send
      // has more info about the HTTP response, in case
      // you'd like to see more than the Transmission id.
      log.Printf("Transmission sent with id [%s]\n", id)
    }

.. _transmissions API: https://www.sparkpost.com/api#/reference/transmissions

Documentation
-------------

* `SparkPost API Reference`_
* `Code samples`_
* `Command-line tool: sparks`_

.. _SparkPost API Reference: https://www.sparkpost.com/api
.. _Code samples: examples/README.md
.. _Command-line tool\: sparks: cmd/sparks/README.md

Contribute
----------

TL;DR:

#. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
#. Fork `the repository`_.
#. Go get the original code - ``go get https://github.com/SparkPost/gosparkpost``
#. Add your fork as a remote - ``git remote add fork http://github.com/YOURID/gosparkpost``
#. Make your changes in a branch on your fork
#. Write a test which shows that the bug was fixed or that the feature works as expected.
#. Push your changes - ``git push fork HEAD``
#. Send a pull request. Make sure to add yourself to AUTHORS_.

More on the `contribution process`_

.. _`the repository`: https://github.com/SparkPost/gosparkpost
.. _AUTHORS: AUTHORS.rst
.. _`contribution process`: CONTRIBUTING.md

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrEmptyPage = errors.New("empty page")
)

https://www.sparkpost.com/api#/reference/message-events

Functions

func ParseContent

func ParseContent(content interface{}) (err error)

ParseContent asserts that Transmission.Content is valid.

func ParseEvents

func ParseEvents(rawEventsPtr []*json.RawMessage) (*[]events.Event, error)

ParseEvents function is left only for backward-compatibility. Events are parsed by events pkg.

func ParseRecipients

func ParseRecipients(recips interface{}) (ra *[]Recipient, err error)

ParseRecipients asserts that Transmission.Recipients is valid.

Types

type Address

type Address struct {
	Email    string `json:"email"`
	Name     string `json:"name,omitempty"`
	HeaderTo string `json:"header_to,omitempty"`
}

Address describes the nested object way of specifying the Recipient's email address. Recipient.Address can also be a plain string.

func ParseAddress

func ParseAddress(addr interface{}) (a Address, err error)

ParseAddress parses the various allowable Content.From values.

type Attachment

type Attachment struct {
	MIMEType string `json:"type"`
	Filename string `json:"name"`
	B64Data  string `json:"data"`
}

Attachment contains metadata and the contents of the file to attach.

type Client

type Client struct {
	Config *Config
	Client *http.Client
	// contains filtered or unexported fields
}

Client contains connection and authentication information. Specifying your own http.Client gives you lots of control over how connections are made.

func (*Client) DoRequest

func (c *Client) DoRequest(method, urlStr string, data []byte) (*Response, error)

func (*Client) EventSamples

func (c *Client) EventSamples(types *[]string) (*events.Events, error)

Samples requests a list of example event data.

func (*Client) HttpDelete

func (c *Client) HttpDelete(url string) (*Response, error)

HttpDelete sends a Delete request to the provided url. Query params are supported via net/url - roll your own and stringify it. Authenticate using the configured API key.

func (*Client) HttpGet

func (c *Client) HttpGet(url string) (*Response, error)

HttpGet sends a Get request to the specified url. Query params are supported via net/url - roll your own and stringify it. Authenticate using the configured API key.

func (*Client) HttpPost

func (c *Client) HttpPost(url string, data []byte) (*Response, error)

HttpPost sends a Post request with the provided JSON payload to the specified url. Query params are supported via net/url - roll your own and stringify it. Authenticate using the configured API key.

func (*Client) HttpPut

func (c *Client) HttpPut(url string, data []byte) (*Response, error)

HttpPut sends a Put request with the provided JSON payload to the specified url. Query params are supported via net/url - roll your own and stringify it. Authenticate using the configured API key.

func (*Client) Init

func (api *Client) Init(cfg *Config) error

Init pulls together everything necessary to make an API request. Caller may provide their own http.Client by setting it in the provided API object.

func (*Client) MetricEventAsString

func (c *Client) MetricEventAsString(e *DeliverabilityMetricItem) string

func (*Client) RecipientListCreate

func (c *Client) RecipientListCreate(rl *RecipientList) (id string, res *Response, err error)

Create accepts a populated RecipientList object, validates it, and performs an API call against the configured endpoint.

func (*Client) RecipientLists

func (c *Client) RecipientLists() (*[]RecipientList, *Response, error)

func (*Client) RemoveHeader

func (c *Client) RemoveHeader(header string)

Removes header set in SetHeader function

func (*Client) Send

func (c *Client) Send(t *Transmission) (id string, res *Response, err error)

Create accepts a populated Transmission object, performs basic sanity checks on it, and performs an API call against the configured endpoint. Calling this function can cause email to be sent, if used correctly.

func (*Client) SetHeader

func (c *Client) SetHeader(header string, value string)

SetHeader adds additional HTTP headers for every API request made from client. Usefull to set subaccount X-MSYS-SUBACCOUNT header and etc.

func (*Client) Subaccount

func (c *Client) Subaccount(id int) (subaccount *Subaccount, res *Response, err error)

func (*Client) SubaccountCreate

func (c *Client) SubaccountCreate(s *Subaccount) (res *Response, err error)

Create accepts a populated Subaccount object, validates it, and performs an API call against the configured endpoint.

func (*Client) SubaccountUpdate

func (c *Client) SubaccountUpdate(s *Subaccount) (res *Response, err error)

Update updates a subaccount with the specified id. Actually it will marshal and send all the subaccount fields, but that must not be a problem, as fields not supposed for update will be omitted

func (*Client) Subaccounts

func (c *Client) Subaccounts() (subaccounts []Subaccount, res *Response, err error)

List returns metadata for all Templates in the system.

func (*Client) SuppressionDelete

func (c *Client) SuppressionDelete(recipientEmail string) (res *Response, err error)

func (*Client) SuppressionInsertOrUpdate

func (c *Client) SuppressionInsertOrUpdate(entries []SuppressionEntry) (err error)

func (*Client) SuppressionList

func (c *Client) SuppressionList() (*SuppressionListWrapper, error)

func (*Client) SuppressionRetrieve

func (c *Client) SuppressionRetrieve(recipientEmail string) (*SuppressionListWrapper, error)

func (*Client) SuppressionSearch

func (c *Client) SuppressionSearch(parameters map[string]string) (*SuppressionListWrapper, error)

func (*Client) TemplateCreate

func (c *Client) TemplateCreate(t *Template) (id string, res *Response, err error)

Create accepts a populated Template object, validates its Contents, and performs an API call against the configured endpoint.

func (*Client) TemplateDelete

func (c *Client) TemplateDelete(id string) (res *Response, err error)

Delete removes the Template with the specified id.

func (*Client) TemplatePreview

func (c *Client) TemplatePreview(id string, payload *PreviewOptions) (res *Response, err error)

func (*Client) TemplateUpdate

func (c *Client) TemplateUpdate(t *Template) (res *Response, err error)

Update updates a draft/published template with the specified id

func (*Client) Templates

func (c *Client) Templates() ([]Template, *Response, error)

List returns metadata for all Templates in the system.

func (*Client) Transmission

func (c *Client) Transmission(id string) (*Transmission, *Response, error)

Retrieve accepts a Transmission.ID and retrieves the corresponding object.

func (*Client) TransmissionDelete

func (c *Client) TransmissionDelete(id string) (*Response, error)

Delete attempts to remove the Transmission with the specified id. Only Transmissions which are scheduled for future generation may be deleted.

func (*Client) Transmissions

func (c *Client) Transmissions(campaignID, templateID *string) ([]Transmission, *Response, error)

List returns Transmission summary information for matching Transmissions. To skip filtering by campaign or template id, use a nil param.

type Config

type Config struct {
	BaseUrl    string
	ApiKey     string
	Username   string
	Password   string
	ApiVersion int
	Verbose    bool
}

Config includes all information necessary to make an API request.

func NewConfig

func NewConfig(m map[string]string) (*Config, error)

NewConfig builds a Config object using the provided map.

type Content

type Content struct {
	HTML         string            `json:"html,omitempty"`
	Text         string            `json:"text,omitempty"`
	Subject      string            `json:"subject,omitempty"`
	From         interface{}       `json:"from,omitempty"`
	ReplyTo      string            `json:"reply_to,omitempty"`
	Headers      map[string]string `json:"headers,omitempty"`
	EmailRFC822  string            `json:"email_rfc822,omitempty"`
	Attachments  []Attachment      `json:"attachments,omitempty"`
	InlineImages []InlineImage     `json:"inline_images,omitempty"`
}

Content is what you'll send to your Recipients. Knowledge of SparkPost's substitution/templating capabilities will come in handy here. https://www.sparkpost.com/api#/introduction/substitutions-reference

type DeliverabilityMetricEventsWrapper

type DeliverabilityMetricEventsWrapper struct {
	Results    []*DeliverabilityMetricItem `json:"results,omitempty"`
	TotalCount int                         `json:"total_count,omitempty"`
	Links      []map[string]string         `json:"links,omitempty"`
	Errors     []interface{}               `json:"errors,omitempty"`
}

type DeliverabilityMetricItem

type DeliverabilityMetricItem struct {
	CountInjected               int    `json:"count_injected"`
	CountBounce                 int    `json:"count_bounce,omitempty"`
	CountRejected               int    `json:"count_rejected,omitempty"`
	CountDelivered              int    `json:"count_delivered,omitempty"`
	CountDeliveredFirst         int    `json:"count_delivered_first,omitempty"`
	CountDeliveredSubsequent    int    `json:"count_delivered_subsequent,omitempty"`
	TotalDeliveryTimeFirst      int    `json:"total_delivery_time_first,omitempty"`
	TotalDeliveryTimeSubsequent int    `json:"total_delivery_time_subsequent,omitempty"`
	TotalMsgVolume              int    `json:"total_msg_volume,omitempty"`
	CountPolicyRejection        int    `json:"count_policy_rejection,omitempty"`
	CountGenerationRejection    int    `json:"count_generation_rejection,omitempty"`
	CountGenerationFailed       int    `json:"count_generation_failed,omitempty"`
	CountInbandBounce           int    `json:"count_inband_bounce,omitempty"`
	CountOutofbandBounce        int    `json:"count_outofband_bounce,omitempty"`
	CountSoftBounce             int    `json:"count_soft_bounce,omitempty"`
	CountHardBounce             int    `json:"count_hard_bounce,omitempty"`
	CountBlockBounce            int    `json:"count_block_bounce,omitempty"`
	CountAdminBounce            int    `json:"count_admin_bounce,omitempty"`
	CountUndeterminedBounce     int    `json:"count_undetermined_bounce,omitempty"`
	CountDelayed                int    `json:"count_delayed,omitempty"`
	CountDelayedFirst           int    `json:"count_delayed_first,omitempty"`
	CountRendered               int    `json:"count_rendered,omitempty"`
	CountUniqueRendered         int    `json:"count_unique_rendered,omitempty"`
	CountUniqueConfirmedOpened  int    `json:"count_unique_confirmed_opened,omitempty"`
	CountClicked                int    `json:"count_clicked,omitempty"`
	CountUniqueClicked          int    `json:"count_unique_clicked,omitempty"`
	CountTargeted               int    `json:"count_targeted,omitempty"`
	CountSent                   int    `json:"count_sent,omitempty"`
	CountAccepted               int    `json:"count_accepted,omitempty"`
	CountSpamComplaint          int    `json:"count_spam_complaint,omitempty"`
	Domain                      string `json:"domain,omitempty"`
	CampaignId                  string `json:"campaign_id,omitempty"`
	TemplateId                  string `json:"template_id,omitempty"`
	TimeStamp                   string `json:"ts,omitempty"`
	WatchedDomain               string `json:"watched_domain,omitempty"`
	Binding                     string `json:"binding,omitempty"`
	BindingGroup                string `json:"binding_group,omitempty"`
}

type Error

type Error struct {
	Message     string `json:"message"`
	Code        string `json:"code"`
	Description string `json:"description"`
	Part        string `json:"part,omitempty"`
	Line        int    `json:"line,omitempty"`
}

Error mirrors the error format returned by SparkPost APIs.

func (Error) Json

func (e Error) Json() (string, error)

type EventsPage

type EventsPage struct {
	Events     events.Events
	TotalCount int
	// contains filtered or unexported fields
}

func (*EventsPage) Next

func (events *EventsPage) Next() (*EventsPage, error)

func (*EventsPage) UnmarshalJSON

func (ep *EventsPage) UnmarshalJSON(data []byte) error

type From

type From struct {
	Email string
	Name  string
}

From describes the nested object way of specifying the From header. Content.From can be specified this way, or as a plain string.

func ParseFrom

func ParseFrom(from interface{}) (f From, err error)

ParseFrom parses the various allowable Content.From values.

type InlineImage

type InlineImage Attachment

InlineImage contains metadata and the contents of the image to make available for inline use.

type PreviewOptions

type PreviewOptions struct {
	SubstitutionData map[string]interface{} `json:"substitution_data"`
}

Preview options contains the required subsitution_data object to preview a template

type RFC3339

type RFC3339 time.Time

func (*RFC3339) MarshalJSON

func (r *RFC3339) MarshalJSON() ([]byte, error)

type Recipient

type Recipient struct {
	Address          interface{} `json:"address"`
	ReturnPath       string      `json:"return_path,omitempty"`
	Tags             []string    `json:"tags,omitempty"`
	Metadata         interface{} `json:"metadata,omitempty"`
	SubstitutionData interface{} `json:"substitution_data,omitempty"`
}

Recipient represents one email (you guessed it) recipient.

func (Recipient) Validate

func (r Recipient) Validate() error

Validate runs sanity checks on a Recipient struct. This should catch most errors before attempting a doomed API call.

type RecipientList

type RecipientList struct {
	ID          string       `json:"id,omitempty"`
	Name        string       `json:"name,omitempty"`
	Description string       `json:"description,omitempty"`
	Attributes  interface{}  `json:"attributes,omitempty"`
	Recipients  *[]Recipient `json:"recipients"`

	Accepted *int `json:"total_accepted_recipients,omitempty"`
}

RecipientList is the JSON structure accepted by and returned from the SparkPost Recipient Lists API. It's mostly metadata at this level - see Recipients for more detail.

func (*RecipientList) String

func (rl *RecipientList) String() string

func (*RecipientList) Validate

func (rl *RecipientList) Validate() error

Validate runs sanity checks on a RecipientList struct. This should catch most errors before attempting a doomed API call.

type Response

type Response struct {
	HTTP    *http.Response
	Body    []byte
	Verbose map[string]string
	Results map[string]interface{} `json:"results,omitempty"`
	Errors  []Error                `json:"errors,omitempty"`
}

Response contains information about the last HTTP response. Helpful when an error message doesn't necessarily give the complete picture. Also contains any messages emitted as a result of the Verbose config option.

func (*Response) AssertJson

func (r *Response) AssertJson() error

AssertJson returns an error if the provided HTTP response isn't JSON.

func (*Response) ParseResponse

func (r *Response) ParseResponse() error

ParseResponse pulls info from JSON http responses into api.Response object. It's helpful to call Response.AssertJson before calling this function.

func (*Response) PrettyError

func (r *Response) PrettyError(noun, verb string) error

PrettyError returns a human-readable error message for common http errors returned by the API. The string parameters are used to customize the generated error message (example: noun=template, verb=create).

func (*Response) ReadBody

func (r *Response) ReadBody() ([]byte, error)

ReadBody is a convenience method that returns the http.Response body. The first time this function is called, the body is read from the http.Response. For subsequent calls, the cached version in Response.Body is returned.

type Subaccount

type Subaccount struct {
	ID               int      `json:"subaccount_id,omitempty"`
	Name             string   `json:"name,omitempty"`
	Key              string   `json:"key,omitempty"`
	KeyLabel         string   `json:"key_label,omitempty"`
	Grants           []string `json:"key_grants,omitempty"`
	ShortKey         string   `json:"short_key,omitempty"`
	Status           string   `json:"status,omitempty"`
	ComplianceStatus string   `json:"compliance_status,omitempty"`
}

Subaccount is the JSON structure accepted by and returned from the SparkPost Subaccounts API.

type SuppressionEntry

type SuppressionEntry struct {
	// Email is used when list is stored
	Email string `json:"email,omitempty"`

	// Recipient is used when a list is returned
	Recipient string `json:"recipient,omitempty"`

	Transactional    bool   `json:"transactional,omitempty"`
	NonTransactional bool   `json:"non_transactional,omitempty"`
	Source           string `json:"source,omitempty"`
	Description      string `json:"description,omitempty"`
	Updated          string `json:"updated,omitempty"`
	Created          string `json:"created,omitempty"`
}

type SuppressionListWrapper

type SuppressionListWrapper struct {
	Results    []*SuppressionEntry `json:"results,omitempty"`
	Recipients []SuppressionEntry  `json:"recipients,omitempty"`
}

type Template

type Template struct {
	ID          string       `json:"id,omitempty"`
	Content     Content      `json:"content,omitempty"`
	Published   bool         `json:"published,omitempty"`
	Name        string       `json:"name,omitempty"`
	Description string       `json:"description,omitempty"`
	LastUse     time.Time    `json:"last_use,omitempty"`
	LastUpdate  time.Time    `json:"last_update_time,omitempty"`
	Options     *TmplOptions `json:"options,omitempty"`
}

Template is the JSON structure accepted by and returned from the SparkPost Templates API. It's mostly metadata at this level - see Content and Options for more detail.

Example

Build a native Go Template structure from a JSON string

package main

import (
	"encoding/json"
	"log"

	sp "github.com/SparkPost/gosparkpost"
)

func main() {
	template := &sp.Template{}
	jsonStr := `{
		"name": "testy template",
		"content": {
			"html": "this is a <b>test</b> email!",
			"subject": "test email",
			"from": {
				"name": "tester",
				"email": "tester@example.com"
			},
			"reply_to": "tester@example.com"
		}
	}`
	err := json.Unmarshal([]byte(jsonStr), template)
	if err != nil {
		log.Fatal(err)
	}
}
Output:

func (*Template) SetHeaders

func (t *Template) SetHeaders(headers map[string]string)

SetHeaders is a convenience method which sets Template.Content.Headers to the provided map.

func (*Template) Validate

func (t *Template) Validate() error

Validate runs sanity checks on a Template struct. This should catch most errors before attempting a doomed API call.

type TmplOptions

type TmplOptions struct {
	OpenTracking  bool `json:"open_tracking"`
	ClickTracking bool `json:"click_tracking"`
	Transactional bool `json:"transactional"`
}

Options specifies settings to apply to this Template. These settings may be overridden in the Transmission API call.

type Transmission

type Transmission struct {
	ID               string      `json:"id,omitempty"`
	State            string      `json:"state,omitempty"`
	Options          *TxOptions  `json:"options,omitempty"`
	Recipients       interface{} `json:"recipients"`
	CampaignID       string      `json:"campaign_id,omitempty"`
	Description      string      `json:"description,omitempty"`
	Metadata         interface{} `json:"metadata,omitempty"`
	SubstitutionData interface{} `json:"substitution_data,omitempty"`
	ReturnPath       string      `json:"return_path,omitempty"`
	Content          interface{} `json:"content"`

	TotalRecipients      *int `json:"total_recipients,omitempty"`
	NumGenerated         *int `json:"num_generated,omitempty"`
	NumFailedGeneration  *int `json:"num_failed_generation,omitempty"`
	NumInvalidRecipients *int `json:"num_invalid_recipients,omitempty"`
}

Transmission is the JSON structure accepted by and returned from the SparkPost Transmissions API.

func (*Transmission) Validate

func (t *Transmission) Validate() error

Validate runs sanity checks of a Transmission struct. This should catch most errors before attempting a doomed API call.

type TxOptions

type TxOptions struct {
	TmplOptions

	StartTime       *RFC3339 `json:"start_time,omitempty"`
	Sandbox         string   `json:"sandbox,omitempty"`
	SkipSuppression string   `json:"skip_suppression,omitempty"`
	InlineCSS       bool     `json:"inline_css,omitempty"`
}

Options specifies settings to apply to this Transmission. If not specified, and present in TmplOptions, those values will be used.

type WebhookItem

type WebhookItem struct {
	ID       string   `json:"id,omitempty"`
	Name     string   `json:"name,omitempty"`
	Target   string   `json:"target,omitempty"`
	Events   []string `json:"events,omitempty"`
	AuthType string   `json:"auth_type,omitempty"`

	AuthRequestDetails struct {
		URL  string `json:"url,omitempty"`
		Body struct {
			ClientID     string `json:"client_id,omitempty"`
			ClientSecret string `json:"client_secret,omitempty"`
		} `json:"body,omitempty"`
	} `json:"auth_request_details,omitempty"`

	AuthCredentials struct {
		Username    string `json:"username,omitempty"`
		Password    string `json:"password,omitempty"`
		AccessToken string `json:"access_token,omitempty"`
		ExpiresIn   int    `json:"expires_in,omitempty"`
	} `json:"auth_credentials,omitempty"`

	AuthToken      string `json:"auth_token,omitempty"`
	LastSuccessful string `json:"last_successful,omitempty,omitempty"`
	LastFailure    string `json:"last_failure,omitempty,omitempty"`

	Links []struct {
		Href   string   `json:"href,omitempty"`
		Rel    string   `json:"rel,omitempty"`
		Method []string `json:"method,omitempty"`
	} `json:"links,omitempty"`
}

type WebhookListWrapper

type WebhookListWrapper struct {
	Results []*WebhookItem `json:"results,omitempty"`
	Errors  []interface{}  `json:"errors,omitempty"`
}

type WebhookQueryWrapper

type WebhookQueryWrapper struct {
	Results *WebhookItem  `json:"results,omitempty"`
	Errors  []interface{} `json:"errors,omitempty"`
}

type WebhookStatus

type WebhookStatus struct {
	BatchID      string `json:"batch_id,omitempty"`
	Ts           string `json:"ts,omitempty"`
	Attempts     int    `json:"attempts,omitempty"`
	ResponseCode string `json:"response_code,omitempty"`
}

type WebhookStatusWrapper

type WebhookStatusWrapper struct {
	Results []*WebhookStatus `json:"results,omitempty"`
	Errors  []interface{}    `json:"errors,omitempty"`
}

Directories

Path Synopsis
cmd
qp
sparks
Sparks is a command-line tool for quickly sending email using SparkPost.
Sparks is a command-line tool for quickly sending email using SparkPost.
Package events defines a struct for each type of event and provides various other helper functions.
Package events defines a struct for each type of event and provides various other helper functions.
examples
cc
helpers

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL