I have a file ~/foo/contacts.csv whose first two columns look like

Student ID,Student Name
[email protected],"Lennon, John"
[email protected],"McCartney, Paul"
[email protected],"Harrison, George"
[email protected],"Starr, Ringo"

In actuality, the file has dozens of lines and several other columns. This file is updated every day (people are added and others are deleted).

I'd like to be able to e-mail every person on this list using mu4e. Ideally this would be done so that each recipient cannot see the identities of the other receipts.

Does mu4e have the capability to read my csv file so I can easily email the entire list under the pseudoname My Class?

  • One option is to write a custom command which parses the csv file adds 'CC' entries for all the recipients, so that they do not see other recipients Commented Sep 7, 2015 at 8:03
  • Correction: I meant 'BCC' Commented Sep 7, 2015 at 8:31

2 Answers 2


There are multiple ways you can achieve this. Reading your question I see two main requirements

1) Parsing a csv file and getting the list of emails from it

2) Sending out emails to the list of emails retrieved without recipients seeing other recipients email address

For first requirement I would suggest you to use pcsv. Below is an example of of using the library

(require 'pcsv)

(defun my-get-emails-from-csv (file &optional file-has-header-p)
  (let* ((csv (pcsv-parse-file file))
         ;; If csv file has header strip the first element of the list
         (emails (if file-has-header-p (cdr csv) csv)))
    ;; Go through the csv entries and format them for mu4e
    (mapcar (lambda (email) (format "%s <%s>"
                                    ;; Remove any , in names
                                    (replace-regexp-in-string "," "" (cadr email))
                                    (car email)))

The above function will parse the given file and return a list of emails of the format user <email>.

Using this you can define an mail abbrev using define-mail-abbrev like so

(define-mail-abbrev "MyClass" (string-join (my-get-emails-from-csv "<path-to-csv>" t) ", "))

For the second requirement you will have to use the BCC header. Please also note that most (not all) email implementations hide the recipients so please research before using this.

In mu4e while composing a message you can do M-xmail-bccRET this will add a bcc header, you can type your alias MyClass and hit SPC and it will be expanded to the aliased entries. You might also want to add yourself to the To: field.

Since you have the basic building blocks, you can define custom commands that do what you want, one such example is below, it reads the path to a csv file (it assumes file is in the format specified in your question) from the user and inserts the emails from the file in the BCC field.

(defun my-mail-to-people-from-file (file)
  (interactive "fRead emails from file: ")
    ;; Read the emails from the CSV file and insert them
    (insert (string-join (my-get-emails-from-csv file t) ", "))))

In case string-join is not defined in your emacs use following to define it

(unless (fboundp 'string-join)
  (defun string-join (strings &optional separator)
    "Join all STRINGS using SEPARATOR."
    (mapconcat 'identity strings separator)))
  • This looks great! One problem--putting this in my .emacs returns "Warining (initialization): An error occurred while loading .emacs: Symbol's function definition is void: string-join Commented Sep 7, 2015 at 18:20
  • @BrianFitzpatrick It seems you are using an older version of emacs, string-join was added in emacs 24.4, I have updated the answer to handle this case Commented Sep 7, 2015 at 18:41
  • What a great answer! Thanks for looking at this! Commented Sep 7, 2015 at 21:06
  • @BrianFitzpatrick Your are welcome, glad I could help! Commented Sep 8, 2015 at 8:18
  • @Iqbai I thought I awarded you the bounty days ago, but I guess I was mistaken. Thanks again for helping me with this. Commented Sep 10, 2015 at 20:28

AFAIK there is no built-in feature in mu4e to achieve this. However, message-mode does support mail aliases.

The procedure (define-mail-abbrev NAME DEFINITION &optional FROM-MAILRC-FILE) could be used to define a name "My Class" that expands to the result of parsing the CSV file into a comma-separated list of strings. When composing a message, type "My Class" and run M-x expand-abbrev to expand the mail alias.

The part that takes some effort is to parse the CSV file. You also need to remember to do re-evaluate the procedure that creates the abbreviation from the result of parsing the CSV.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.