{"id":18837954,"url":"https://github.com/nextjournal/garden-email","last_synced_at":"2026-01-25T08:31:27.613Z","repository":{"id":222680920,"uuid":"721757340","full_name":"nextjournal/garden-email","owner":"nextjournal","description":"Email library for application.garden.","archived":false,"fork":false,"pushed_at":"2024-09-18T23:06:41.000Z","size":59,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-09-30T16:52:18.306Z","etag":null,"topics":["application-garden"],"latest_commit_sha":null,"homepage":"","language":"Clojure","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/nextjournal.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,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-11-21T17:58:30.000Z","updated_at":"2024-09-18T23:06:45.000Z","dependencies_parsed_at":"2024-11-08T02:38:23.249Z","dependency_job_id":"4f59b32f-6a13-4a46-9028-457fd938f724","html_url":"https://github.com/nextjournal/garden-email","commit_stats":null,"previous_names":["nextjournal/garden-email"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nextjournal/garden-email","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextjournal%2Fgarden-email","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextjournal%2Fgarden-email/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextjournal%2Fgarden-email/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextjournal%2Fgarden-email/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nextjournal","download_url":"https://codeload.github.com/nextjournal/garden-email/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextjournal%2Fgarden-email/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28749305,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T08:31:04.260Z","status":"ssl_error","status_checked_at":"2026-01-25T08:30:28.859Z","response_time":113,"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":["application-garden"],"created_at":"2024-11-08T02:37:17.505Z","updated_at":"2026-01-25T08:31:27.598Z","avatar_url":"https://github.com/nextjournal.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Garden Email\n\nA small helper library to send and receive email with application.garden. \n\n## Installation\n\nGarden Email is [hosted on GitHub](https://github.com/nextjournal/garden-email) so you can simply add it as a git dependency to your `deps.edn`:\n\n```clojure {:nextjournal.clerk/code-listing true}\n{io.github.nextjournal/garden-email {:git/sha \"\u003clatest-sha\u003e\"}}\n```\n\n## My Email Address\n\nYour own email address is available in `nextjournal.garden-email/my-email-address`.\nYou can send email from this address, including plus-addresses and receive email at this address, including plus addresses.\n\nThere is a helper function to construct plus addresses:\n\n```clojure {:nextjournal.clerk/code-listing true}\n(garden-email/plus-address \"foo@example.com\" \"bar\")\n; =\u003e \"foo+bar@example.com\"\n```\n\n## Sending Email\n\nYou can send email using `nextjournal.garden-email/send-email!`:\n\n```clojure {:nextjournal.clerk/code-listing true}\n(garden-email/send-email! {:to {:email \"foo@example.com\"\n                                :name \"Foo Bar\"}\n                           :from {:email garden-email/my-email-address\n                                  :name \"My App\"}\n                           :subject \"Hi!\"\n                           :text \"Hello World!\"\n                           :html \"\u003chtml\u003e\u003cbody\u003e\u003ch1\u003eHello World!\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e\"})\n```\n\nEvery parameter except for `{:to {:email \"…\"}}` is optional.\n\n### Double-Opt-In\n\nThe first time you send an email to a new email address, the recipient gets a generic email to confirm that they want to receive your email.\nYour original email gets buffered and sent to the recipient, as soon as they confirm that they want your email.\n\nYou are blocked from sending more email to that address, until the recipient confirms that they want your email.\n\nAfter the recipient confirmed they want to receive further email, you can continue sending email as usual.\napplication.garden automatically adds a footer to unsubscribe from future emails to every email.\n\n\n## Receiving Email\n\nYou can process incoming email by adding the `nextjournal.garden-email/wrap-with-email` middleware to your application and providing a callback:\n\n```clojure {:nextjournal.clerk/code-listing true}\n(defn on-receive [{:keys [message-id from to reply-to subject text html]}]\n  (println (format \"Received email from %s to %s with subject %s.\" from to subject)))\n\n(def wrapped-ring-handler\n  (-\u003e my-ring-handler (garden-email/wrap-with-email {:on-receive on-receive})))\n```\n\nIf you do not provide a custom callback, garden-email saves incoming email to a mailbox in persistent storage, which you can interact with using the following functions:\n\n- `inbox`\n- `save-to-inbox!`\n- `delete-from-inbox!`\n- `clear-inbox!`\n\n## Development\n\nWhen running your application locally in development, no actual emails are sent.\nInstead we collect mock-emails, which you can view at the url in `nextjournal.garden-email/outbox-url`,\nassuming you have added the ring middleware to your handler.\n\nTo mock incoming email, you can call `nextjournal.garden-email/receive-email`.\n\n## Mailbox\n\n`nextjournal.garden-email.render` has helper functions to render a mailbox.\n\n## Example\n\nSee [example](https://github.com/nextjournal/garden-email/tree/main/example) for an example application.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnextjournal%2Fgarden-email","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnextjournal%2Fgarden-email","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnextjournal%2Fgarden-email/lists"}