Skip to content

Instantly share code, notes, and snippets.

@sorz
Created November 21, 2016 11:17
Show Gist options
  • Save sorz/abad87262f79bf9411d6f2da323d7c9b to your computer and use it in GitHub Desktop.
Save sorz/abad87262f79bf9411d6f2da323d7c9b to your computer and use it in GitHub Desktop.
Script to check postfix's mail queue and forward all deferred mails via IMAP.
#!/usr/bin/env python3
"""
Script to check postfix's mail queue and forward all deferred mails via IMAP.
Forwarded mails will be removed from queue.
Only handle mails in deferred queue and whose's (one of) recipients is EMAIL.
"""
from imaplib import IMAP4_SSL
from subprocess import check_output
import json
HOST = 'imap.gmail.com'
EMAIL = '[email protected]'
PASSWORD = 'your-password'
MAILBOX = 'INBOX'
POSTQUEUE = '/usr/bin/postqueue'
POSTCAT = '/usr/bin/postcat'
POSTSUPER = '/usr/bin/postsuper'
def connect_imap():
"""Login and return IMAPv4 object."""
imap = IMAP4_SSL(HOST)
imap.login(EMAIL, PASSWORD)
return imap
def append_mail(imap, mail):
"""Put mail into mailbox. Return True if success."""
result, _ = imap.append(MAILBOX, None, None, mail)
return result == 'OK'
def get_deferred_mail_ids():
"""Get all deferred mails in queue with specified recipient.
Return a list of queue IDs.
"""
ids = []
raw_output = check_output([POSTQUEUE, '-j'])
for raw_mail in raw_output.decode().split('\n'):
if not raw_mail:
continue
mail = json.loads(raw_mail)
if mail['queue_name'] != 'deferred':
continue
if EMAIL not in {r['address'] for r in mail['recipients']}:
continue
ids.append(mail['queue_id'])
return ids
def get_queued_mail(queue_id):
"""Return the specified mail."""
return check_output([POSTCAT, '-bhq', queue_id])
def delete_queued_mail(queue_id):
"""Delete mail from queue."""
return check_output([POSTSUPER, '-d', queue_id])
def main():
ids = get_deferred_mail_ids()
if not ids:
return
imap = connect_imap()
for queue_id in ids:
print('Forwarding %s...' % queue_id)
mail = get_queued_mail(queue_id)
if append_mail(imap, mail):
delete_queued_mail(queue_id)
imap.shutdown()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment