omamail README

The project's README from github.com/huacnlee/omamail. As one markdown file: README.md.

Omamail

Your mail as a native Omarchy window — not a browser tab.

Omamail is an Omarchy desktop email client: a Quickshell plugin that reads, triages, and answers your mail over the official Gmail API, through Microsoft OAuth for Outlook, over the HEY CLI client 37signals publish, over JMAP, or over IMAP and SMTP for every other mailbox. It runs inside the omarchy-shell process you already have, follows your active theme, and puts an unread count in the bar.

Omamail - Reading mail with AI assistance for selected messages

The calendar, a new message, and the question every new mailbox starts with:

Omamail - The calendar in month view Omamail - Writing a new message Omamail - Adding a mailbox: Gmail, HEY or IMAP

And with mini size mode:

Omamail - Mini size: the message list Omamail - Mini size: one message open Omamail - Mini size: writing a new message

Works with Gmail, HEY, Fastmail, iCloud Mail, Outlook, Yahoo, Zoho, GMX, Proton Mail (through its Bridge), and any server that speaks JMAP or IMAP — including one you run yourself.

Features

What it is

Three parts, one plugin:

Add it to Omarchy

omarchy plugin add https://github.com/huacnlee/omamail.git --enable

Then click the envelope in the bar. To open it from the keyboard, add this to ~/.config/hypr/bindings.lua:

  o.bind("SUPER + SHIFT + G", "Omamail", "omarchy shell shell toggle omamail '{}'")

The target is shell, not the plugin id: the window is summoned by the shell, which is what loads it in the first place. A plugin-scoped target would have to be registered by code that is only running once the window is already open.

Once the plugin is enabled, Omamail handles mailto: links. Clicking an address in a browser, a PDF, or a notification opens compose here. xdg-open mailto:[email protected] is the check.

Requires Omarchy 4, plus socat, secret-tool, openssl, xdg-open, python3 and curl. Python handles remote images, one-click unsubscribe and attachments; curl handles IMAP, SMTP and CalDAV. A HEY mailbox additionally needs hey; see below.

Mailboxes it can open

Adding a mailbox asks which kind first, because the four setups have nothing in common.

Gmail signs in with Google directly. Google issues Gmail API access per project, so this route needs an OAuth client you create once — the setup page walks through it. In exchange it gets labels, conversations, Gmail's own search syntax, and a "report spam" that Google actually learns from.

Outlook signs in on Microsoft's own page and uses [Microsoft's supported OAuth route for IMAP and SMTP][microsoft-mail-oauth]. It works with Outlook.com, Hotmail, Live and MSN accounts; Omamail never asks for the Microsoft account password. Until Omamail ships a maintainer-owned public client, the setup page asks for an Application (client) ID from a one-time Microsoft Entra app registration. Make it a public client for personal Microsoft accounts; the sign-in asks for IMAP.AccessAsUser.All, SMTP.Send and offline_access and shows the device code to enter in the Microsoft page it opens.

Before signing in, enable IMAP in Outlook.com: Settings > Mail > Forwarding and IMAP > Let devices and apps use IMAP, then save. Microsoft disables IMAP by default; OAuth consent alone does not enable mailbox access. See Microsoft's IMAP setup instructions.

HEY needs no address and no password. HEY publishes no IMAP, no POP and no public API, so Omamail reads it through the [HEY CLI][hey-cli] client 37signals ship for exactly this — which means the sign-in, the token and the keyring entry it lives in are all hey's, and Omamail never asks for your HEY password.

Install it once:

omarchy-mise-install github:basecamp/hey-cli hey

Recent versions of Omarchy install it for you as a lazy mise tool, so that line is only for doing it by hand; [37signals' own installer][hey-cli] is the other route. Either way it lands in ~/.local/bin, which is where Omamail looks when it is not already on PATH. Then choose HEY on the setup page and press Sign in to HEY — that opens HEY in your browser, and nothing else is asked of you.

The rail is HEY's own: Imbox, New for you, Reply Later, Set Aside, The Feed and Paper Trail. No Sent — HEY's API has one, but hey does not serve it yet: there is no hey box sent, and search only scopes to the Imbox, the Feed, Paper Trail and Trash. When the client gains it, it is one more line in the rail.

What HEY does not have, the panel does not offer: no star and no archive, because HEY moves a thread to one of those boxes instead, and a key that quietly meant "file this in Paper Trail" would be a promise this could not keep — e and s say so rather than pretending. Reading, marking read, replying, searching, labels, trashing and a "report spam" HEY trains its filter on all work.

Three more differences worth knowing. A HEY row is a conversation, not a single message. Message bodies read as hey serves them — as the sender's own HTML where your hey is new enough to hand it over, and as text elsewhere; Omamail asks for the richer one every time and takes whichever comes back, so upgrading hey improves it with nothing to change here. And the meeting card, the one-click unsubscribe, attachments and the Screener are all read out of parts of a message that hey does not serve, or out of an endpoint it does not expose — so they stay in HEY's own app, which the setup page links to.

JMAP is an address and an app password or an API token — Fastmail, a Stalwart server of your own, or anything else that speaks the protocol. Discovery starts at https://<your-address-domain>/.well-known/jmap. If your domain does not serve that endpoint, enter the server URL under Server settings. Discovery uses HTTPS and may follow its authenticated redirect; an unsigned DNS SRV record cannot choose where your credential goes. The credential goes to that server and to the addresses inside its session object.

Where a server offers JMAP and IMAP alike, this is the better of the two. A JMAP row is a conversation rather than a single message, and the reader draws a rail of that conversation's other messages down its side — n and p walk it. Mail also arrives when the server sends it rather than when the next check comes round: every signed-in JMAP mailbox holds one event stream open whether or not the window is, so a message that lands on the server is in the list about a second later.

What your particular server does not have, the panel does not offer — and here that is a fact about your account rather than about the protocol. A server with no Archive mailbox has no Archive row and no e; one whose Junk folder trains nothing has no "report spam"; a credential that cannot submit mail makes the mailbox read-only. Each of them says which it is instead of failing after you have pressed it.

IMAP is an address and a password. Fastmail, iCloud, Zoho, GMX, Proton via its Bridge, or a server of your own: the servers are filled in from the address for the ones this knows, and shown behind a disclosure so they can be corrected for the ones it does not. Most providers want an app password rather than the one you sign in to their website with, and the form says so before you find out the hard way.

What IMAP does not have, the panel does not offer: no labels, no server-side conversations, no "report spam" — moving a message to a Junk folder teaches a server nothing, and a button that quietly meant that would be a promise this could not keep. Archive appears only when the server has an archive folder to move to. Sending goes out over SMTP, or the mailbox is read-only if no SMTP server is set.

The sent copy is filed by Omamail rather than left to the server: a message handed to SMTP submission lands nowhere on its own. It goes to the server's own Sent folder, named by the server rather than guessed, and arrives already marked read; a server that reports no Sent folder holds no copy, and the status row says so. One thing worth knowing: a Gmail account read over IMAP has Google file its own copy of anything sent through Gmail's SMTP, so those accounts hold two.

To remove it:

omarchy plugin remove omamail

That takes the plugin itself. Nothing it wrote lives inside your Omarchy config, so removing those is separate and entirely up to you:

secret-tool clear service omamail    # refresh tokens and JMAP and IMAP passwords
hey auth logout                      # the HEY session, if you added one
rm -rf ~/.config/omamail             # the OAuth client and account list
rm -rf ~/.cache/omamail              # cached mail
rm ~/.local/share/applications/omamail.desktop

Signing out from inside the app clears the keyring entry on its own. The plugin never edits your shell, Hyprland or theme configuration. The keybinding above and the mailto desktop file are yours to add and yours to remove.

Connecting your mailbox

Gmail has no shared application to sign in through. Google issues API access per Cloud project, so Omamail signs in with an OAuth client you own. The window walks you through it in five steps, each with the console page one click away. It takes about two minutes, once.

The step people skip, and the one that decides whether the sign-in lasts: press "Publish app" on your own project. A project left in Testing is issued refresh tokens that expire after seven days, so the app would sign you out every week. Publishing shows an "unverified app" warning once — expected for a client you made yourself, since you are the developer and the only user.

If you have the gcloud CLI, scripts/google-cloud-project.sh does the two steps that have an API — creating the project and enabling Gmail — and opens the console on the rest with the project already selected. The consent screen and the client itself are console-only; there is no CLI for them.

Why isn't a client built in? gmail.modify and gmail.send are restricted scopes. Shipping a client would mean this project completing Google's OAuth verification first; until then it would be stuck in Testing, handing every user a seven-day session. The code is ready for one — Credentials.BUILTIN is a single constant — and your own client always wins over it.

Using it

Right-click does the rest. On a label in the rail: rename it, make a label beside or beneath it, move it under another, delete it, or watch it for new mail — a watched label counts its unread on every refresh and shows an eye. On the reader's From or To line: copy the address, or search the mailbox for mail from it or to it.

Key What it does
j / k Move down / up
Enter or o Open the selected message
n / p Next / previous message in the conversation
Esc Back to the list; close the window from the list
e Archive
d Move to trash
s Star or unstar
v Move to a label or folder
Shift+I / Shift+U Mark read / unread
r / a / f Reply, reply all, forward
c Compose
Ctrl+Enter Send
/ Search
Alt+1 … Alt+0 The mailbox with that number on the rail
Alt+A Switch account
Space / x Select the message; e, d, s, v, Shift+I, Shift+U then act on every selected one
Ctrl+A Select every message loaded, or none
Alt+G Open AI assistance for the message, selection, or draft in the right dock
Ctrl+= / Ctrl+- / Ctrl+0 Zoom the message body, or reset it
F5 / Ctrl+R Check for mail
? Every shortcut

To act on several messages, hold Ctrl to replace the row actions with checkboxes, or Ctrl+click a row to select or deselect it without opening it. Checkboxes stay visible while any message is selected; releasing Ctrl with no selection restores the usual actions. Space or x toggles the keyboard cursor's row. Shift+click selects the range from the cursor to an unchecked row, or clears that range when the clicked row is already checked; other selections stay as they are. In the list, Ctrl+A selects every loaded message or clears the selection, and Esc clears an active selection before going back. The status bar shows how many messages are selected; archive, trash, star, move and read/unread actions apply to that selection while the list is visible.

Search paints matching cached rows first and adds server results as they arrive. It takes Gmail's own operator syntax straight through — from:jane, has:attachment, older_than:7d. The Unread mailbox leaves Promotions, Social and Forums out rather than asking for Primary: Gmail's categories do not remove the INBOX label, so an unread filter without that exclusion comes back as the whole promotional backlog rather than the mail you have not read — while one that asks for Primary comes back empty on any account where Gmail is not applying the category labels, which is unread mail with nothing left to say so. Updates stays in, because receipts, deliveries and notifications land there. Right-click any row in the list for archive, trash, spam, star and read/unread without leaving the keyboard cursor behind.

AI assistance uses the default AI selected in Omarchy, with no separate Omamail AI settings. Use the outline AI icon button beside Compose, the message menu, or Alt+G. Type a multiline question or use / for common commands, then Enter to send or Shift+Enter for a new line. The … menu opens new chats and conversation history. Results return to the right dock; draft suggestions can be inserted or replace the body after review. The panel streams the conversation and supports follow-up questions without opening a terminal. The background adapter currently supports Claude. See AI assistance.

A signature is set per mailbox on the settings page, under Writing. It is placed under a new message and above the quoted text in a reply, so a sign-off stays next to the words it signs rather than stranded below a screen of somebody else's message. It is sent exactly as typed — no -- line is added in front of it, because a client that adds one turns a signature into two decisions, and the line is one keystroke away for anybody who wants it. Each mailbox keeps its own: two addresses are two identities, and one sign-off under both is wrong for whichever it was not written for. A saved draft is reopened as it was written, so resuming one never signs it twice.

What it does not do

Remote images in a message body are blocked until you ask for them, and asking covers that one message. Qt

omamail (huacnlee/omamail)

Searching Database…

这是什么?Omamail 是面向 Omarchy 桌面(基于 Hyprland/Quickshell 构建)的原生电子邮件客户端插件,可以在一个统一主题的窗口中读取、整理并回复来自 Gmail、Outlook、HEY、JMAP 和 IMAP 账户的邮件。
这是一个独立的邮件应用,还是需要依赖其他程序运行?它是一个 Quickshell 插件,运行在 Omarchy 桌面上已在运行的 omarchy-shell 进程之中,而不是一个独立的应用程序。
怎么把它添加到我的 Omarchy 中?启用插件并点击栏中的信封图标即可;如果想用快捷键打开它,需要在 ~/.config/hypr/bindings.lua 中添加一条指向 'shell'(而不是插件 id)的绑定。
除了 Omarchy 本身还需要安装什么?它需要 Omarchy 4,以及 socat、secret-tool、openssl、xdg-open、python3 和 curl;使用 HEY 邮箱还需要单独的 HEY CLI 工具。
连接 HEY 账户时会有什么不同或缺什么?HEY 不提供 IMAP 也没有公开 API,所以 Omamail 只能通过 HEY CLI 与它交互:没有加星标或归档(HEY 会把会话归入它自己的信箱),还没有已发送箱,而会议卡片、一键退订和附件则只能留在 HEY 自己的应用里。
我的邮箱密码和令牌保存在哪里?Gmail 和 Outlook 的刷新令牌以及所有 JMAP/IMAP 密码都存储在 GNOME Keyring 中;HEY 邮箱在这里完全不保存任何凭据,因为 HEY CLI 自己持有令牌。
除了 Gmail 和 HEY 还能连接哪些提供商?通过 Microsoft OAuth 连接 Outlook,以及任何 JMAP 或 IMAP/SMTP 服务器,涵盖 Fastmail、iCloud Mail、Yahoo、Zoho、GMX,还有通过 Bridge 接入的 Proton Mail。
能在应用内回复会议邀请吗?可以,会议卡片直接从邮件的日历部分读取,按你自己的时区显示时间,在 Gmail 和 IMAP 上你可以一键回复“是”“可能”或“否”,或一键加入 Google Meet 链接。
它能处理阿拉伯语或希伯来语这类从右到左的语言吗?可以,阿拉伯语、希伯来语或波斯语邮件会从右到左排版,包括主题、列表行和正文,而旁边的英文邮件仍保持从左到右,并且无论会话方向如何,“Re:”前缀都保持拉丁字母。
为什么不能在单独的窗口里打开写信界面?在 Omarchy 的面板机制下,第二个窗口会占用自己独立的屏幕区域,所以写信和回复都在同一个应用窗口内进行。
Creator
huacnlee
Size
13.7 MB
Stars
302
Age
2mo
Commits · 90 Days