{"id":17647174,"url":"https://github.com/taku0/imap-watcher","last_synced_at":"2025-03-30T07:29:23.053Z","repository":{"id":141276103,"uuid":"586186754","full_name":"taku0/imap-watcher","owner":"taku0","description":"Execute command on new messages on IMAP server","archived":false,"fork":false,"pushed_at":"2023-08-04T10:46:29.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-05T09:48:48.079Z","etag":null,"topics":["command","email","imap","mail","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/taku0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2023-01-07T08:41:10.000Z","updated_at":"2023-01-07T09:05:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"bd6dd6ff-46a8-4d77-9060-ce253d45c798","html_url":"https://github.com/taku0/imap-watcher","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/taku0%2Fimap-watcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taku0%2Fimap-watcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taku0%2Fimap-watcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taku0%2Fimap-watcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/taku0","download_url":"https://codeload.github.com/taku0/imap-watcher/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246290555,"owners_count":20753723,"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":["command","email","imap","mail","ruby"],"created_at":"2024-10-23T11:10:59.682Z","updated_at":"2025-03-30T07:29:23.033Z","avatar_url":"https://github.com/taku0.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `imap-watcher`\n\nWatches on an IMAP server using IDLE command and execute external command on new messages.\n\n## Usage\n\n```sh\nbundle install\nbundle exec ruby lib/app.rb \\\n  --server mail.example.org \\\n  --tls \\\n  --user me \\\n  --password 12345 \\\n  --inbox INBOX \\\n  --command \"jq --exit-status '.subject | contains(\\\"error\\\")' \u0026\u0026 mpv bell.wav\"\n```\n\nAlternatively, you can store those parameters in `~/.config/imap-watcher/config.json`, or other files specified in `--config` parameter.\n\nExample:\n\n```json\n{\n  \"server\": \"mail.example.org\",\n  \"tls\": true,\n  \"user\": \"me\",\n  \"password\": \"12345\",\n  \"inbox\": \"INBOX\",\n  \"command\": \"jq --exit-status '.subject | contains(\\\"error\\\")' \u0026\u0026 mpv bell.wav\"\n}\n```\n\n## Data Format\n\nMails are passed to the standard input of the command in as a JSON object.\n\nExample (pretty printed for the sake of readability):\n\n```json\n{\n  \"uid\": 12345,\n  \"timestamp\": 1672531200,\n  \"message_id\": \"0000000@example.org\",\n  \"from\": [\"test@example.org\"],\n  \"to\": [\"test@example.org\"],\n  \"cc\": [],\n  \"subject\": \"test\",\n  \"source\": null\n}\n```\n\nKeys:\n\n- `uid`: IMAP UID of the mail.  Not available for dead letters.\n- `timestamp`: The UNIX time of the `Date` header.\n- `message_id`: The `Message-ID` header without angle brackets.\n- `from`: An array of the `From` header addresses without angle brackets.\n- `to`: An array of the `To` header addresses without angle brackets.\n- `cc`: An array of the `Cc` header addresses without angle brackets.\n- `subject`: The decoded `Subject` header.\n- `source`: The entire RFC 5322 message.  Available only if `--fetch-source` is set.\n\n## Command Line Options\n\n- `--config` `PATH`\\\n  Path to configuration file.\\\n  Default: $XDG_CONFIG_HOME/imap-watcher/config.json.\\\n  The configuration file should contain JSON object.\\\n  Its keys are the command line option names.\n\n- `--server` `SERVER`\\\n  IMAP server name.\n\n- `--port` `PORT`\\\n  IMAP Port.\\\n  Default: 143 for unencrypted server. 993 for encrypted server\n\n- `--user` `USER`\\\n  User name.\n\n- `--password` `PASSWORD`\\\n  Password.\n\n- `--command` `COMMAND`\\\n  Command to execute on mails.  Evalueated by the shell.\n\n- `--dead-letter-command` `COMMAND`\\\n  Command to execute on dead letters.  Evalueated by the shell.\\\n  Default: command given by `--command`\n\n- `--mailbox` `MAILBOX`\\\n  Mailbox to watch.\\\n  Default: `INBOX`.\n\n- `--fetch-source`\\\n  Fetch entire RFC 5322 message.\n\n- `--database` `PATH`\\\n  Path to database.\\\n  Default: `$XDG_DATA_HOME/imap-watcher/mails.sqlite3`.\n\n- `--tls`\\\n  Encrypt connection using TLS.\\\n  Sometimes called SSL.  Not to be confused with `--starttls`.\n\n- `--starttls`\\\n  Encrypt connection using STARTTLS.\\\n  Not to be confused with `--tls`.\n\n- `--[no-]verify`\\\n  Verify server when `--tls` or `--starttls` is used.\\\n  Default: verify the server.\n\n- `--certificate` `PATH`\\\n  Path to CA certificate file/directory.\n\n- `--initial-fetch-count` `COUNT`\\\n  Number of mails to be fetched on the initial startup.\\\n  Default: 10.\\\n  Those mails are not passed to the executable.\n\n- `--dead-letter-retry-interval` `COUNT`\\\n  Interval between re-delivering dead letters, in seconds.\\\n  Default: 3600.\n\n- `--debug`\\\n  Show communications between the IMAP server.\n\n- `-h`, `--help`\\\n  Prints the help.\n\n\n## Message Delivery Reliability\n\n`imap-watcher` struggles to deliver massage at-least-once.  If `imap-watcher` exits abnormally, it will deliver the mail on the next time.  Nevertheless, it may lose mails if mails are deleted on the server before delivered.\n\nTo be precise, If the command returns non-zero exit status, dead letter command given by `--dead-letter-command`, default to the command given by `--command`, is invoked, and if the command returns non-zero exit status again, the mail is queued to the dead letter queue.  Then mails in the dead letter queue will be re-delivered at start up and at intervals of `--dead-letter-retry-interval` seconds.\n\n## Data Stored by `imap-watcher`\n\nA SQLite3 database is created at `~/.local/share/imap-watcher/mails.sqlite3` or any path specified by `--database`.  It contains known message IDs, last known `UID` and `UIDVALIDITY`, and the dead letter queue.\n\n\n## Developping\n\n```sh\n# Run linters.\nbundle exec rake lint\n\n# Generate YARD documents.\nbundle exec rake doc\n```\n\n## License\n\nMIT.  See [LICENSE.md](./LICENSE.md) for details.  Copyright (c) 2023 taku0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaku0%2Fimap-watcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftaku0%2Fimap-watcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaku0%2Fimap-watcher/lists"}