Giter Club home page Giter Club logo

lua-mailgun's Introduction

mailgun

test

A Lua library for sending emails and interacting with the Mailgun API. Compatible with OpenResty via Lapis HTTP API, or any other Lua script via LuaSocket.

At the moment this library only implements a subset of the API. If there's an missing API method feel free to open an issue.

Example

local Mailgun = require("mailgun").Mailgun

local m = Mailgun({
  domain = "leafo.net",
  api_key = "api:key-blah-blah-blahblah"
})

m:send_email({
  to = "[email protected]",
  subject = "Important message here",
  html = true,
  body = [[
    <h1>Hello world</h1>
    <p>Here is my email to you.</p>
    <hr />
    <p>
      <a href="%unsubscribe_url%">Unsubscribe</a>
    </p>
  ]]
})

Install

luarocks install mailgun

Reference

The Mailgun constructor can be used to create a new client to Mailgun. It's found in the mailgun module.

local Mailgun = require("mailgun").Mailgun

local m = Mailgun({
  domain = "leafo.net",
  api_key = "api:key-blah-blah-blahblah"
})

The following options are valid:

  • domain - the domain to use for API requests (required)
  • api_key - the API key to authenticate requests (required)
  • webhook_signing_key - key used for webhook signature verification, defaults to api key without username (optional)
  • default_sender - the sender to use for send_email when a sender is not provided (optional)
  • http - set the HTTP client (optional)

The value of default_sender has a default created from the domain like this: {domain} <postmaster@{domain}>.

HTTP Client

If a HTTP client is not specified, this library will pick lapis.nginx.http when inside of Nginx (OpenResty), otherwise it will fall back on ssl.https (LuaSocket & LuaSec)

The client can be changed by providing an http option to the constructor. If a string is passed, it will be required as a module name. For example, you can use lua-http by passing in http = "http.compat.socket"

Alternatively, a function can be passed in. The function will be called once and the return value will be used as the http module. (It should be a table with a request function that works like LuaSocket)

Methods

mailgun:send_email(opts={})

The following are required options:

  • to - the recipient(s) of the email. Pass an array table to send to multiple recipients
  • subject - the subject line of the email
  • body - the body of the email

Optional fields:

  • from - the sender of the email (default: {domain} <postmaster@{domain}>)
  • html - set to true to send email as HTML (default false)
  • domain - use a different domain than the default
  • cc - recipients to cc to, same format as to
  • bcc - recipients to bcc to, same format as to
  • track_opens - track the open rate fo the email (default false)
  • tags - an array table of tags to apply to message
  • vars - table of recipient specific variables where the key is the recipient and value is a table of vars
  • headers - a table of additional headers to provide
  • campaign - the campaign id of the campaign the email is part of (see get_or_create_campaign_id)
  • v:{NAME} - add any number of user variables with the name {NAME}, ie. v:user_id
Recipient variables

Using recipient variables you can bulk send many emails in a single API call. You can parameterize your email address with different variables for each recipient:

local vars = {
  ["[email protected]"] = {
    username = "L.E.A.F.",
    profile_url = "http://example.com/leafo",
  },
  ["[email protected]"] = {
    username = "Adumb",
    profile_url = "http://example.com/adam",
  }
}

mailgun:send_email({
  to = {"[email protected]", "[email protected]"},
  vars = vars,
  subject = "Hey check it out!",
  body = [[
    Hello %recipient.username%,
    We just updated your profile page. Check it out: %recipient.profile_url%
  ]]
})
Setting reply-to email

Pass the Reply-To header:

mailgun:send_email({
  to = "[email protected]",
  subject = "Hey check it out!",
  from = "Postmaster <[email protected]>",
  headers = {
    ["Reply-To"] = "[email protected]"
  },
  body = [[
    Thanks for downloading our game, reply if you have any questions!
  ]]
})

mailgun:create_campaign(name)

Creates a new campaign named name. Returns the campaign object

campaigns = mailgun:get_campaigns()

Gets all the campaigns that are available

mailgun:get_or_create_campaign_id(name)

Gets a campaign id for a campaign by name. If it doesn't exist yet a new one is created.

messages, paging = mailgun:get_messages()

Gets the first page of stored messages (this uses the events API). The paging object includes the urls for fetching subsequent pages.

unsubscribes, paging = mailgun:get_unsubscribes(opts={})

https://documentation.mailgun.com/api-suppressions.html#unsubscribes

Gets the first page of unsubscribes messages. opts is passed as query string parameters.

iter = mailgun:each_event(filter_params={})

https://documentation.mailgun.com/en/latest/api-events.html

Iterates through each event, lazily fetching pages of events as needed. In order to stop processing events before all of them have been traversed use break to exit the loop.

for e in mailgun:each_unsubscribe() do
  print(e.event)
end

Each event is a plain Lua table with the same format provided by the API : https://documentation.mailgun.com/en/latest/api-events.html#event-structure

Uses limit of 300 by default, which will fetch 300 events at a time for each page.

result = mailgun:get_events(params={})

https://documentation.mailgun.com/en/latest/api-events.html

Issues API call to GET /<domain>/events with provided parameters. If you want to iterate over events see each_event.

iter = mailgun:each_unsubscribe()

Iterates through each message (fetching each page as needed)

for unsub in mailgun:each_unsubscribe() do
  print(unsub.address)
end

bounces, paging = mailgun:get_bounces(opts={})

https://documentation.mailgun.com/api-suppressions.html#bounces

Gets the first page of unsubscribes bounces. opts is passed as query string parameters.

iter = mailgun:each_bounce()

Iterates through each bounce (fetching each page as needed). Similar to get_unsubscribes.

complaints, paging = mailgun:get_complaints(opts={})

https://documentation.mailgun.com/api-suppressions.html#view-all-complaints

Gets the first page of complaints messages. opts is passed as query string parameters.

iter = mailgun:each_complaint()

Iterates through each complaint (fetching each page as needed). Similar to get_unsubscribes.

new_mailgun = mailgun:for_domain(domain)

Returns a new instance of the API client configured the same way, but with the domain replaced with the provided domain. If you have multiple domains on your account you can use this to switch to them for any of the get_ methods.

mailgun:verify_webhook_signature(timestamp, token, signature)

Verify signature of a webhook call using the stored API key as described here: https://documentation.mailgun.com/en/latest/user_manual.html#webhooks

Returns true if the signature is validated, otherwise returns nil and an error message.

If any of the arguments aren't provided, an error is thrown.

mailgun:validate_email(email_address)

Look up email using the email validation service described here: https://documentation.mailgun.com/en/latest/api-email-validation.html#email-validation

Returns a Lua object with results of validation

Changelog

Changelog now available on GitHub releases: https://github.com/leafo/lua-mailgun/releases

License (MIT)

Copyright (C) 2022 by Leaf Corcoran

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

lua-mailgun's People

Contributors

leafo avatar vadi2 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

lua-mailgun's Issues

Cannot find Mailgun.Util

After building and installing the latest Mailgun from the LuaRocks Repo, I'm getting the below issue:

C:\Lua\share\lua\5.1\mailgun\init.lua:4: module 'mailgun.util' not found: no field package.preload['mailgun.util'] no file 'C:\Program Files (x86)\LuaRocks\lua\mailgun\util.lua' no file 'C:\Program Files (x86)\LuaRocks\lua\mailgun\util\init.lua' no file 'C:\Users\gelada.CUBO\AppData\Roaming\LuaRocks\share\lua\5.1\mailgun\util.lua' no file 'C:\Users\gelada.CUBO\AppData\Roaming\LuaRocks\share\lua\5.1\mailgun\util\init.lua' no file 'C:\Lua\share\lua\5.1\mailgun\util.lua' no file 'C:\Lua\share\lua\5.1\mailgun\util\init.lua' no file 'C:\Users\gelada.CUBO\AppData\Roaming\LuaRocks\lib\lua\5.1\mailgun\util.dll' no file 'C:\Lua\lib\lua\5.1\mailgun\util.dll' no file 'C:\Users\gelada.CUBO\AppData\Roaming\LuaRocks\lib\lua\5.1\mailgun.dll' no file 'C:\Lua\lib\lua\5.1\mailgun.dll' stack traceback: [C]: in function 'require' C:\Lua\share\lua\5.1\mailgun\init.lua:4: in main chunk [C]: in function 'require' stdin:1: in main chunk [C]: ?

Can you let me know if it's a problem my end?
Had this on 2 separate machines.

Thanks.

Include license file or text

I see that in the rockspec you're calling this MIT licensed, can you include an actual file or put the license text in the source somewhere?

"failed to adjust the subrequest" when sending an email

Given this code:

    local Mailgun = require("mailgun").Mailgun
    print(inspect(init))
    print(inspect(message))

    local m = Mailgun(init)
    m:send_email(message)

Gives this log:

package-repo_1  | 2020/05/23 12:56:27 [notice] 16#16: *4 [lua] mail.lua:39: send(): {
package-repo_1  |   api_key = "<legitimate key here>",
package-repo_1  |   domain = "mudlet.org"
package-repo_1  | }, client: 172.21.0.1, server: , request: "POST /register HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/register"
package-repo_1  | 2020/05/23 12:56:27 [notice] 16#16: *4 [lua] mail.lua:40: send(): {
package-repo_1  |   body = "Hello Vadi3. In order to verify your email address for your account with Mudlet Package Repository (experimental), please visit http://localhost:8080/verifyemail?ver_code=b6f12d02-bbf7-4cc9-ba4f-888cd79c0dbe&[email protected]\n\nIf that url does not work, visit http://localhost:8080/verifyemail and enter your email address and the verification code b6f12d02-bbf7-4cc9-ba4f-888cd79c0dbe .",
package-repo_1  |   from = "[email protected]",
package-repo_1  |   html = true,
package-repo_1  |   http = "http.compat.socket",
package-repo_1  |   subject = "Please verify your email address with Mudlet Package Repository (experimental)",
package-repo_1  |   to = "Vadi3 <[email protected]>"
package-repo_1  | }, client: 172.21.0.1, server: , request: "POST /register HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/register"
package-repo_1  | 2020/05/23 12:56:27 [error] 16#16: *4 variable "_url" cannot be assigned a value (maybe you forgot to define it first?) , client: 172.21.0.1, server: , request: "POST /register HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/register"
package-repo_1  | 2020/05/23 12:56:27 [error] 16#16: *4 lua coroutine: runtime error: /usr/local/share/lua/5.1/lapis/nginx/http.lua:94: failed to adjust the subrequest: -1
package-repo_1  | stack traceback:
package-repo_1  | coroutine 0:
package-repo_1  | 	[C]: in function 'capture'
package-repo_1  | 	/usr/local/share/lua/5.1/lapis/nginx/http.lua:94: in function 'request'
package-repo_1  | 	/usr/local/share/lua/5.1/mailgun/init.lua:96: in function 'send_email'
package-repo_1  | 	./controllers/mail.lua:43: in function 'send'
package-repo_1  | 	./controllers/mail.lua:53: in function 'send_verification'

The variable "_url" cannot be assigned a value (maybe you forgot to define it first?) bit looks suspicious, but a scan of the code showed url being defined fine.

Using lua-http as the http provider didn't help either.

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.