aboutsummaryrefslogtreecommitdiffstats
path: root/home/mail
diff options
context:
space:
mode:
Diffstat (limited to 'home/mail')
-rw-r--r--home/mail/default.nix244
1 files changed, 244 insertions, 0 deletions
diff --git a/home/mail/default.nix b/home/mail/default.nix
new file mode 100644
index 0000000..2b2b031
--- /dev/null
+++ b/home/mail/default.nix
@@ -0,0 +1,244 @@
+{ pkgs, config, ... }:
+
+let
+ # Common configuration for Gmail-based accounts
+ mkGmailAccount =
+ {
+ name,
+ address,
+ userName,
+ passwordCommand,
+ primary ? false,
+ }:
+ let
+ accountConfig = {
+ inherit
+ primary
+ address
+ userName
+ passwordCommand
+ ;
+ realName = "Petri Hienonen";
+
+ imap = {
+ host = "imap.gmail.com";
+ port = 993;
+ tls.enable = true;
+ };
+
+ smtp = {
+ host = "smtp.gmail.com";
+ port = 587;
+ tls.enable = true;
+ };
+
+ maildir = {
+ path = name;
+ };
+
+ mbsync = {
+ enable = true;
+ create = "both";
+ expunge = "both";
+ remove = "both";
+ patterns = [
+ "*"
+ "!Drafts"
+ "!Sent Mail"
+ ];
+ extraConfig.channel = {
+ CopyArrivalDate = "yes";
+ SyncState = "*";
+ };
+ };
+
+ notmuch.enable = true;
+
+ himalaya = {
+ enable = true;
+ settings = {
+ inherit primary;
+ display-name = "Petri Hienonen";
+ signature = "Regards,\nPetri Hienonen";
+ signature-delim = "-- \n";
+
+ "backend.type" = "notmuch";
+ "backend.db-path" = "${config.home.homeDirectory}/Mail/${name}";
+
+ "folder.aliases.inbox" = "INBOX";
+ "folder.aliases.sent" = "Sent Mail";
+ "folder.aliases.drafts" = "Drafts";
+ "folder.aliases.trash" = "Trash";
+
+ "message.write.headers" = [
+ "From"
+ "To"
+ "Cc"
+ "Bcc"
+ "Subject"
+ ];
+ "message.send.save-copy" = true;
+ "message.delete.style" = "folder";
+
+ "template.new.signature-style" = "inlined";
+ "template.reply.posting-style" = "top";
+ "template.reply.signature-style" = "below-quote";
+ "template.reply.quote-headline-fmt" = "On %d/%m/%Y %H:%M, {senders} wrote:\n";
+
+ "message.send.backend.type" = "smtp";
+ "message.send.backend.host" = "smtp.gmail.com";
+ "message.send.backend.port" = 465;
+ "message.send.backend.login" = userName;
+ "message.send.backend.auth.type" = "password";
+ "message.send.backend.auth.cmd" = passwordCommand;
+
+ "pgp.type" = "commands";
+ "pgp.encrypt-cmd" = "${pkgs.gnupg}/bin/gpg --encrypt --armor --quiet -r '%r'";
+ "pgp.decrypt-cmd" = "${pkgs.gnupg}/bin/gpg --decrypt --quiet";
+ "pgp.sign-cmd" = "${pkgs.gnupg}/bin/gpg --sign --armor --quiet --default-key '%s'";
+ "pgp.verify-cmd" = "${pkgs.gnupg}/bin/gpg --verify --quiet";
+ };
+ };
+
+ aerc = {
+ enable = true;
+ };
+
+ imapnotify = {
+ enable = true;
+ boxes = [ "INBOX" ];
+ onNotify = emailNotifyScript name;
+ extraConfig.wait = 60;
+ };
+ };
+ in
+ accountConfig;
+
+ # Simplified notification script that only extracts sender and subject
+ emailNotifyScript =
+ account:
+ pkgs.writeShellScript "email-notify-${account}" ''
+ set -euo pipefail
+
+ # Sync this account specifically
+ ${pkgs.isync}/bin/mbsync "${account}"
+
+ # Wait a moment for notmuch to index
+ sleep 2
+ ${pkgs.notmuch}/bin/notmuch new
+
+ LATEST_MSG=$(${pkgs.notmuch}/bin/notmuch search --output=messages --limit=1 "tag:unread and folder:${account}/INBOX" | head -1)
+
+ if [ -n "$LATEST_MSG" ]; then
+ # Extract sender and subject using notmuch show
+ SENDER=$(${pkgs.notmuch}/bin/notmuch show --format=json "$LATEST_MSG" | ${pkgs.jq}/bin/jq -r '.[][0].headers.From // "Unknown sender"')
+ SUBJECT=$(${pkgs.notmuch}/bin/notmuch show --format=json "$LATEST_MSG" | ${pkgs.jq}/bin/jq -r '.[][0].headers.Subject // "No subject"')
+
+ # Send notification
+ ${pkgs.libnotify}/bin/notify-send -i mail-unread -a "Email" \
+ "New email in ${account}" \
+ "From: $SENDER\nSubject: $SUBJECT" \
+ -t 10000 # 10 second timeout
+ fi
+ '';
+
+in
+{
+ accounts.email = {
+ maildirBasePath = "${config.home.homeDirectory}/Mail";
+
+ accounts = {
+ gmail = mkGmailAccount {
+ name = "gmail";
+ primary = true;
+ address = "petri.hienonen@gmail.com";
+ userName = "petri.hienonen@gmail.com";
+ passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.gmail.path}";
+ };
+
+ relesoft = mkGmailAccount {
+ name = "relesoft";
+ primary = false;
+ address = "petri.hienonen@relesoft.io";
+ userName = "petri.hienonen@relesoft.io";
+ passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.relesoft.path}";
+ };
+ };
+ };
+
+ # Global settings for programs (not account-specific)
+ programs.mbsync.enable = true;
+
+ programs.notmuch = {
+ enable = true;
+ hooks = {
+ preNew = "${pkgs.isync}/bin/mbsync -a || true";
+ };
+ new = {
+ tags = [
+ "new"
+ "unread"
+ ];
+ ignore = [
+ "/.*[.](json|lock|bak)$/"
+ ".uidvalidity"
+ ".mbsyncstate"
+ ".mbsyncstate.journal"
+ ".msoepln"
+ ".mbsyncstate.new"
+ ".mbsyncstate.lock"
+ ];
+ };
+ };
+
+ programs.himalaya = {
+ enable = true;
+ package = pkgs.himalaya.override {
+ withFeatures = [
+ "notmuch"
+ "pgp-gpg"
+ ];
+ };
+ };
+
+ # aerc configuration
+ programs.aerc = {
+ enable = true;
+ # aerc will automatically pick up accounts from accounts.email
+ # Additional aerc-wide configuration can go here
+ extraConfig = {
+ general = {
+ unsafe-accounts-conf = true;
+ # Example aerc configuration
+ # ui.message-list-time-format = "2006-01-02 15:04"
+ # ui.timestamp-format = "2006-01-02 15:04"
+ };
+ };
+ };
+
+ systemd.user.services.mbsync = {
+ Unit = {
+ Description = "Sync mail with mbsync";
+ After = [ "network-online.target" ];
+ Wants = [ "network-online.target" ];
+ };
+ Service = {
+ Type = "oneshot";
+ ExecStart = "${pkgs.isync}/bin/mbsync -a";
+ };
+ Install.WantedBy = [ "default.target" ];
+ };
+
+ systemd.user.timers.mbsync = {
+ Unit = {
+ Description = "Timer for mbsync mail synchronization";
+ Requires = "mbsync.service";
+ };
+ Timer = {
+ OnBootSec = "5m";
+ OnUnitInactiveSec = "5m";
+ Unit = "mbsync.service";
+ };
+ Install.WantedBy = [ "timers.target" ];
+ };
+}