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 mailserver meant for friends who value privacy and a hard to use interface....

python-mail A python mailserver meant for friends who value privacy and a hard to use interface.... Basic info This mailserver was just a random proje

Hashm 2 Jan 19, 2022
An offline Phishing Email Analyzer.

An offline Phishing Email Analyzer.

Kamran Saifullah (Frog Man) 11 Oct 19, 2022
Yahoo Mail Validator For Python

Validator Validator helps to know if the mail is valid or not Installation Install The libraries pip install requests bs4 colorama Usage Create a new

Mr Python 3 Mar 12, 2022
Disposable Temporary Email (Python Library)

Disposable Temporary Email (Python Library)

krypton 13 Nov 24, 2022
Send e-mails to teachers with specified school-website using Aula, anonymously

Information : This only works in Denmark! Send e-mails to teachers with specified school-website using Aula, anonymously. Find your school via the att

Binary.club 1 Jan 24, 2022
A news curator and newsletter subscription package for Django

django-newsfeed What is django-newsfeed? django-newsfeed is a news curator and newsletter subscription package for django. It can be used to create a

Maksudul Haque 179 Nov 14, 2022
Suplantar mails de empresas como google, facebook, github, etc...

Suplantar mails de empresas como google, facebook, github, etc...

piter 3 Feb 05, 2022
Collection of emails sent from the Hungarian gov and Viktor Orbán to the citizens of Hungary

Public list of Hungary and Viktor Orbán's emails since March 2021 Collection of emails sent from the Hungarian government and Viktor Orbán to the citi

Miguel Sozinho Ramalho 1 Mar 28, 2022
A light-weight, modular, message representation and mail delivery framework for Python.

Marrow Mailer A highly efficient and modular mail delivery framework for Python 2.6+ and 3.2+, formerly called TurboMail. © 2006-2019, Alice Bevan-McG

Marrow Open Source Collective 255 Dec 28, 2022
A simple email sender

Email-Sender Un semplice Email-Sender che utilizza il modulo smtplib con aggiunta di interfaccia grafica realizzata con il modulo tkinter Per il corre

Vincenzo Caliendo 0 Jan 14, 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
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
Automatically Send Custom Named Certificates via Mail

Welcome to Certificate Launchpad 🚀 Automatically Send Custom Named Certificates via Email Intro After any event, sending certificates to attendees or

Dc7 16 Oct 16, 2022
Tempmail API aswell as a SMTP server.

Tempmail API/Server Tempmail API aswell as a SMTP server. Website · Report Bug · Request Feature Setup Firstly create a mongodb account, and proceed t

femboy.party 16 Mar 09, 2022
SMTP In some vulnerable configurations, email servers can also be aggregated Use information that gives us information about the host or network Give

SMTP In some vulnerable configurations, email servers can also be aggregated Use information that gives us information about the host or network Give. The SMTP protocol supports some basic commands s

m3hr44n 1 Jan 16, 2022
Search email inbox with python and filter with search criteria via IMAP4 and fastapi or console

Search email inbox with python and filter with search criteria via IMAP4 and fastapi or console

Karma Computing 0 Sep 07, 2021
Djrill is an email backend and new message class for Django users that want to take advantage of the Mandrill transactional email service from MailChimp.

Djrill: Mandrill Transactional Email for Django Djrill integrates the Mandrill transactional email service into Django. PROJECT STATUS: INACTIVE As of

Brack3t 327 Oct 01, 2022
A small system for writing via email.

A small system for writing via email.

0 Nov 24, 2021
This python script will generate passwords for your emails, With certain lengths, And saves them into plain text files.

How to use. Change the Default length of genereated password in default.length.txt Type the email for your account. Type the website that the email an

2 Dec 26, 2021
You take an email and password from the combo list file and check it on mail.com

Brute-Force-mail tool information: Combo Type: email:pass Domains: All domains of the site Url: https://www.mail.com Api: ☑️ Proxy: No ☑️ The correct

6 Jun 05, 2022