Giter Site home page Giter Site logo

elixir-sparkpost's Introduction

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

SparkPost Elixir Library

Travis CI Coverage Status

The official Elixir package for the SparkPost API.

Capabilities include:

  • convenience functions for easy "I just want to send mail" users
  • advanced functions for unleashing all of Sparkpost's capabilities

Installation

  1. Add sparkpost and ibrowse to your list of dependencies in mix.exs:
def deps do
  [
    {:sparkpost, "~> 0.5.1"}
  ]
end
  1. Ensure sparkpost is started before your application:
def application do
  [applications: [:sparkpost]]
end
  1. Update your dependencies:
$ mix deps.get

Usage

Configuration

In your config/config.exs file:

config :sparkpost, api_key: "YOUR-API-KEY"

Option 1: Convenience

defmodule MyApp.Example do
  def send_message do
    SparkPost.send to: "[email protected]",
         from: "[email protected]",
         subject: "Sending email from Elixir is awesome!",
         text: "Hi there!",
         html: "<p>Hi there!</p>"
  end
end

Option 2: Full SparkPost API

defmodule MyApp.Example do
  alias SparkPost.{Content, Recipient, Transmission}
  
	def send_message do
    Transmission.send(%Transmission{
        recipients: [ "[email protected]" ],
        content: %Content.Inline{
          subject: "Sending email from Elixir is awesome!",
          from: "[email protected]", 
          text: "Hi there!",
          html: "<p>Hi there!</p>"
        }
    })
  end
end

Start your app and send a message:

    $ iex -S mix
    iex> MyApp.Example.send_message
    {:ok, ...}

Contribute

We welcome your contributions! See CONTRIBUTING.md for details on how to help out.

Change Log

See ChangeLog here

elixir-sparkpost's People

Contributors

aydrian avatar davidantaramian avatar davidefedrigo avatar ewandennis avatar jasongoodwin avatar jgzamora avatar richleland avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elixir-sparkpost's Issues

More idiomatic response tuples

It'd be nice if functions returned {:error, X} and {:ok, Y}. It results in more elegant client code that doesn't have to match against specific structures.

def(%Transmission.Response{id: id), do: ...

vs

def({:ok, %{id: id}}), do: ...

Same same with case and with

Comments for initial review

The example for sending using the API doesn't work as-is. Specifically:

defmodule MyApp.Example do
  alias SparkPost.Transmission
  alias SparkPost.Recipient
  alias SparkPost.Template

  def send_message do
    Transmission.create(%Transmission{
        recipients: [ %Recipient{ address: %Sparkpost.Address{ email: "[email protected]" }} ],
        return_path: "[email protected]",
        content: %Template.Inline{
          subject: "Sending email from Elixir is awesome!",
          from: %Sparkpost.Address{ email: "[email protected]" },
          text: "Hi there!",
          html: "<p>Hi there!</p>"
        }
    })
  end
end
  • References to Sparkpost.Address should be SparkPost.Address
  • Cannot find SparkPost.Template

We should also use the new Elixir 1.2 syntax for aliases to change this:

alias SparkPost.Transmission
alias SparkPost.Recipient
alias SparkPost.Template

To this:

alias SparkPost.{Transmission, Recipient, Template}

A few other things:

Ability to send transmissions

  • support sending to one or more recipients
  • support using templates
  • support using recipient lists
  • support attachments

Request timeout

I'm experiencing timeout issues while sending mails (with attachment) and I'd like to increase the request timeout value.

HTTPotion accepts option "timeout" but looking at SparkPost.Endpoint.request it looks like it's not configurable yet. Is it something you're going to implement?

Is anyone still maintaining this?

I'm still using this library on a project or two, but over the time, I was forced to add compatibility wrappers for a lot of stuff missing here.

My PR which adds support for transmissions endpoints has been open for two years.

The upcoming changes to the transmissions API will likely end up breaking a fair chunk of what's currently still working.

Is there a way to get contributor privileges here, so I can do some maintenance myself, at least? I already tried contacting Sparkpost via the support infrastructure.

I would really like to revive this.

Update readme for 0.4.0

The readme has some formatting/indentation errors, but more importantly, it instructs the developer to install an old version of the package.

The user should be instructed to install the latest, 0.4.0.

Add support for OAuth 1.0 or decouple HTTP client from base lib

Our SparkPost server is sitting behind an OAuth 1.0 gateway on our internal network. While adding OAuth support would probably be a heavyweight approach--I wonder if there would be some way to decouple the specific HTTP client being used, for a more bring-your-own approach?

`:application.get_env(:sparkpost, :vsn)` returns undefined

Discussed with @ewandennis on Slack, but filing this ticket for reference/

What probably want is the function Application.spec(:sparkpost, :vsn)…which will query the VM for the application version number. The problem currently is that it’s not going to be in the env for the app as far as I know. Although, I’m having problems getting any specs locally for it anyways. From our corporate app:

iex(1)> Application.spec(:sparkpost, :vsn)
nil
iex(2)> Application.spec(:poison, :vsn)   
'3.0.0'
iex(3)> Application.spec(:hackney, :vsn)
'1.6.3'
iex(4)> Application.spec(:phoenix, :vsn)
'1.2.1'

This may be because the release was built on an older version of Elixir, so it didn't package the necessary metadata for this.

Remove ibrowse from README

I gathered that the library has migrated from HTTPotion to HTTPoison (#12), which relies on hackney rather than ibrowse.

I would be great if the README is updated accordingly to avoid confusing newcomers like me.

"test" mode

One of the nice things about Swoosh is the Test adapter which causes emails to be sent to the calling process. We end up with very nice tests that look like:

// do_something_that_causes_an_email_to_be_sent()
token = receive do
  {:email, msg} ->
    assert msg.subject == "Password Reset"
    %{"token" => token} = Regex.named_captures(~r/token=(?<token>[^"]+)/, msg.html_body)
    token
after
  500 -> assert false
end
// assert that token was stored in the DB

Template API

are there any plans to add support for the template API anytime soon? Noticed that the python library does - specifically looking for the "preview template" endpoint.

Would be happy to contribute if necessary!

Transmission.get no longer supported?

Version: using 0.5.1 from hex.

Actual:

iex(103)> SparkPost.Transmission.get("156823913470671414")
%SparkPost.Endpoint.Error{errors: [%{message: "You may use the Message Events API to retrieve event data for your transmission. For example https://api.sparkpost.com/api/v1/message-events?from=2018-01-05T03:00&transmission_ids=156823913470671414"}],
 results: nil, status_code: 404}

Expected:
Results like the following:

Transmission.get("102258889940193105")
#=> %Transmission{campaign_id: "",
content: %{template_id: "inline", template_version: 0,
use_draft_template: false}, description: "",
generation_end_time: "2016-01-14T12:52:05+00:00",
generation_start_time: "2016-01-14T12:52:05+00:00", id: "48215348926834924",
metadata: "", num_failed_gen: 0, num_generated: 2, num_rcpts: 2,
options: %{click_tracking: true, conversion_tracking: "", open_tracking: true},
rcp_list_total_chunks: nil, rcpt_list_chunk_size: 100, recipients: :required,
return_path: "[email protected]", state: "Success",
substitution_data: ""}

Create Transmission with "ip_pool" option

I need to define a custom ip pool, but I see this option is not implemented yet.

I'll open a pull request to add the "ip_pool" option to the module SparkPost.Transmission.Options...

HTTPoison timout option

After the migration from HTTPotion to HTTPoison, I started to get timeout errors.

It seems the meaning of (sparkpost) http_timeout slightly changed. HTTPoison handles two different timeout options:

:timeout - timeout to establish a connection, in milliseconds. Default is 8000
:recv_timeout - timeout used when receiving a connection. Default is 5000

http_timeout should be used to populate recv_timeout, but it is currently tied to timeout.

I fixed it and I'm testing it right now. No errors so far, tomorrow I'll send a PR.

Decoding HTTP Responses with Strings vs. Atoms

Is there a specific reason why the body is being decoded with keys as atoms?

  # lib/endpoint.ex:85-89@30402ea
  defp decode_response_body(body) do
    # TODO: [key: :atoms] is unsafe for open-ended structures such as
    # metadata and substitution_data
    body |> Poison.decode!([keys: :atoms])
  end

While this can be convenient, and definitely draws in Ruby's preference of symbols over strings, I feel that it unnecessarily grows the atom-space in BEAM which should be left to the determination of the end-programmer if the atom itself is not declared in-code.

"Resource not found" when previewing template

Seems the url is built incorrectly in the case of Template.preview. The url is generated as

"https://api.sparkpost.com/api/v1//templates/#{id}/preview"

Note the double dash. Should be a quick fix, so I'll submit a PR.

Prefer Dependency Injection instead of Mocking

@richleland As I was going through the requirements for change implementation for #12 I realized that the tests depend significantly on mocking the behaviour of HTTPotion. Moving forward, would you be open to preferring a dependency injection model over mocking? This is the style preferred for Elixir core components (see "Mocks and explicit contracts" – José Valim on Plataformatec Blog).

My thoughts would be to do this once #12 is complete but prior to further development.

SparkPost.Endpoint.decode_response_body/1 uses decoding as atoms

Creating this ticket so I can remove a TODO from code.

Poison.encode(keys: :atoms) is potentially unsafe for open ended structures such as metadata and substitution_data, as atoms are not garbage collected and are a definite (albeit often slow) memory leak. Substitution data and metadata should be decoded into a string keys map.

Update readme version

Might want to update your readme to include the latest version, changing:

{:sparkpost, "~> 0.1.0"}

to

{:sparkpost, "~> 0.2.1"}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.