{"id":13507839,"url":"https://github.com/gen-smtp/gen_smtp","last_synced_at":"2026-02-20T16:01:38.906Z","repository":{"id":35112592,"uuid":"207238","full_name":"gen-smtp/gen_smtp","owner":"gen-smtp","description":"The extensible Erlang SMTP client and server library.","archived":false,"fork":false,"pushed_at":"2025-05-30T07:15:08.000Z","size":4926,"stargazers_count":704,"open_issues_count":45,"forks_count":283,"subscribers_count":31,"default_branch":"master","last_synced_at":"2025-12-13T01:46:02.500Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gen-smtp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2009-05-21T23:18:49.000Z","updated_at":"2025-11-17T08:47:41.000Z","dependencies_parsed_at":"2024-01-31T07:03:39.791Z","dependency_job_id":"889f8c0b-3dd9-4cbd-a950-29b93007ab96","html_url":"https://github.com/gen-smtp/gen_smtp","commit_stats":{"total_commits":611,"total_committers":80,"mean_commits":7.6375,"dds":0.8036006546644845,"last_synced_commit":"da7893dbe5dc20f1d6137141a4ec49f910a7cef6"},"previous_names":["vagabond/gen_smtp"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/gen-smtp/gen_smtp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen-smtp%2Fgen_smtp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen-smtp%2Fgen_smtp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen-smtp%2Fgen_smtp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen-smtp%2Fgen_smtp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gen-smtp","download_url":"https://codeload.github.com/gen-smtp/gen_smtp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen-smtp%2Fgen_smtp/sbom","scorecard":{"id":422103,"data":{"date":"2025-08-11","repo":{"name":"github.com/gen-smtp/gen_smtp","commit":"68ab11101a0710a13d39d73ff780dc9d76ffa15f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.1,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":7,"reason":"Found 19/25 approved changesets -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":4,"reason":"2 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/docs.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/gen-smtp/gen_smtp/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/gen-smtp/gen_smtp/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/gen-smtp/gen_smtp/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/gen-smtp/gen_smtp/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/gen-smtp/gen_smtp/docs.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docs.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/gen-smtp/gen_smtp/docs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/gen-smtp/gen_smtp/docs.yml/master?enable=pin","Info:   0 out of   5 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":10,"reason":"project is fuzzed","details":["Info: ErlangPropertyBasedTesting integration found: test/prop_mimemail.erl:19","Info: ErlangPropertyBasedTesting integration found: test/prop_rfc5322.erl:18","Info: ErlangPropertyBasedTesting integration found: test/prop_mimemail.erl:19","Info: ErlangPropertyBasedTesting integration found: test/prop_rfc5322.erl:18"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T01:29:03.198Z","repository_id":35112592,"created_at":"2025-08-19T01:29:03.198Z","updated_at":"2025-08-19T01:29:03.198Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29656589,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T09:27:29.698Z","status":"ssl_error","status_checked_at":"2026-02-20T09:26:12.373Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":[],"created_at":"2024-08-01T02:00:40.658Z","updated_at":"2026-02-20T16:01:38.880Z","avatar_url":"https://github.com/gen-smtp.png","language":"Erlang","funding_links":[],"categories":["Email","Networking and Distributed"],"sub_categories":["Networking"],"readme":"# gen_smtp\n\n[![Hex pm](http://img.shields.io/hexpm/v/gen_smtp.svg?style=flat)](https://hex.pm/packages/gen_smtp)\n[![CI](https://github.com/gen-smtp/gen_smtp/actions/workflows/ci.yml/badge.svg)](https://github.com/gen-smtp/gen_smtp/actions/workflows/ci.yml)\n[![Docs](https://github.com/gen-smtp/gen_smtp/actions/workflows/docs.yml/badge.svg)](https://github.com/gen-smtp/gen_smtp/actions/workflows/docs.yml)\n\nThe Erlang SMTP client and server library.\n\n## Mission\n\nProvide a generic Erlang SMTP server framework that can be extended via\ncallback modules in the OTP style. A pure Erlang SMTP client is also included.\nThe goal is to make it easy to send and receive email in Erlang without the\nhassle of POP/IMAP. This is *not* a complete mailserver - although it includes\nmost of the parts you'd need to build one.\n\nThe SMTP server/client supports PLAIN, LOGIN, CRAM-MD5 authentication as well\nas STARTTLS and SSL (port 465).\n\nAlso included is a MIME encoder/decoder, sorta according to RFC204{5,6,7}.\n\nIPv6 is also supported (at least serverside).\n\nSMTP server uses ranch as socket acceptor. It can use Ranch 1.8+, as well as 2.x.\n\nI (Vagabond) have had a simple gen_smtp based SMTP server receiving and parsing\ncopies of all my email for several months and its been able to handle over 100\nthousand emails without leaking any RAM or crashing the erlang virtual machine.\n\n## Current Participants\n\n+ Andrew Thompson (andrew AT hijacked.us)\n+ Jack Danger Canty (code AT jackcanty.com)\n+ Micah Warren (micahw AT lordnull.com)\n+ Arjan Scherpenisse (arjan AT botsquad.com)\n+ Marc Worrell (marc AT worrell.nl)\n\n## Who is using it?\n\n+ gen_smtp is used to provide the email functionality of [OpenACD](https://github.com/OpenACD/OpenACD)\n+ gen_smtp is used as both the SMTP server and SMTP client for [Zotonic](http://zotonic.com)\n+ [Chicago Boss](http://www.chicagoboss.org/) uses gen_smtp for its mail API.\n+ [Gmailbox](https://www.gmailbox.org) uses gen_smtp to provide a free email forwarding service.\n+ [JOSHMARTIN GmbH](https://joshmartin.ch/) uses gen_smtp to send emails in [Hygeia](https://covid19-tracing.ch/) to send emails for contact tracing of SARS-CoV-2.\n+ [hookup.email](https://hookup.email) uses gen_smtp to receive and parse emails the service forwards to webhooks, APIs, or any other HTTP application.\n+ many libraries [depend on gen_smtp](https://hex.pm/packages/gen_smtp) according to hex.pm\n\nIf you'd like to share your usage of gen_smtp, please submit a PR to this `README.md`.\n\n# Usage\n\n## Client Example\n\nHere's an example usage of the client:\n\n```erlang\ngen_smtp_client:send({\"whatever@test.com\", [\"andrew@hijacked.us\"],\n \"Subject: testing\\r\\nFrom: Andrew Thompson \u003candrew@hijacked.us\u003e\\r\\nTo: Some Dude \u003cfoo@bar.com\u003e\\r\\n\\r\\nThis is the email body\"},\n  [{relay, \"smtp.gmail.com\"}, {username, \"me@gmail.com\"}, {password, \"mypassword\"}]).\n```\n\nThe From and To addresses will be wrapped in `\u003c\u003e` if they aren't already,\nTLS will be auto-negotiated if available (unless you pass `{tls, never}`) and\nauthentication will by attempted by default since a username/password were\nspecified (`{auth, never}` overrides this).\n\nIf you want to mandate tls or auth, you can pass `{tls, always}` or `{auth,\nalways}` as one of the options. You can specify an alternate port with `{port,\n2525}` (default is 25) or you can indicate that the server is listening for SSL\nconnections using `{ssl, true}` (port defaults to 465 with this option).\n\n### Options\n\n    send(Email, Options)\n    send(Email, Options, Callback)\n    send_blocking(Email, Options)\n\nThe `send` method variants `send/2, send/3, send_blocking/2` take an `Options` argument.\n`Options` must be a proplist with the following valid values:\n\n  * **relay** the smtp relay, e.g. `\"smtp.gmail.com\"`\n  * **username** the username of the smtp relay e.g. `\"me@gmail.com\"`\n  * **password** the password of the smtp relay e.g. `\"mypassword\"`\n  * **auth** whether the smtp server needs authentication. Valid values are `if_available`, `always`, and `never`. Defaults to `if_available`. If your smtp relay requires authentication set it to `always`\n  * **ssl** whether to connect on 465 in ssl mode. Defaults to `false`\n  * **sockopts** used for the initial plain or SSL/TLS TCP connection. More info at Erlang documentation [gen_tcp](https://www.erlang.org/doc/man/gen_tcp.html) and [ssl](https://www.erlang.org/doc/man/ssl.html). Defaults to `[binary, {packet, line}, {keepalive, true}, {active, false}]`.\n  * **tls** valid values are `always`, `never`, `if_available`. Most modern smtp relays use tls, so set this to `always`. Defaults to `if_available`\n  * **tls_options** used for `STARTTLS` upgrades in `ssl:connect`, More info at [Erlang documentation - ssl](https://www.erlang.org/doc/man/ssl.html). Defaults to `[{versions , ['tlsv1', 'tlsv1.1', 'tlsv1.2']}]`. This is merged with options listed at: [smtp_socket.erl#L50 - SSL_CONNECT_OPTIONS](https://github.com/gen-smtp/gen_smtp/blob/master/src/smtp_socket.erl#L50) .\n  * **hostname** the hostname to be used by the smtp relay. Defaults to: `smtp_util:guess_FQDN()`. The hostname on your computer might not be correct, so set this to a valid value.\n  * **retries** how many retries per smtp host on temporary failure. Defaults to 1, which means it will retry once if there is a failure.\n  * **protocol** valid values are `smtp`, `lmtp`. Default is `smtp`\n\n\n### DKIM signing of outgoing emails\n\nYou may wish to configure DKIM signing [RFC6376](https://datatracker.ietf.org/doc/html/rfc5672) or [RFC8463](https://datatracker.ietf.org/doc/html/rfc8463) (Ed25519) of outgoing emails\nfor better security. To do that you need public and private keys, which can be generated by\nfollowing commands:\n\n```bash\n# RSA\nopenssl genrsa -out private-key.pem 1024\nopenssl rsa -in private-key.pem -out public-key.pem -pubout\n\n# Ed25519 - Erlang/OTP 24.1+ only!\nopenssl genpkey -algorithm ed25519 -out private-key.pem\nopenssl pkey -in private-key.pem -pubout -out public-key.pem\n# DKIM DNS record p value for Ed25519 must only contain Base64 encoded public key, without ASN.1\nopenssl asn1parse -in public-key.pem -offset 12 -noout -out /dev/stdout | openssl base64\n```\n\nTo send DKIM-signed email:\n\n```erlang\n{ok, PrivKey} = file:read_file(\"private-key.pem\"),\nDKIMOptions = [\n    {s, \u003c\u003c\"foo.bar\"\u003e\u003e},\n    {d, \u003c\u003c\"example.com\"\u003e\u003e},\n    {private_key, {pem_plain, PrivKey}}]}\n    %{private_key, {pem_encrypted, EncryptedPrivKey, \"password\"}}\n],\nSignedMailBody = \\\n mimemail:encode({\u003c\u003c\"text\"\u003e\u003e, \u003c\u003c\"plain\"\u003e\u003e,\n                  [{\u003c\u003c\"Subject\"\u003e\u003e, \u003c\u003c\"DKIM testing\"\u003e\u003e},\n                   {\u003c\u003c\"From\"\u003e\u003e, \u003c\u003c\"Andrew Thompson \u003candrew@hijacked.us\u003e\"\u003e\u003e},\n                   {\u003c\u003c\"To\"\u003e\u003e, \u003c\u003c\"Some Dude \u003cfoo@bar.com\u003e\"\u003e\u003e}],\n                  #{},\n                  \u003c\u003c\"This is the email body\"\u003e\u003e},\n                  [{dkim, DKIMOptions}]),\ngen_smtp_client:send({\"whatever@example.com\", [\"andrew@hijacked.us\"], SignedMailBody}, []).\n```\n\nFor using Ed25519 you need to set the option `{a, 'ed25519-sha256'}`.\n\nDon't forget to put your public key to `foo.bar._domainkey.example.com` TXT DNS record as something like\n\nRSA:\n```\nv=DKIM1; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBA......\n```\n\nEd25519:\n```\nv=DKIM1; g=*; k=ed25519; p=MIGfMA0GCSqGSIb3DQEBA......\n```\n\nSee RFC6376 for more details.\n\n## Server Example\n\n`gen_smtp` ships with a simple callback server example, `smtp_server_example`. To start the SMTP server with this as the callback module, issue the following command:\n\n```erlang\ngen_smtp_server:start(smtp_server_example).\ngen_smtp_server starting at nonode@nohost\nlistening on {0,0,0,0}:2525 via tcp\n{ok,\u003c0.33.0\u003e}\n```\n\nBy default it listens on 0.0.0.0 port 2525. You can telnet to it and test it:\n\n```\n^andrew@orz-dashes:: telnet localhost 2525                                                      [~]\nTrying 127.0.0.1...\nConnected to localhost.\nEscape character is '^]'.\n220 localhost ESMTP smtp_server_example\nEHLO example.com\n250-orz-dashes\n250-SIZE 10485670\n250-8BITMIME\n250-PIPELINING\n250 WTF\nMAIL FROM: andrew@hijacked.us\n250 sender Ok\nRCPT TO: andrew@hijacked.us\n250 recipient Ok\nDATA\n354 enter mail, end with line containing only '.'\nGood evening gentlemen, all your base are belong to us.\n.\n250 queued as d98ae19ee87f0741ac9ba90d7046f0c5\nQUIT\n221 Bye\nConnection closed by foreign host.\n```\n\nYou can configure the server in general, each SMTP session, and the callback module, for example:\n\n```erlang\ngen_smtp_server:start(\n    smtp_server_example,\n    [{sessionoptions, [{allow_bare_newlines, fix},\n                       {callbackoptions, [{parse, true}]}]}]).\n```\n\nThis configures the session to fix bare newlines (other options are `strip`, `ignore` and `false`: `false` rejects emails with bare newlines, `ignore` passes them through unmodified and `strip` removes them) and tells the callback module to run the MIME decoder on the email once its been received. The example callback module also supports the following options: `relay` - whether to relay email on, `auth` - whether to do SMTP authentication and `parse` - whether to invoke the MIME parser. The example callback module is included mainly as an example and are not intended for serious usage. You could easily create your own callback options.\nIn general, following options can be specified `gen_smtp_server:options()`:\n\n* `{domain, string()}` - is used as server hostname (it's placed to SMTP server banner and HELO/EHLO response), default - guess from machine hostname\n* `{address, inet:ip4_address()}` - IP address to listen on, default `{0, 0, 0, 0}`\n* `{port, inet:port_number()}` - port to listen on, default `2525`\n* `{family, inet | inet6}` - IP address type (IPv4/IPv6), default `inet`\n* `{protocol, tcp | ssl}` - listen in tcp or ssl mode, default `tcp`\n* `{ranch_opts, ranch:opts()}` - format depends on ranch version. Consult Ranch documentation.\n* `{sessionoptions, gen_smtp_server_session:options()}` - see below\n\nSession options are:\n\n* `{allow_bare_newlines, false | ignore | fix | strip}` - see above\n* `{hostname, inet:hostname()}` - which hostname server should send in response\n  to `HELO` / `EHLO` commands. Default: `inet:gethostname()`.\n* `{tls_options, [ssl:server_option()]}` - options to pass to `ssl:handshake/3`\n  when `STARTTLS` command is sent by the client. Only needed if `STARTTLS` extension\n  is enabled\n* `{protocol, smtp | lmtp}` - when `lmtp` is passed, the control flow of the\n  [Local Mail Transfer Protocol](https://tools.ietf.org/html/rfc2033) is applied.\n  LMTP is derived from SMTP with just a few variations and is used by standard\n  [Mail Transfer Agents (MTA)](https://en.wikipedia.org/wiki/Message_transfer_agent), like Postfix, Exim and OpenSMTPD to\n  send incoming email to local mail-handling applications that usually don't have a delivery queue.\n  The default value of this option is `smtp`.\n* `{callbackoptions, any()}` - value will be passed as 4th argument to callback module's `init/4`\n\nYou can connect and test this using the `gen_smtp_client` via something like:\n\n```erlang\ngen_smtp_client:send(\n    {\"whatever@test.com\", [\"andrew@hijacked.us\"], \"Subject: testing\\r\\nFrom: Andrew Thompson \\r\\nTo: Some Dude \\r\\n\\r\\nThis is the email body\"},\n    [{relay, \"localhost\"}, {port, 2525}]).\n```\n\nIf you want to listen on IPv6, you can use the `{family, inet6}` and `{address, {0, 0, 0, 0, 0, 0, 0, 0}}` options to enable listening on IPv6.\n\nPlease notice that when using the LMTP protocol, the `handle_EHLO` callback will be used\nto handle the `LHLO` command as defined in [RFC2033](https://tools.ietf.org/html/rfc2033),\ndue to their similarities. Although not used, the implementation of `handle_HELO` is still\nmandatory for the general `gen_smtp_server_session` behaviour (you can simply\nreturn a 500 error, e.g. `{error, \"500 LMTP server, not SMTP\"}`).\n\n## Dependency on iconv\n\ngen_smtp relies on iconv for text encoding and decoding when parsing is activated.\n\nTo use gen_smtp, a `eiconv` module must be loaded, with a `convert/3` function.\n\nYou can use [Zotonic/eiconv](https://github.com/zotonic/eiconv), which is used\nfor tests on the project.\n\nFor that, you can add the following line to your `rebar.config` file:\n\n```\n{deps, [\n  {eiconv, \"1.0.0\"}\n]}.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgen-smtp%2Fgen_smtp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgen-smtp%2Fgen_smtp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgen-smtp%2Fgen_smtp/lists"}