Skip to content
📥 IMAP based message broker client
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
.gitignore first commit Oct 27, 2016
LICENSE first commit Oct 27, 2016 Update README Nov 1, 2016
imapmq.go Add keep-alive to imap socket Nov 4, 2016
worker.go Don't call IMAP check when appending Nov 2, 2016

IMAPMQ is an IMAP based message broker client. It provides a simple interface for publishing, subscribing and dequeuing messages. It also supports concurrent access to the same message queue. Based on go-imap.

Go Report Card GoDoc

How it works

IMAPMQ treats IMAP mailboxes as queues. In order to add a message to a queue, IMAPMQ appends an email to the mailbox.


  • IMAPMQ can connect to any IMAPv4rev1 server with the CONDSTORE extension
  • Publish/Subscribe
  • Message Queue
  • Message format agnostic
  • No polling, the IMAP server notifies the client of new messages thanks to the IDLE command
  • Concurrency aware: multiple dequeuing instances can work on the same queue
  • Bring your own GUI: any IMAP client would do


$ go get

Example: A simple chat

The following example connects to an IMAP account, and creates a queue based on the INBOX mailbox. It spawns a goroutine that subscribes to the "chat" topic and listens to the returned channel. Anytime a user writes something and press enter, a new "chat" message is published to the queue.

You need to have an IMAP server to connect to. If you don't, you can create a gmail account. Make sure you enable IMAP (more info here) if you do.

package main

import (


func main() {
	// Create a new IMAPMQ client
	mq, err := imapmq.New(imapmq.Config{
		Login: "login",
		Passwd: "password",
		URL: "",
	if err != nil {
	defer mq.Close()

	// Create a queue based on INBOX
	q, err := mq.Queue("INBOX")
	if err != nil {

	go func() {
		// Subscribe to messages with the "chat" subject
		c := q.Sub("chat")
		for msg := range c { // msg is a mail.Message instance.
			log.Printf("%s", msg.Header.Get("Subject"))

	// We scan stdin for user input
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		// Publish a message with the "chat" subject in the INBOX queue
		q.Pub("chat", []byte(scanner.Text()))



MIT © Michael Sokol

You can’t perform that action at this time.