{"id":13778734,"url":"https://github.com/leafo/lua-mailgun","last_synced_at":"2026-03-01T17:36:01.875Z","repository":{"id":66222848,"uuid":"51226001","full_name":"leafo/lua-mailgun","owner":"leafo","description":"Lua bindings to Mailgun HTTP API","archived":false,"fork":false,"pushed_at":"2022-04-08T17:09:28.000Z","size":47,"stargazers_count":25,"open_issues_count":2,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-06-04T04:23:07.956Z","etag":null,"topics":["lua","mailgun","moonscript","openresty"],"latest_commit_sha":null,"homepage":null,"language":"MoonScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leafo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-02-06T22:51:31.000Z","updated_at":"2025-05-27T06:56:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"07a79cce-b31d-4425-bae3-25762fd6f26b","html_url":"https://github.com/leafo/lua-mailgun","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/leafo/lua-mailgun","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flua-mailgun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flua-mailgun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flua-mailgun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flua-mailgun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leafo","download_url":"https://codeload.github.com/leafo/lua-mailgun/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flua-mailgun/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29976279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T16:35:47.903Z","status":"ssl_error","status_checked_at":"2026-03-01T16:35:44.899Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lua","mailgun","moonscript","openresty"],"created_at":"2024-08-03T18:00:56.907Z","updated_at":"2026-03-01T17:36:01.520Z","avatar_url":"https://github.com/leafo.png","language":"MoonScript","readme":"# mailgun\n\n![test](https://github.com/leafo/lua-mailgun/workflows/test/badge.svg)\n\nA Lua library for sending emails and interacting with the\n[Mailgun](https://mailgun.com/) API. Compatible with OpenResty via Lapis HTTP\nAPI, or any other Lua script via LuaSocket.\n\n*At the moment this library only implements a subset of the API. If there's an\nmissing API method feel free to open an issue.*\n\n## Example\n\n```lua\nlocal Mailgun = require(\"mailgun\").Mailgun\n\nlocal m = Mailgun({\n  domain = \"leafo.net\",\n  api_key = \"api:key-blah-blah-blahblah\"\n})\n\nm:send_email({\n  to = \"you@example.com\",\n  subject = \"Important message here\",\n  html = true,\n  body = [[\n    \u003ch1\u003eHello world\u003c/h1\u003e\n    \u003cp\u003eHere is my email to you.\u003c/p\u003e\n    \u003chr /\u003e\n    \u003cp\u003e\n      \u003ca href=\"%unsubscribe_url%\"\u003eUnsubscribe\u003c/a\u003e\n    \u003c/p\u003e\n  ]]\n})\n```\n\n## Install\n\n```\nluarocks install mailgun\n```\n\n## Reference\n\nThe `Mailgun` constructor can be used to create a new client to Mailgun. It's\nfound in the `mailgun` module.\n\n```lua\nlocal Mailgun = require(\"mailgun\").Mailgun\n\nlocal m = Mailgun({\n  domain = \"leafo.net\",\n  api_key = \"api:key-blah-blah-blahblah\"\n})\n```\n\nThe following options are valid:\n\n* `domain` - the domain to use for API requests (**required**)\n* `api_key` - the API key to authenticate requests (**required**)\n* `webhook_signing_key` - key used for webhook signature verification, defaults to api key without username (*optional*)\n* `default_sender` - the sender to use for `send_email` when a sender is not provided (*optional*)\n* `http` - set the HTTP client (*optional*)\n\nThe value of `default_sender` has a default created from the `domain` like\nthis: `{domain} \u003cpostmaster@{domain}\u003e`.\n\n### HTTP Client\n\nIf a HTTP client is not specified, this library will pick `lapis.nginx.http`\nwhen inside of Nginx (OpenResty), otherwise it will fall back on `ssl.https`\n(LuaSocket \u0026 LuaSec)\n\nThe client can be changed by providing an `http` option to the constructor. If\na string is passed, it will be required as a module name. For example, you can\nuse [lua-http](https://github.com/daurnimator/lua-http) by passing in `http = \"http.compat.socket\"`\n\nAlternatively, a function can be passed in. The function will be called once\nand the return value will be used as the http module. (It should be a table\nwith a request function that works like LuaSocket)\n\n### Methods\n\n#### `mailgun:send_email(opts={})`\n\nThe following are required options:\n\n* `to` - the recipient(s) of the email. Pass an array table to send to multiple recipients\n* `subject` - the subject line of the email\n* `body` - the body of the email\n\nOptional fields:\n\n* `from` - the sender of the email (default: `{domain} \u003cpostmaster@{domain}\u003e`)\n* `html` - set to `true` to send email as HTML (default `false`)\n* `domain` - use a different domain than the default\n* `cc` - recipients to cc to, same format as `to`\n* `bcc` - recipients to bcc to, same format as `to`\n* `track_opens` - track the open rate fo the email (default `false`)\n* `tags` - an array table of tags to apply to message\n* `vars` - table of recipient specific variables where the key is the recipient and value is a table of vars\n* `headers` - a table of additional headers to provide\n* `campaign` - the campaign id of the campaign the email is part of (see `get_or_create_campaign_id`)\n* `v:{NAME}` - add any number of user variables with the name `{NAME}`, ie. `v:user_id`\n\n##### Recipient variables\n\nUsing recipient variables you can bulk send many emails in a single API call.\nYou can parameterize your email address with different variables for each\nrecipient:\n\n\n```lua\nlocal vars = {\n  [\"leafo@example.com\"] = {\n    username = \"L.E.A.F.\",\n    profile_url = \"http://example.com/leafo\",\n  },\n  [\"adam@example.com\"] = {\n    username = \"Adumb\",\n    profile_url = \"http://example.com/adam\",\n  }\n}\n\nmailgun:send_email({\n  to = {\"leafo@example.com\", \"adam@example.com\"},\n  vars = vars,\n  subject = \"Hey check it out!\",\n  body = [[\n    Hello %recipient.username%,\n    We just updated your profile page. Check it out: %recipient.profile_url%\n  ]]\n})\n```\n\n##### Setting reply-to email\n\nPass the `Reply-To` header:\n\n```lua\nmailgun:send_email({\n  to = \"you@example.com\",\n  subject = \"Hey check it out!\",\n  from = \"Postmaster \u003cpostmaster@leaf.zone\u003e\",\n  headers = {\n    [\"Reply-To\"] = \"leafo@leaf.zone\"\n  },\n  body = [[\n    Thanks for downloading our game, reply if you have any questions!\n  ]]\n})\n```\n\n#### `mailgun:create_campaign(name)`\n\nCreates a new campaign named `name`. Returns the campaign object\n\n#### `campaigns = mailgun:get_campaigns()`\n\nGets all the campaigns that are available\n\n#### `mailgun:get_or_create_campaign_id(name)`\n\nGets a campaign id for a campaign by name. If it doesn't exist yet a new one is created.\n\n#### `messages, paging = mailgun:get_messages()`\n\nGets the first page of stored messages (this uses the events API). The paging\nobject includes the urls for fetching subsequent pages.\n\n#### `unsubscribes, paging = mailgun:get_unsubscribes(opts={})`\n\nhttps://documentation.mailgun.com/api-suppressions.html#unsubscribes\n\nGets the first page of unsubscribes messages. `opts` is passed as query string\nparameters.\n\n#### `iter = mailgun:each_event(filter_params={})`\n\nhttps://documentation.mailgun.com/en/latest/api-events.html\n\nIterates through each event, lazily fetching pages of events as needed. In\norder to stop processing events before all of them have been traversed use\n`break` to exit the loop.\n\n```\nfor e in mailgun:each_unsubscribe() do\n  print(e.event)\nend\n```\n\nEach event is a plain Lua table with the same format provided by the API :\n\u003chttps://documentation.mailgun.com/en/latest/api-events.html#event-structure\u003e\n\nUses `limit` of 300 by default, which will fetch 300 events at a time for each page.\n\n#### `result = mailgun:get_events(params={})`\n\nhttps://documentation.mailgun.com/en/latest/api-events.html\n\nIssues API call to `GET /\u003cdomain\u003e/events` with provided parameters. If you want\nto iterate over events see `each_event`.\n\n#### `iter = mailgun:each_unsubscribe()`\n\nIterates through each message (fetching each page as needed)\n\n```lua\nfor unsub in mailgun:each_unsubscribe() do\n  print(unsub.address)\nend\n```\n\n#### `bounces, paging = mailgun:get_bounces(opts={})`\n\nhttps://documentation.mailgun.com/api-suppressions.html#bounces\n\nGets the first page of unsubscribes bounces. `opts` is passed as query string\nparameters.\n\n#### `iter = mailgun:each_bounce()`\n\nIterates through each bounce (fetching each page as needed). Similar to\n`get_unsubscribes`.\n\n#### `complaints, paging = mailgun:get_complaints(opts={})`\n\nhttps://documentation.mailgun.com/api-suppressions.html#view-all-complaints\n\nGets the first page of complaints messages. `opts` is passed as query string\nparameters.\n\n#### `iter = mailgun:each_complaint()`\n\nIterates through each complaint (fetching each page as needed). Similar to\n`get_unsubscribes`.\n\n\n#### `new_mailgun = mailgun:for_domain(domain)`\n\nReturns a new instance of the API client configured the same way, but with the\ndomain replaced with the provided domain. If you have multiple domains on your\naccount you can use this to switch to them for any of the `get_` methods.\n\n#### `mailgun:verify_webhook_signature(timestamp, token, signature)`\n\nVerify signature of a webhook call using the stored API key as described here: \u003chttps://documentation.mailgun.com/en/latest/user_manual.html#webhooks\u003e\n\nReturns `true` if the signature is validated, otherwise returns `nil` and an error message.\n\nIf any of the arguments aren't provided, an error is thrown.\n\n#### `mailgun:validate_email(email_address)`\n\nLook up email using the email validation service described here: \u003chttps://documentation.mailgun.com/en/latest/api-email-validation.html#email-validation\u003e\n\nReturns a Lua object with results of validation\n\n# Changelog\n\nChangelog now available on GitHub releases: https://github.com/leafo/lua-mailgun/releases\n\n## License (MIT)\n\nCopyright (C) 2022 by Leaf Corcoran\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n","funding_links":[],"categories":["Libraries"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleafo%2Flua-mailgun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleafo%2Flua-mailgun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleafo%2Flua-mailgun/lists"}