{"id":13442357,"url":"https://github.com/owainlewis/clojure-mail","last_synced_at":"2025-04-13T05:08:01.948Z","repository":{"id":4089162,"uuid":"5195928","full_name":"owainlewis/clojure-mail","owner":"owainlewis","description":"A Clojure library for parsing, downloading and reading email from IMAP servers.","archived":false,"fork":false,"pushed_at":"2021-04-14T13:01:40.000Z","size":177,"stargazers_count":205,"open_issues_count":15,"forks_count":55,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-13T05:07:57.448Z","etag":null,"topics":["clojure","email","gmail"],"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/owainlewis.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}},"created_at":"2012-07-26T18:48:32.000Z","updated_at":"2024-12-14T18:01:50.000Z","dependencies_parsed_at":"2022-09-17T18:53:27.315Z","dependency_job_id":null,"html_url":"https://github.com/owainlewis/clojure-mail","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owainlewis%2Fclojure-mail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owainlewis%2Fclojure-mail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owainlewis%2Fclojure-mail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owainlewis%2Fclojure-mail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/owainlewis","download_url":"https://codeload.github.com/owainlewis/clojure-mail/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248665747,"owners_count":21142123,"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":["clojure","email","gmail"],"created_at":"2024-07-31T03:01:44.769Z","updated_at":"2025-04-13T05:08:01.910Z","avatar_url":"https://github.com/owainlewis.png","language":"Clojure","readme":"# Clojure-mail\n\n![](https://travis-ci.org/owainlewis/clojure-mail.svg?branch=master)\n\n[![Clojars Project](http://clojars.org/io.forward/clojure-mail/latest-version.svg#)](http://clojars.org/io.forward/clojure-mail)\n\nA clojure library for parsing, downloading and reading email from IMAP servers.\n\n## Quickstart\n\nThis is a complete example showing how to read the subject of your latest Gmail inbox message\n\n```clojure\n(ns myproject.core\n  (:require [clojure-mail.core :refer :all]\n            [clojure-mail.gmail :as gmail]\n            [clojure-mail.message :refer (read-message)]))\n\n(def gstore (gmail/store \"user@gmail.com\" \"password\"))\n\n(def inbox-messages (inbox gstore))\n\n;; to convert a javamail message into a clojure message we need to call read-message\n\n(def latest (read-message (first inbox-messages)))\n\n;; Let's read the subject of our latest inbox message\n(:subject latest)\n\n(keys latest)\n;; =\u003e (:id :to :cc :bcc :from :sender :subject :date-sent :date-recieved :multipart? :content-type :body :headers)\n\n```\n\n## Use\n\nWe need to require clojure-mail.core before we begin.\n\n```clojure\n(:require [clojure-mail.core :refer :all]\n          [clojure-mail.message :as message])\n```\n\nThe first thing we need is a mail store which acts as a gateway to our IMAP account.\n\n```clojure\n(def store (store \"imap.gmail.com\" \"user@gmail.com\" \"password\"))\n```\n\nYou can also authenticate using an Oauth token.\n\n```clojure\n(def store (xoauth2-store \"imap.gmail.com\" \"user@gmail.com\" \"user-oauth-token\"))\n```\n\nNow we can fetch email messages easily.\n\n```clojure\n(def my-inbox-messages (take 5 (all-messages store \"inbox\")))\n\n(def first-message (first my-inbox-messages))\n\n(message/subject first-message) ;; =\u003e \"Hi! Here are your new links from the weekend\"\n```\n\nNote that the messages returned are Java mail message objects.\n\n\n## Reading email messages\n\n```clojure\n\n(def javamail-message (first inbox-messages))\n\n;; To read the entire message as a clojure map\n(def message (read-message javamail-message))\n\n;; There are also individual methods available in the message namespace. I.e to read the subject\n;; of a javax.mail message\n(message/subject javamail-message)\n\n;; You can also select only the fields you require\n(def message (read-message javamail-message :fields [:id :to :subject]))\n\n```\n\nAn email message returned as a Clojure map from read-message looks something like this:\n\n```clojure\n\n{:subject \"Re: Presents for Dale's baby\",\n :from {:address \"\u003csomeone@aol.com\u003e\" :name \"Someone\"}\n :date-recieved \"Tue Mar 11 12:54:41 GMT 2014\",\n :to ({:address \"owain@owainlewis.com\" :name \"Owain Lewis\"}),\n :cc (),\n :bcc (),\n :multipart? true,\n :content-type \"multipart/ALTERNATIVE\",\n :sender {:address \"\u003csomeone@aol.com\u003e\" :name \"Someone\"},\n :date-sent #inst \"2015-10-23T12:19:33.838-00:00\"\n :date-received #inst \"2015-10-23T12:19:33.838-00:00\"\n :body [{:content-type \"text/plain\" :body \"...\"}\n        {:content-type \"text/html\"  :body \"...\"}]\n :headers {\"Subject\" \"Re: Presents for Dale's baby\" .......}\n\n```\n\n## Searching your inbox\n\nYou can easily search your inbox for messages\n\n```clojure\n(def s (gen-store \"user@gmail.com\" \"password\"))\n(def results (search-inbox s \"projects\"))\n(def results (search-inbox s [:body \"projects\" :subject \"projects\"]))\n(def results (search-inbox s :body \"projects\" :received-before :yesterday))\n(def results (search-inbox s :body \"projects\" :from \"john@example.com\"))\n\n(-\u003e\u003e results first subject) ;; =\u003e \"Open Source Customisation Projects\"\n```\n\n## Parser\n\nHTML emails are evil. There is a simple HTML -\u003e Plain text parser provided if you need to\ndo any machine learning type processing on email messages.\n\n```clojure\n(require '[clojure-mail.parser :refer :all])\n\n(html-\u003etext \"\u003ch1\u003eI HATE HTML EMAILS\u003c/h1\u003e\")\n\n;; =\u003e \"I HATE HTML EMAILS\"\n\n```\n\n## Watching a folder\n\nSome IMAP servers allow the use of the IDLE command to receive push notifications when a folder changes.\n\n```clojure\n(require '[clojure-mail.events :as events])\n\n;; Create a manager and start listening to the inbox, printing the subject of new messages\n(def manager\n  (let [s (get-session \"imaps\")\n        gstore (store \"imaps\" s \"imap.gmail.com\" \"me@gmail.com\" \"mypassword\")\n        folder (open-folder gstore \"inbox\" :readonly)\n        im (events/new-idle-manager s)]\n    (events/add-message-count-listener (fn [e]\n                                  (prn \"added\" (-\u003e\u003e e\n                                                    :messages\n                                                    (map read-message)\n                                                    (map :subject))))\n                                #(prn \"removed\" %)\n                                folder\n                                im)\n    im))\n;; now we wait...\n\n\"added\" (\"added\" (\"test!\")\n\"added\" (\"added\" (\"another test!\")\n\n;; we received some messages and printed them, now we can stop the manager as we are finished\n(events/stop manager)\n\n```\n\n## Reading emails from disk\n\nClojure mail can be used to parse existing email messages from file. Take a look in dev-resources/emails to see some example messages. To read one of these messages we can do something like this\n\n\n```clojure\n\n(def message (file-\u003emessage \"test/clojure_mail/fixtures/25\"))\n\n(read-message message)\n\n;; =\u003e\n;; {:subject \"Request to share ContractsBuilder\",\n;; :from nil, :date-recieved nil,\n;; :to \"zaphrauk@gmail.com\",\n;; :multipart? true,\n;; :content-type \"multipart/alternative; boundary=90e6ba1efefc44ffe804a5e76c56\",\n;; :sender nil,\n;; :date-sent \"Fri Jun 17 13:21:19 BST 2011\" ..............\n\n```\n\n## License\n\nCopyright © 2017 Owain Lewis\n\nDistributed under the Eclipse Public License, the same as Clojure.\n","funding_links":[],"categories":["Clojure"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowainlewis%2Fclojure-mail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fowainlewis%2Fclojure-mail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowainlewis%2Fclojure-mail/lists"}