summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergio Pastor Pérez <sergio.pastorperez@gmail.com>2026-07-22 14:28:07 +0200
committerLudovic Courtès <ludo@gnu.org>2026-08-21 23:18:11 +0200
commit58091d1b6e33d978b06ea05e3dedb3203720a64d (patch)
treefa6b9d5145ace34139eada51e9d7efd52fae16dd
parent0837a51e66580f58af7c2e8c17e22c5bd3d80039 (diff)
services: Add home-goimapnotify-service-type.
* doc/guix.texi (Mail Home Services): Document 'home-goimapnotify-service-type' and 'home-goimapnotify-configuration'. * gnu/home/services/mail.scm (camelize-field-name) (goimapnotify-serialize-field, goimapnotify-serialize-boolean): New procedure. (field-name-mapping): New parameter. (goimapnotify-tls-options-configuration): New configuration. (goimapnotify-serialize-string, goimapnotify-serialize-maybe-string) (goimapnotify-serialize-string-or-gexp): New procedure. (goimapnotify-serialize-maybe-string-or-gexp): New maybe type. * gnu/home/services/mail.scm (goimapnotify-box-configuration): New configuration. (serialize-goimapnotify-tls-options-configuration): New maybe type. (goimapnotify-tls-options-configuration): New configuration.:(list-of-goimapnotify-boxes-configurations?): New procedure. (serialize-list-of-goimapnotify-boxes-configurations): New configuration. (goimapnotify-configuration): New configuration. (serialize-goimapnotify-configuration)::(list-of-goimapnotify-configurations?) (serialize-list-of-goimapnotify-configurations): New procedure. (home-goimapnotify-configuration): New configuration. (home-goimapnotify-shepherd-service): New service. (home-goimapnotify-service-type): New service type. Signed-off-by: Ludovic Courtès <ludo@gnu.org> Merges: #10104
-rw-r--r--doc/guix.texi169
-rw-r--r--gnu/home/services/mail.scm255
2 files changed, 423 insertions, 1 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index f19cb4f1ee6..555fd082471 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -55455,7 +55455,10 @@ Extra content to add to the end of @file{~/.config/alsa/asoundrc}.
55455The @code{(gnu home services mail)} module provides services that help 55455The @code{(gnu home services mail)} module provides services that help
55456you set up the tools to work with emails in your home environment. 55456you set up the tools to work with emails in your home environment.
55457 55457
55458@subsubheading MSMTP Service
55458@cindex msmtp 55459@cindex msmtp
55460@cindex mail configuration, for outgoing mail
55461
55459@uref{https://marlam.de/msmtp, MSMTP} is a @acronym{SMTP, Simple Mail 55462@uref{https://marlam.de/msmtp, MSMTP} is a @acronym{SMTP, Simple Mail
55460Transfer Protocol} client. It sends mail to a predefined SMTP server 55463Transfer Protocol} client. It sends mail to a predefined SMTP server
55461that takes care of proper delivery. 55464that takes care of proper delivery.
@@ -55584,6 +55587,172 @@ format.
55584 55587
55585@c %end of fragment 55588@c %end of fragment
55586 55589
55590@subsubheading Goimapnotify Service
55591@cindex IMAP notifications
55592
55593@defvar home-goimapnotify-service-type
55594This is the type of the service that runs
55595@uref{https://gitlab.com/shackra/goimapnotify, Goimapnotify}, a
55596command-line application to execute scripts on IMAP mailbox changes
55597using @uref{https://www.rfc-editor.org/info/rfc2177, IDLE}. Its value
55598is a @code{home-goimapnotify-configuration} object.
55599@end defvar
55600
55601Here is a snippet of the service with an example configuration that you
55602could add to the @code{services} field of your @code{home-environment}:
55603
55604@lisp
55605(service home-goimapnotify-service-type
55606 (home-goimapnotify-configuration
55607 (configurations
55608 (list
55609 (goimapnotify-configuration
55610 (host "imap.example.com")
55611 (tls? #t)
55612 (tls-options
55613 (goimapnotify-tls-options-configuration
55614 (reject-unauthorized? #t)))
55615 (user-name "alice@@example.com")
55616 (password-command
55617 #~(string-append #$(file-append libsecret "/bin/secret-tool")
55618 " lookup user alice@@example.com"))
55619 (boxes
55620 (list
55621 (goimapnotify-box-configuration
55622 (mailbox "Inbox")
55623 (on-new-mail
55624 #~(string-append #$(file-append isync "/bin/mbsync")
55625 " alice"))
55626 (on-new-mail-post
55627 #~(string-append #$(file-append notmuch "/bin/notmuch")
55628 " new"))))))))))
55629@end lisp
55630
55631@c %start of fragment
55632
55633@deftp {Data Type} home-goimapnotify-configuration
55634Available @code{home-goimapnotify-configuration} fields are:
55635
55636@table @asis
55637@item @code{goimapnotify} (default: @code{goimapnotify}) (type: file-like)
55638The @code{goimapnotify} package to use.
55639
55640@item @code{configurations} (type: list-of-goimapnotify-configurations)
55641A list of @code{goimapnotify-configuration} records which contain
55642information about all your accounts configurations.
55643
55644@end table
55645
55646@end deftp
55647
55648
55649@c %end of fragment
55650
55651@c %start of fragment
55652
55653@deftp {Data Type} goimapnotify-configuration
55654Available @code{goimapnotify-configuration} fields are:
55655
55656@table @asis
55657@item @code{host} (type: string)
55658The IMAP server hostname.
55659
55660@item @code{host-command} (type: maybe-string-or-gexp)
55661Command to retrieve the IMAP server hostname.
55662
55663@item @code{port} (default: @code{993}) (type: integer)
55664The port that the IMAP server listens on.
55665
55666@item @code{tls?} (default: @code{#f}) (type: boolean)
55667Enable or disable TLS.
55668
55669@item @code{tls-options} (type: maybe-goimapnotify-tls-options-configuration)
55670TLS options for the IMAP connection.
55671
55672@item @code{idle-logout-timeout} (type: maybe-integer)
55673The idle logout timeout in minutes.
55674
55675@item @code{user-name} (type: maybe-string)
55676The user-name for authentication.
55677
55678@item @code{user-name-command} (type: maybe-string-or-gexp)
55679Command to retrieve the user-name.
55680
55681@item @code{alias} (type: maybe-string)
55682An alias for the account.
55683
55684@item @code{password} (type: maybe-string)
55685The password for authentication.
55686
55687@item @code{password-command} (type: maybe-string-or-gexp)
55688Command to retrieve the password.
55689
55690@item @code{xo-auth2?} (default: @code{#f}) (type: boolean)
55691Enable or disable XOAUTH2 authentication.
55692
55693@item @code{boxes} (type: list-of-goimapnotify-boxes-configurations)
55694The mailboxes to monitor.
55695
55696@end table
55697
55698@end deftp
55699
55700
55701@c %end of fragment
55702
55703@c %start of fragment
55704
55705@deftp {Data Type} goimapnotify-box-configuration
55706Available @code{goimapnotify-box-configuration} fields are:
55707
55708@table @asis
55709@item @code{mailbox} (type: string)
55710The mailbox to monitor.
55711
55712@item @code{on-new-mail} (type: maybe-string-or-gexp)
55713Command to execute when new mail arrives.
55714
55715@item @code{on-new-mail-post} (type: maybe-string-or-gexp)
55716Command to execute after the new-mail command.
55717
55718@item @code{on-changed-mail} (type: maybe-string-or-gexp)
55719Command to execute when mail is changed.
55720
55721@item @code{on-changed-mail-post} (type: maybe-string-or-gexp)
55722Command to execute after the changed-mail command.
55723
55724@item @code{on-deleted-mail} (type: maybe-string-or-gexp)
55725Command to execute when mail is deleted.
55726
55727@item @code{on-deleted-mail-post} (type: maybe-string-or-gexp)
55728Command to execute after the deleted-mail command.
55729
55730@end table
55731
55732@end deftp
55733
55734
55735@c %end of fragment
55736
55737@c %start of fragment
55738
55739@deftp {Data Type} goimapnotify-tls-options-configuration
55740Available @code{goimapnotify-tls-options-configuration} fields are:
55741
55742@table @asis
55743@item @code{reject-unauthorized?} (default: @code{#f}) (type: boolean)
55744Whether to reject unauthorized TLS certificates.
55745
55746@item @code{starttls?} (default: @code{#f}) (type: boolean)
55747Whether to use STARTTLS.
55748
55749@end table
55750
55751@end deftp
55752
55753
55754@c %end of fragment
55755
55587@node Messaging Home Services 55756@node Messaging Home Services
55588@subsection Messaging Home Services 55757@subsection Messaging Home Services
55589 55758
diff --git a/gnu/home/services/mail.scm b/gnu/home/services/mail.scm
index 78d614dc842..78a2ec3c520 100644
--- a/gnu/home/services/mail.scm
+++ b/gnu/home/services/mail.scm
@@ -17,12 +17,14 @@
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. 17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18 18
19(define-module (gnu home services mail) 19(define-module (gnu home services mail)
20 #:use-module (guix records)
20 #:use-module (guix gexp) 21 #:use-module (guix gexp)
21 #:use-module (gnu services) 22 #:use-module (gnu services)
22 #:use-module (gnu services configuration) 23 #:use-module (gnu services configuration)
23 #:use-module (gnu home services) 24 #:use-module (gnu home services)
24 #:use-module (gnu home services shepherd) 25 #:use-module (gnu home services shepherd)
25 #:use-module (gnu packages mail) 26 #:use-module (gnu packages mail)
27 #:use-module (ice-9 match)
26 #:use-module (ice-9 string-fun) 28 #:use-module (ice-9 string-fun)
27 #:use-module (srfi srfi-1) 29 #:use-module (srfi srfi-1)
28 #:use-module (srfi srfi-26) 30 #:use-module (srfi srfi-26)
@@ -47,7 +49,13 @@
47 msmtp-configuration-extra-content 49 msmtp-configuration-extra-content
48 msmtp-account 50 msmtp-account
49 msmtp-account-name 51 msmtp-account-name
50 msmtp-account-configuration)) 52 msmtp-account-configuration
53
54 goimapnotify-tls-options-configuration
55 goimapnotify-box-configuration
56 goimapnotify-configuration
57 home-goimapnotify-configuration
58 home-goimapnotify-service-type))
51 59
52(define (string-or-gexp? obj) 60(define (string-or-gexp? obj)
53 (or (string? obj) 61 (or (string? obj)
@@ -228,3 +236,248 @@ format."
228 (description "Configure msmtp, a simple 236 (description "Configure msmtp, a simple
229@acronym{SMTP, Simple Mail Transfer Protocol} client that can relay email 237@acronym{SMTP, Simple Mail Transfer Protocol} client that can relay email
230to SMTP servers."))) 238to SMTP servers.")))
239
240
241;;; Goimapnotify.
242
243;; Mapping used by 'camelize-field-name' to handle certain symbols specially.
244(define field-name-mapping
245 (make-parameter '()))
246
247(define (camelize-field-name field-name)
248 (let* ((str (symbol->string (or (assq-ref (field-name-mapping) field-name)
249 field-name)))
250 (words (string-split (if (string-suffix? "?" str)
251 (string-drop-right str 1)
252 str)
253 #\-)))
254 (match words
255 ((head . tail)
256 (string-concatenate (cons* head
257 (map string-capitalize tail)))))))
258
259(define (goimapnotify-serialize-field field-name val)
260 (parameterize ((field-name-mapping
261 '((host-command . hostCmd)
262 (user-name . username)
263 (user-name-command . usernameCmd)
264 (password-command . passwordCmd))))
265 #~(format #f "~a: ~s\n"
266 #$(camelize-field-name field-name)
267 #$val)))
268
269(define (goimapnotify-serialize-boolean field-name val)
270 (goimapnotify-serialize-field field-name (if val ''true ''false)))
271
272(define-configuration goimapnotify-tls-options-configuration
273 (reject-unauthorized?
274 (boolean #f)
275 "Whether to reject unauthorized TLS certificates.")
276
277 (starttls?
278 (boolean #f)
279 "Whether to use STARTTLS.")
280
281 (prefix goimapnotify-))
282
283;; XXX: The 'define-maybe' macros of the MSMTP configuration already define
284;; the maybe types, so we just need to define the extra serializers.
285
286(define (goimapnotify-serialize-string field-name val)
287 (goimapnotify-serialize-field field-name val))
288
289(define (goimapnotify-serialize-maybe-string field-name val)
290 (if (maybe-value-set? val)
291 (goimapnotify-serialize-string field-name val)
292 ""))
293
294(define goimapnotify-serialize-string-or-gexp
295 goimapnotify-serialize-string)
296
297(define (goimapnotify-serialize-maybe-string-or-gexp field-name val)
298 (if (and (maybe-value-set? val)
299 (string-or-gexp? val))
300 (goimapnotify-serialize-string-or-gexp field-name val)
301 ""))
302
303(define-configuration goimapnotify-box-configuration
304 (mailbox
305 string
306 "The mailbox to monitor.")
307
308 (on-new-mail
309 maybe-string-or-gexp
310 "Command to execute when new mail arrives.")
311
312 (on-new-mail-post
313 maybe-string-or-gexp
314 "Command to execute after the new-mail command.")
315
316 (on-changed-mail
317 maybe-string-or-gexp
318 "Command to execute when mail is changed.")
319
320 (on-changed-mail-post
321 maybe-string-or-gexp
322 "Command to execute after the changed-mail command.")
323
324 (on-deleted-mail
325 maybe-string-or-gexp
326 "Command to execute when mail is deleted.")
327
328 (on-deleted-mail-post
329 maybe-string-or-gexp
330 "Command to execute after the deleted-mail command.")
331
332 (prefix goimapnotify-))
333
334(define (goimapnotify-serialize-integer field-name val)
335 (goimapnotify-serialize-field field-name val))
336
337(define (goimapnotify-serialize-maybe-integer field-name val)
338 (if (maybe-value-set? val)
339 (goimapnotify-serialize-integer field-name val)
340 ""))
341
342(define (serialize-goimapnotify-tls-options-configuration field-name val)
343 (serialize-configuration val goimapnotify-tls-options-configuration-fields))
344
345(define-maybe goimapnotify-tls-options-configuration)
346
347(define (list-of-goimapnotify-boxes-configurations? lst)
348 (and (not (null? lst))
349 (every goimapnotify-box-configuration? lst)))
350
351(define (serialize-list-of-goimapnotify-boxes-configurations field-name value)
352 (let ((serializations (cons 'list
353 (map (cut serialize-configuration <>
354 goimapnotify-box-configuration-fields)
355 value))))
356 #~(begin
357 (use-modules (ice-9 format) (ice-9 string-fun))
358 (format #f "~a:
359~{ - ~a~%~}"
360 '#$field-name
361 (map (lambda (s)
362 (string-replace-substring s "\n" "\n "))
363 #$serializations)))))
364
365(define-configuration goimapnotify-configuration
366 (host
367 string
368 "The IMAP server hostname.")
369
370 (host-command
371 maybe-string-or-gexp
372 "Command to retrieve the IMAP server hostname.")
373
374 (port
375 (integer 993)
376 "The port that the IMAP server listens on.")
377
378 (tls?
379 (boolean #f)
380 "Enable or disable TLS.")
381
382 (tls-options
383 maybe-goimapnotify-tls-options-configuration
384 "TLS options for the IMAP connection."
385 (serializer serialize-maybe-goimapnotify-tls-options-configuration))
386
387 (idle-logout-timeout
388 maybe-integer
389 "The idle logout timeout in minutes.")
390
391 (user-name
392 maybe-string
393 "The user-name for authentication.")
394
395 (user-name-command
396 maybe-string-or-gexp
397 "Command to retrieve the user-name.")
398
399 (alias
400 maybe-string
401 "An alias for the account.")
402
403 (password
404 maybe-string
405 "The password for authentication.")
406
407 (password-command
408 maybe-string-or-gexp
409 "Command to retrieve the password.")
410
411 (xo-auth2?
412 (boolean #f)
413 "Enable or disable XOAUTH2 authentication.")
414
415 (boxes
416 list-of-goimapnotify-boxes-configurations
417 "The mailboxes to monitor."
418 (serializer serialize-list-of-goimapnotify-boxes-configurations))
419
420 (prefix goimapnotify-))
421
422;; Serialize virtualhosts and components last.
423(define (serialize-goimapnotify-configuration config)
424 (define (boxes? field)
425 (eq? (configuration-field-name field) 'boxes))
426 (let ((rest (filter boxes? goimapnotify-configuration-fields)))
427 #~(string-append #$(serialize-configuration config rest)
428 #$(serialize-list-of-goimapnotify-boxes-configurations
429 'boxes
430 (goimapnotify-configuration-boxes config)))))
431
432(define (list-of-goimapnotify-configurations? lst)
433 (every goimapnotify-configuration? lst))
434
435(define (serialize-list-of-goimapnotify-configurations field-name value)
436 (let ((serializations (cons 'list
437 (map (cut serialize-configuration <>
438 goimapnotify-configuration-fields)
439 value))))
440 #~(begin
441 (use-modules (ice-9 format) (ice-9 string-fun))
442 (format #f "~a:
443~{ - ~a~%~}"
444 '#$field-name
445 (map (lambda (s)
446 (string-replace-substring s "\n" "\n "))
447 #$serializations)))))
448
449(define-configuration home-goimapnotify-configuration
450 (goimapnotify
451 (file-like goimapnotify)
452 "The @code{goimapnotify} package to use."
453 empty-serializer)
454 (configurations
455 (list-of-goimapnotify-configurations)
456 "List of @code{goimapnotify-configuration} records which contain
457information about all your accounts configurations."))
458
459(define (home-goimapnotify-shepherd-service config)
460 (let ((log-file #~(string-append %user-log-dir "/goimapnotify.log")))
461 (list
462 (shepherd-service
463 (provision '(goimapnotify))
464 (modules '((shepherd support))) ;for '%user-log-dir'
465 (documentation "Run a goimapnotify process")
466 (start #~(make-forkexec-constructor
467 (list
468 #$(file-append
469 (home-goimapnotify-configuration-goimapnotify config)
470 "/bin/goimapnotify")
471 "-conf" #$(mixed-text-file "goimapnotify.yaml"
472 (serialize-configuration config
473 home-goimapnotify-configuration-fields)))
474 #:log-file #$log-file))
475 (stop #~(make-kill-destructor))))))
476
477(define home-goimapnotify-service-type
478 (service-type
479 (name 'home-goimapnotify)
480 (extensions
481 (list (service-extension home-shepherd-service-type
482 home-goimapnotify-shepherd-service)))
483 (description "Configures the @code{goimapnotify} IMAP mailbox notifier.")))