Convert emails without attachments to pdf and send as email

Overview

Email to PDF to email

This script will check an imap folder for unread emails. Any unread email that does not have an attachment will be converted to a pdf and then emailed to the address you specify. The script is run at a configurable interval.

This was built to integrate with paperless-ng which works with pdf attachements. However, I get many documents that are html only, so I wanted them converted to pdf for storage in paperless-ng.

Usage

The following parameters are used:

  • IMAP_URL
  • IMAP_USERNAME
  • IMAP_PASSWORD
  • IMAP_FOLDER Which folder to watch for unread emails
  • SMTP_URL
  • MAIL_SENDER: Address the mail with pdf should be sent from
  • MAIL_DESTINATION: Where to send the resulting pdf
  • INTER_RUN_INTERVAL: Time in seconds that the system should wait between running the script

Docker-Compose

1. Use prebuilt image

This image is stored in the github registry, so you can use it without downloading this code repository. The image address is ghcr.io/rob-luke/emails-html-to-pdf/image:latest. So to use it in a docker-compose it would be something like...

version: "3.8"

services:

  email2pdf:
    image: ghcr.io/rob-luke/emails-html-to-pdf/image:latest
    container_name: email2pdf
    environment:
      - IMAP_URL=imap.provider.com
      - [email protected]
      - IMAP_PASSWORD=randompassword
      - IMAP_FOLDER=Paperless
      - SMTP_URL=smtp.provider.com
      - [email protected]
      - [email protected]
      - INTER_RUN_INTERVAL=600

2. Build image yourself

Open the docker-compose file and enter your details in the environment. This will run the script every minute.

docker-compose up -d

Python

Or if you prefer you can run the script manually by running these commands.

poetry install
poetry run src/main.py
Comments
  • Non-standard characters break file naming

    Non-standard characters break file naming

    I setup a forward to move my html only emails to an email address that this script processes. The colon in the subject line (Fwd:) breaks the file naming because files cannot contain non-standard characters, the file is saved simply as "Fwd".

    opened by bjnoel 5
  • Moved from Windows/WSL/Ubuntu to RPi 4b Ubuntu 64 and container fails on startup

    Moved from Windows/WSL/Ubuntu to RPi 4b Ubuntu 64 and container fails on startup

    It's not producing much error details only: email2pdf | standard_init_linux.go:228: exec user process caused: exec format error

    My compose section:

      email2pdf:
        image: ghcr.io/rob-luke/emails-html-to-pdf:latest
        container_name: email2pdf
        environment:
          - IMAP_URL=xxxx
          - IMAP_USERNAME=xxxx
          - IMAP_PASSWORD=xxxx
          - IMAP_FOLDER=paperless
          - SMTP_URL=xxxx
          - MAIL_SENDER=xxxx
          - MAIL_DESTINATION=xxxx
          - INTER_RUN_INTERVAL=300
          - PRINT_FAILED_MSG='false'
    
    opened by smseidl 4
  • Fix issue 11

    Fix issue 11

    This PR fixes #11

    This PR introduces 2 new Environment Variables:

    HOSTS

    This var is a semicolon separated list of hosts that should be added to /etc/hosts to prevent dns lookup failures. e.x.: HOSTS=127.0.0.1 tracking.paypal.com;127.0.0.1 my.custom.host.tld

    WKHTMLTOPDF_OPTIONS

    This var is a python dict (json) representation of wkhtmltopdf_options that can be passed to the used pdfkit library.

    e.x.: WKHTMLTOPDF_OPTIONS='{"load-media-error-handling":"ignore"}'

    More options for wkhtmltopdf can be found here. More about the usage of those options with pdfkit can be found here

    Examples

    I had the problem that the tracking pixel of PayPal caused a HostNotFoundError. This was because the container was not able to resolve the tracking.paypal.com domain.

    With this PR, I would add following to the docker-compose.yml:

    
    ...
        environment:
            ...
            HOSTS=127.0.0.1 tracking.paypal.com
            WKHTMLTOPDF_OPTIONS={"load-media-error-handling":"ignore"}
    
    opened by mirisbowring 4
  • Error while loading/opening URL

    Error while loading/opening URL

    I tried to send a Paypal receipt email to Paperless via the Email to PDF and got the below error. I don't understand why it's trying to load this page instead of the actual email... thoughts?

    email2pdf    |
    email2pdf    | No attachments in: You have authorized a payment to XXXXXXXX Inc.
    email2pdf    |
    email2pdf    | PDF: You-have-authorized-a-payment-to-XXXXXXXX_.pdf
    email2pdf    |
    email2pdf    | PDF: You-have-authorized-a-payment-to-XXXXXXXX_.pdf
    email2pdf    | Traceback (most recent call last):
    email2pdf    |   File "/app/main.py", line 98, in <module>
    email2pdf    |     process_mail(imap_url=server_imap,
    email2pdf    |   File "/app/main.py", line 72, in process_mail
    email2pdf    |     pdfkit.from_string(html, filename)
    email2pdf    |   File "/usr/local/lib/python3.9/site-packages/pdfkit/api.py", line 72, in from_string
    email2pdf    |     return r.to_pdf(output_path)
    email2pdf    |   File "/usr/local/lib/python3.9/site-packages/pdfkit/pdfkit.py", line 156, in to_pdf
    email2pdf    |     raise IOError('wkhtmltopdf reported an error:\n' + stderr)
    email2pdf    | OSError: wkhtmltopdf reported an error:
    email2pdf    | QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
    email2pdf    | Loading page (1/2)
    Error: Failed to load https://t.paypal.com/ts?xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, with network status code 1 and http status code 0 - Connection refused
    Printing pages (2/2)                                                        ] 25%
    Done                                                                        ]
    email2pdf    | Exit with code 1 due to network error: ConnectionRefusedError
    email2pdf    |
    
    opened by smseidl 4
  • Improved support for search criteria

    Improved support for search criteria

    • Adds an option to specify a custom search criteria
    • Fixes mail being processed multiple times if flag is not "SEEN"
      • Search was always looking for "unseen" mail. If the mail flag was not set to seen, the mail would remain unread and be processed next run. A suitable filter should now be determined, or an error raised if the user must specify one.
    • Remove "DRAFT" flag option
      • Causes strange behaviour where inbound mail can be converted to an outbound draft. This can then be accidentally discarded deleting the original message or converting it back can result in the metadata of the email being lost.
    • Add "UNFLAGGED" mail flag option
      • Removes the "FLAGGED" option from the message once processed
    opened by deosrc 3
  • Possible to add the email header to the PDF?

    Possible to add the email header to the PDF?

    This looks perfect in combination with paperless, thanks for spending your time creating this!

    Sometimes, I do not only get HTML emails but simply text emails where I would need the actual headers (from, date, subject, etc.) - is it possible to include these in the generated PDF?WKHTMLTOPDF options appear to control the PDF's layout, not the content.

    opened by Cantello 2
  • Added seperate SMTP login username and password

    Added seperate SMTP login username and password

    I added smtp_username and smtp_password options in case your outgoing email goes through an smtp server with different login credentials than your imap server.

    opened by chirmstream 2
  • Implement Delete option for Mails

    Implement Delete option for Mails

    It would be cool to have an option to delete the mails instead of marking them as read. Mails I want to consume will be moved into a "Processing" folder where this container picks them up. Afterwards, they are sent to the paperless instance and can therefore be deleted to keep the mail inbox empty.

    opened by mirisbowring 2
  • Use Docker and Github Tags for releases

    Use Docker and Github Tags for releases

    Hi,

    since this project got some good improvements over the last days, the image should be shipped with a versioning system. Since only the latest Tag is currently used, clients will not pull a later image because the tag name did not change.

    My Recommendation:

    • create a Github Release (Tag) for every new Feature / Group of Features
    • Modify the Buildprocess to get triggered by the "onTag" action of GitHub and use the tagname as Docker tag
    • Build the latest tag with the current master (independently of current releases) branch.
    opened by mirisbowring 2
  • Use Alpine baseimage

    Use Alpine baseimage

    Currently, the derived base image (python 3.9) is based on a default debian install and therefore is about 1,5GB tall. We should create an image based on alpine-linux to reduce image size.

    I will create an PR tomorrow probably.

    opened by mirisbowring 2
  • Option to activte or deactivate SSL/TLS and define the port via environment variables on docker

    Option to activte or deactivate SSL/TLS and define the port via environment variables on docker

    Hey there, thanks for your effort! Is it possible to setup the docker-compose.yml variables to define if SSL/TLS os in or off and another option to define the port that should be used?

    opened by gsusxx 2
  • !!!!  UNHANDLED EXCEPTION.  !!!!  :  wkhtmltopdf reported and error:   Protocol ‘about’ is unknown

    !!!! UNHANDLED EXCEPTION. !!!! : wkhtmltopdf reported and error: Protocol ‘about’ is unknown

    Hi

    Just started to use your docker instance and it seemed to be going great, but then suddenly the container stopped, looking in the logs I saw the following error a few times..

    44D9C31D-EC04-4BE4-A29E-8A7E8EDA3505

    opened by nodecentral 0
  • Supported email providers ?

    Supported email providers ?

    Hi

    I’m looking to use something just like this, however it seems the likes of gmail and outlook (hotmail, live) etc. are now no longer supporting basic authentication (username,password) is that your understanding too ? If so what providers can be used with your set up ?

    Many thanks

    opened by nodecentral 0
  • Login Fails

    Login Fails

    My account has 2FA enabled on it, and I don't have the option to disable 2FA. I'm assuming that is why I'm getting this error, but I don't even get a prompt on my Microsoft Authenticator app to approve the login attempt, so it doesn't seem to be getting that far.

    600
    Skipping virtualenv creation, as specified in config file.
    Running emails-html-to-pdf
    Starting mail processing run
        raise self.error(dat[-1])
    imaplib.IMAP4.error: b'LOGIN failed.'
    Traceback (most recent call last):
      File "/app/main.py", line 257, in <module>
        process_mail(
      File "/app/main.py", line 102, in process_mail
        with MailBox(imap_url).login(imap_username, imap_password, imap_folder) as mailbox:
      File "/usr/local/lib/python3.9/site-packages/imap_tools/mailbox.py", line 44, in login
        login_result = self.box.login(username, password)
      File "/usr/local/lib/python3.9/imaplib.py", line 612, in login
        raise self.error(dat[-1])
    imaplib.IMAP4.error: b'LOGIN failed.'
    
    opened by cjfagerstrom 0
  • Add Header information to PDF

    Add Header information to PDF

    This is a pull request to add the feature requested here: #27

    The following ENV variables have been added:

    EMAIL_HEADER EMAIL_HEADER_EXT

    These are both False by default.

    By turning on the Header, you will now have some basic information added to the PDF such as the subject, date/time, sender and recipient. Example:

    image

    Right now it displays:

    • Subject
    • Date
    • From
    • Reply-to
    • To

    Additional fields such as CC / BCC should probably be added.

    By turning on the Header (extended) it will display the full headers as received. However, it currently does not display them very cleanly. Maybe it would be worthwhile to look into how to make them display better. It could be as simple as adding a <pre> tag.

    Tested and works.

    opened by ajquick 1
  • Handling Inline Image?

    Handling Inline Image?

    I thought I had a failing installation because my first test email was not being converted.

    The email had an inline image that was attached to the email. I guess I didn't know that in some cases (Gmail in this instance) an HTML image in the body of the email is also attached to the email itself.

    Could there be a way to handle attached images in this manner? Perhaps it allows attachments, but only if the attachment is also used in the body of the message? That way it skips legitimately attached files but does act when the attachment is part of the email body?

    My Paperless-ng(x) filters out all non-PDF attachments already, so it wouldn't import the email with the inline images anyways.

    opened by ajquick 0
Releases(v0.2.0)
Owner
Robert Luke
Neuroscientist in the Department of Linguistics at Macquarie University
Robert Luke
A python script that helps you understand why your E-Mail ended up in Spam

decode-spam-headers.py Whether you are trying to understand why a specific e-mail ended up in SPAM/Junk for your daily Administrative duties or for yo

Mariusz Banach 316 Jan 05, 2023
Using this repository you can send mails to multiple recipients.Was created in support of Ukraine, to turn society`s attention to war.

mails-in-support-of-UA Using this repository you can send mails to multiple recipients.Was created in support of Ukraine, to turn society`s attention

Oleksii Budzinskiy 2 Mar 04, 2022
Simple Email Sender using Python 3.

Email Sender 使用 Python 3 实现的简单邮件发送工具。 Version: 0.1.2 (Beta) 主要功能 使用 SMTP 协议发送邮件 支持 SSL/TLS 、 STARTTLS 加密(为保证安全,强制加密发送) 支持邮件模板与邮件生成 支持向多人群发邮件 日志记录 脚本执行

SUMSC 1 Feb 13, 2022
Python email address and Mime parsing library

Flanker - email address and MIME parsing for Python Flanker is an open source parsing library written in Python by the Mailgun Team. Flanker currently

Mailgun Team 1.6k Dec 29, 2022
A functional demo of the O365 Module to send an email on an authenticated, tokenized account.

O365_email A functional demo of the O365 Module to send an email on an authenticated, tokenized account. Prep Create an app in Azure Developer's porta

2 Oct 14, 2022
Envia-emails - A Python Program that creates emails

Envia-emails Os emails é algo muito importante e usado. Pensando nisso, eu criei

José Rodolfo 2 Mar 05, 2022
Email-osint - Email OSINT tool written in python3

Email-osint - Email OSINT tool written in python3

Surtains 7 Nov 28, 2022
Mailer is python3 script use for sending spear-phishing to target email...It was created by Spider Anongreyhat

Mailer Mailer is a python3 script. It's used for sending spear-phishing to target email...It was created by Spider Anongreyhat Screenshots Installatio

Spider Anongreyhat 31 Dec 05, 2022
automatic mails sender with attachments

أزعجني لين تدربني Automatic mails sender with attachments. Note: You need to have gmail account & and you need to turn on "Less secure app access" set

6 Dec 30, 2022
faceFarm is an active yahoo email detection script that functions to take over the facebook account using email.

faceFarm – The simple Email Detector. Email Valid Detector for Facebook (Yahoo) faceFarm is an active yahoo email detection script that functions to t

Fadjrir Herlambang 2 Jan 18, 2022
Command line interface for sending email using SMTP (ships with Gmail configuration).

mailsend Description Lightweight command line interface for sending email using SMTP. Default configuration is set for Gmail (smtp.gmail.com at port 5

Keith Mathe 1 Mar 22, 2022
Secret Service Email Encryption/Steganography

SecretService Decoy Encrypted Emailer

Unit 221B 6 Aug 05, 2022
Simple, powerfull and nonobstructive django email middleware.

djmail djmail is a BSD Licensed, simple and nonobstructive django email middleware. Why use djmail? Because it: Sends emails asynchronously without ad

David Barragán Merino 77 Aug 30, 2021
Django module to easily send templated emails using django templates, or using a transactional mail provider (mailchimp, silverpop, etc.)

Django-Templated-Email Info: A Django oriented templated email sending class Author: Bradley Whittington (http://github.com/bradwhittington, http://tw

Vinta Software 659 Dec 27, 2022
This Python program generates a random email address and password from a 2 big lists and checks the generated email.

This Python program generates a random email address and password from a 2 big lists and checks the generated email.

Killin 13 Dec 04, 2022
ghotok mail - lets you find available contact email addresses from target website

ghotok-mail ghotok mail - lets you find available contact email addresses from target website git clone https://github.com/josifkhan/ghotok-mail cd gh

Md Josif Khan 3 Mar 14, 2022
SMTP checker to check Mail Access via SMTP

SMTP checker to check Mail Access via SMTP with easy usage ! Medusa has been written and tested with Python 3.8. It should run on any OS as long as Python and all dependencies are installed.

h3x0 23 Dec 05, 2022
Esio_dev 3 Oct 15, 2021
Send email in Python conveniently for gmail using yagmail

yagmail -- Yet Another GMAIL/SMTP client For the asynchronous asyncio version, look here: https://github.com/kootenpv/aioyagmail The goal here is to m

Pascal van Kooten 2.4k Dec 31, 2022
An email sending system with random confirmation code.

email_sending An email sending system with random confirmation code. Description Confirmation emails are sent based on the list of email addresses. Ea

Larissa Queiroz 2 Mar 22, 2022