{"id":13620606,"url":"https://github.com/aphyr/postal","last_synced_at":"2025-04-14T22:32:01.607Z","repository":{"id":15835967,"uuid":"18575941","full_name":"aphyr/postal","owner":"aphyr","description":"Clojure email support","archived":false,"fork":true,"pushed_at":"2014-04-08T21:42:06.000Z","size":263,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-08T07:38:10.276Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"drewr/postal","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aphyr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-04-08T21:40:45.000Z","updated_at":"2014-06-05T15:00:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aphyr/postal","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aphyr%2Fpostal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aphyr%2Fpostal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aphyr%2Fpostal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aphyr%2Fpostal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aphyr","download_url":"https://codeload.github.com/aphyr/postal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248971888,"owners_count":21191680,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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-01T21:00:57.646Z","updated_at":"2025-04-14T22:32:01.324Z","avatar_url":"https://github.com/aphyr.png","language":"Clojure","funding_links":[],"categories":["Clojure"],"sub_categories":[],"readme":"postal\n=======\n\n#### Internet email library for Clojure\n\npostal is a library for constructing and sending RFC822-compliant\nInternet email messages.  It wraps the JavaMail package for message\nand SMTP support.  It supports sendmail natively.  Supports STARTTLS \u0026\nSSL.\n\n### Platforms\n\n* Anything that can run Java should work\n* sendmail support likely requires *nix, but `msmtp`, et al., are worthy substitutes\n* Untested on Windows\n\n### Dependencies\n\n* JavaMail 1.4.2 (in `lib/` after build)\n\n### Install\n\nServed by Clojars.  In your Leiningen project.clj:\n\n    [com.draines/postal \"1.11.1\"]\n\nLikewise substitute any tag name from git.\n\n### Examples\n\n#### Local\n\nAt a bare minimum, provide a map with `:from` and `:to` (and you'll\nprobably also be wanting `:subject` and `:body`, though they're\ntechnically optional).  Any other keys you supply will show up as\nancillary headers.  This example will locally inject the message into\nwhatever sendmail-compatible interface your system provides.\n\n    user\u003e (in-ns 'postal.core)\n    #\u003cNamespace postal.core\u003e\n    postal.core\u003e (send-message {:from \"me@draines.com\"\n                                :to [\"mom@example.com\" \"dad@example.com\"]\n                                :cc \"bob@example.com\"\n                                :subject \"Hi!\"\n                                :body \"Test.\"\n                                :X-Tra \"Something else\"})\n    {:code 0, :error :SUCCESS, :message \"message sent\"}\n    postal.core\u003e\n\n#### SMTP\n\nTo use SMTP, add an argument map before the message with at least\n`:host` key.\n\n    postal.core\u003e (send-message {:host \"mail.isp.net\"}\n                               {:from \"me@draines.com\"\n                                :to \"foo@example.com\"\n                                :subject \"Hi!\"\n                                :body \"Test.\"})\n    {:code 0, :error :SUCCESS, :message \"message sent\"}\n    postal.core\u003e\n\nFor legacy compatibility, you can also supply these connection\nparameters as metadata on the message.  `(send-message ^{:host ...} {:from ...})`\n\n#### Authentication\n\nAuthenticate to SMTP server with `:user` and `:pass`.\n\n    postal.core\u003e (send-message {:host \"mail.isp.net\"\n                                :user \"jsmith\"\n                                :pass \"sekrat!!1\"}\n                               {:from \"me@draines.com\"\n                                :to \"foo@example.com\"\n                                :subject \"Hi!\"\n                                :body \"Test.\"})\n    {:code 0, :error :SUCCESS, :message \"message sent\"}\n    postal.core\u003e\n\n#### Encryption (Gmail example)\n\nYou probably do not want to do this in the clear, so add `:ssl` to get\nan encrypted connection.  This will default to port `465` if you don't\nspecify one.\n\nIf your destination supports TLS instead, you can use `:tls`.  This\nwill default to port `25`, however, so if you need a different one\nmake sure you supply `:port`.  (It's common for ISPs to block outgoing\nport 25 to relays that aren't theirs.  Gmail supports SSL \u0026 TLS but\nit's easiest to just use SSL since you'll likely need port 465\nanyway.)\n\n    postal.core\u003e (send-message {:host \"smtp.gmail.com\"\n                                :user \"jsmith\"\n                                :pass \"sekrat!!1\"\n                                :ssl :yes!!!11}\n                               {:from \"me@draines.com\"\n                                :to \"foo@example.com\"\n                                :subject \"Hi!\"\n                                :body \"Test.\"})\n    {:code 0, :error :SUCCESS, :message \"message sent\"}\n    postal.core\u003e\n\n#### Amazon\n\nSince Amazon SES uses authenticated SMTP, postal can use it.  Just\nmake sure you use a verified address and your SMTP credentials (visit\nthe AWS Console to set those up).  Also, if you're just sandboxing,\nyou can only send *to* a verified address as well.  Example:\n\n    postal.core\u003e (send-message {:user \"AKIAIDTP........\" :pass \"AikCFhx1P.......\"\n                                :host \"email-smtp.us-east-1.amazonaws.com\"\n                                :port 587}\n                   {:from \"me@draines.com\" :to \"me@draines.com\"\n                    :subject \"Test from Amazon SES\" :body \"Test!!!11\"})\n    {:error :SUCCESS, :code 0, :message \"messages sent\"}\n    postal.core\u003e\n\n#### Attachments\n\nAttachments and multipart messages can be added as sequences of maps:\n\n    postal.core\u003e (send-message {:host \"mail.isp.net\"}\n                               {:from \"me@draines.com\"\n                                :to \"foo@example.com\"\n                                :subject \"Hi!\"\n                                :body [{:type \"text/html\"\n                                        :content \"\u003cb\u003eTest!\u003c/b\u003e\"}\n                                       ;;;; supports both dispositions:\n                                       {:type :attachment\n                                        :content (java.io.File. \"/tmp/foo.txt\")}\n                                       {:type :inline\n                                        :content (java.io.File. \"/tmp/a.pdf\")\n                                        :content-type \"application/pdf\"}]})\n    {:code 0, :error :SUCCESS, :message \"message sent\"}\n    postal.core\u003e\n\nIf your attachment has a content-type that is not recognized by\nJavaMail, e.g., `.pdf` or `.doc`, you can set `:content-type`.  You\ncan also set `:file-name` and `:description` if you don't like the\nfilename that `:content` uses.\n\nIf you want another multipart type than \"mixed\", you can specify it as a keyword\nas the first value in the map sequence. That way you can for example create an\nHTML-Email that displays a text message as fallback in email clients that do not\nsupport (or suppress) HTML-mails:\n\n    postal.core\u003e (send-message {:host \"localhost\"\n                                :port 2500\n                                :user \"user@localhost\"\n                                :pass \"somePassword\"}\n                           {:from \"jon-doe@example.com\"\n                            :to \"jane-doe@example.com\"\n                            :subject \"multipart/alternative test\"\n                            :body [:alternative\n                                   {:type \"text/plain\"\n                                    :content \"This is a test.\"}\n                                   {:type \"text/html\"\n                                    :content \"\u003chtml\u003e\u003chead\u003e \u003c/head\u003e\u003cbody\u003e\n                                    \u003ch1\u003eHeading 1\u003c/h1\u003e\u003cp\u003eThis is a test.\u003c/p\u003e\n                                    \u003c/body\u003e\u003c/html\u003e\"}\n                                  ]}))\n\n#### UTF-8\n\nPostal uses JavaMail underneath, which defaults to charset\n`us-ascii`. To set the charset, set the `:type`, like `\"text/html; charset=utf-8\"`.\n\n#### Message ID\n\nPostal will supply a message ID by default that looks like\n`[random]@postal.[host]`.  You can customize this by supplying a\n`:message-id` header with a function that takes no args.  The included\n`postal.support/message-id` can be used if you'd like to make use of\nits randomness and only customize the hostname.\n\n    {:from \"foo@bar.dom\"\n     :to \"baz@bar.dom\"\n     :subject \"Message IDs!\"\n     :body \"Regards.\"\n     :message-id #(postal.support/message-id \"foo.bar.dom\")}\n\n#### User Agent\n\nYou can customize the default `User-Agent` header (by default\n`postal/VERSION`).\n\n    {:from \"foo@bar.dom\"\n     :to \"baz@bar.dom\"\n     :subject \"Message IDs!\"\n     :body \"Regards.\"\n     :user-agent \"MyMailer 1.0\"}\n\n\n#### Stress-testing\n\nYou can stress-test a server by:\n\n    postal.core\u003e (stress ^{:host \"localhost\"\n                           :num     1000\n                           :delay   250   ;; msecs\n                           :threads 5     ;; concurrent connections}\n                         {:from \"foo@lolz.dom\"\n                          :to \"bar@lolz.dom\"})\n    sent 1000 msgs to localhost:25\n    nil\n    postal.core\u003e\n\n### Building\n\n    % lein deps \u0026\u0026 lein jar\n\n## Contributors\n\nAllen Rohner       \nAndre Branco       \nAndy Fingerhut       \nChristoph Henkelmann       \nColin Jones       \nDimas Guardado       \nGerrit Hentschel       \nJ. David Lowe       \nJeff Palmucci       \nJoe Gallo       \nKevin DeJong       \nPaul Biggar       \nPaul Stadig       \nPhil Hagelberg       \nRoman Flammer       \nSam Ritchie       \n\n## License\n\nPostal is (c) 2009-2014 Andrew A. Raines and released under the MIT\nlicense.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faphyr%2Fpostal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faphyr%2Fpostal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faphyr%2Fpostal/lists"}