diff --git a/README.md b/README.md
index 83c23e2..46f5110 100644
--- a/README.md
+++ b/README.md
@@ -133,6 +133,11 @@ sudo service nginx restart
 sudo cp deployment/ticketfrei-web.service /etc/systemd/system/
 sudo systemctl daemon-reload
 sudo systemctl start ticketfrei-web.service
+
+# create and start the backend systemd service
+sudo cp deployment/ticketfrei-backend.service /etc/systemd/system
+sudo systemctl daemon-reload
+sudo systemctl start ticketfrei-backend.service
 ```
 
 ### Logs
diff --git a/active_bots/__init__.py b/active_bots/__init__.py
new file mode 100644
index 0000000..eedb95f
--- /dev/null
+++ b/active_bots/__init__.py
@@ -0,0 +1,15 @@
+__all__ = []
+
+import pkgutil
+import inspect
+
+for loader, name, is_pkg in pkgutil.walk_packages(__path__):
+    module = loader.find_module(name).load_module(name)
+
+    for name, value in inspect.getmembers(module):
+        if name.startswith('__'):
+            continue
+
+        globals()[name] = value
+        __all__.append(name)
+
diff --git a/active_bots/mailbot.py b/active_bots/mailbot.py
deleted file mode 100644
index 995b390..0000000
--- a/active_bots/mailbot.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env python3
-
-from config import config
-import logging
-import sendmail
-import ssl
-import datetime
-import email
-import imaplib
-import report
-from bot import Bot
-
-
-logger = logging.getLogger(__name__)
-
-
-class Mailbot(Bot):
-    """
-    Bot which sends Mails if mentioned via twitter/mastodon, and tells
-    other bots that it received mails.
-    """
-
-    def login(self, user):
-        # change to use mailbox of local system
-        mailinglist = user.get_mailinglist()
-        mailbox = imaplib.IMAP4_SSL(mailinglist)
-        context = ssl.create_default_context()
-        try:
-            mailbox.starttls(ssl_context=context)
-        except:
-            logger.error('StartTLS failed', exc_info=True)
-        try:
-            mailbox.login(config["mail"]["user"],
-                               config["mail"]["passphrase"])
-        except imaplib.IMAP4.error:
-            logger.error("Login to mail server failed", exc_info=True)
-            try:
-                mailer = sendmail.Mailer()
-                mailer.send('', config['web']['contact'],
-                            'Ticketfrei Crash Report',
-                            attachment=config['logging']['logpath'])
-            except:
-                logger.error('Mail sending failed', exc_info=True)
-
-    def crawl(self, user):
-        """
-        crawl for new mails.
-        :return: msgs: (list of report.Report objects)
-        """
-        mailbox = self.login(user)
-        try:
-            rv, data = mailbox.select("Inbox")
-        except imaplib.IMAP4.abort:
-            logger.error("Crawling Mail failed", exc_info=True)
-            rv = False
-        msgs = []
-        if rv == 'OK':
-            rv, data = mailbox.search(None, "ALL")
-            if rv != 'OK':
-                return msgs
-
-            for num in data[0].split():
-                rv, data = mailbox.fetch(num, '(RFC822)')
-                if rv != 'OK':
-                    logger.error("Couldn't fetch mail %s %s" % (rv, str(data)))
-                    return msgs
-                msg = email.message_from_bytes(data[0][1])
-
-                # check if email was sent by the bot itself. Different solution?
-                if not user.get_mailinglist() in msg['From']:
-                    # get a comparable date out of the email
-                    date_tuple = email.utils.parsedate_tz(msg['Date'])
-                    date_tuple = datetime.datetime.fromtimestamp(
-                            email.utils.mktime_tz(date_tuple)
-                        )
-                    date = int((date_tuple -
-                                datetime.datetime(1970, 1, 1)).total_seconds())
-                    if date > user.get_seen_mail():
-                        msgs.append(self.make_report(msg))
-        return msgs
-
-    def post(self, user, report):
-        """
-        sends reports by other sources to a mailing list.
-
-        :param report: (report.Report object)
-        """
-        mailinglist = self.login(user)
-        if report.source is not self:
-            mailer = sendmail.Mailer()
-            mailer.send(report.text, mailinglist,
-                        "Warnung: Kontrolleure gesehen")
-
-    def make_report(self, msg):
-        """
-        generates a report out of a mail
-
-        :param msg: email.parser.Message object
-        :return: post: report.Report object
-        """
-        # get a comparable date out of the email
-        date_tuple = email.utils.parsedate_tz(msg['Date'])
-        date_tuple = datetime.datetime.fromtimestamp(
-                email.utils.mktime_tz(date_tuple)
-            )
-        date = (date_tuple - datetime.datetime(1970, 1, 1)).total_seconds()
-
-        author = msg.get("From")  # get mail author from email header
-        # :todo take only the part before the @
-
-        text = msg.get_payload()
-        post = report.Report(author, "mail", text, None, date)
-        self.last_mail = date
-        return post
diff --git a/active_bots/mastodonbot.py b/active_bots/mastodonbot.py
index 07a2311..1007110 100755
--- a/active_bots/mastodonbot.py
+++ b/active_bots/mastodonbot.py
@@ -18,7 +18,11 @@ class MastodonBot(Bot):
         :return: list of statuses
         """
         mentions = []
-        m = Mastodon(*user.get_masto_credentials())
+        try:
+            m = Mastodon(*user.get_masto_credentials())
+        except TypeError:
+            #logger.error("No Mastodon Credentials in database.", exc_info=True)
+            return mentions
         try:
             notifications = m.notifications()
         except Exception:
diff --git a/active_bots/twitterbot.py b/active_bots/twitterbot.py
index fdf6045..696ed56 100755
--- a/active_bots/twitterbot.py
+++ b/active_bots/twitterbot.py
@@ -13,7 +13,7 @@ logger = logging.getLogger(__name__)
 
 class TwitterBot(Bot):
     def get_api(self, user):
-        keys = user.get_api_keys()
+        keys = user.get_twitter_credentials()
         auth = tweepy.OAuthHandler(consumer_key=keys[0],
                                    consumer_secret=keys[1])
         auth.set_access_token(keys[2],  # access_token_key
@@ -27,7 +27,11 @@ class TwitterBot(Bot):
         :return: reports: (list of report.Report objects)
         """
         reports = []
-        api = self.get_api(user)
+        try:
+            api = self.get_api(user)
+        except Exception:
+            #logger.error("Error Authenticating Twitter", exc_info=True)
+            return reports
         last_mention = user.get_seen_tweet()
         try:
             if last_mention == 0:
diff --git a/backend.py b/backend.py
index b66fcfa..77189f3 100755
--- a/backend.py
+++ b/backend.py
@@ -39,5 +39,5 @@ if __name__ == '__main__':
                             bot2.post(user, status)
             time.sleep(60)  # twitter rate limit >.<
     except Exception:
-        logger.error('Shutdown.', exc_info=True)
+        logger.error("Shutdown.", exc_info=True)
         shutdown()
diff --git a/bot.py b/bot.py
index b003ab8..c288140 100644
--- a/bot.py
+++ b/bot.py
@@ -1,7 +1,8 @@
 class Bot(object):
     # returns a list of Report objects
     def crawl(self, user):
-        pass
+        reports = []
+        return reports
 
     # post/boost Report object
     def post(self, user, report):
diff --git a/deployment/ticketfrei-backend.service b/deployment/ticketfrei-backend.service
index db95b88..87dce2e 100644
--- a/deployment/ticketfrei-backend.service
+++ b/deployment/ticketfrei-backend.service
@@ -9,7 +9,7 @@ ExecStart=/srv/ticketfrei/bin/python3 backend.py
 #RuntimeDirectory=uwsgi
 Restart=always
 KillSignal=SIGQUIT
-Type=notify
+Type=simple
 StandardError=syslog
 NotifyAccess=all
 
diff --git a/frontend.py b/frontend.py
index 969bea6..943a62a 100755
--- a/frontend.py
+++ b/frontend.py
@@ -87,6 +87,20 @@ def city_page(city):
     return dict(info='There is no Ticketfrei bot in your city yet. Create one yourself!')
 
 
+@get('/city/mail/<city>')
+@view('template/mail.tpl')
+def display_mail_page(city, user):
+    return user.state()
+
+
+@post('/city/mail/submit/<city>')
+def subscribe_mail(user, city):
+    email = request.forms['mailaddress']
+    # add confirmation mail workflow
+    user.add_subscriber(email)
+    redirect('/city/' + city)
+
+
 @get('/settings')
 @view('template/settings.tpl')
 def settings(user):
diff --git a/promotion/vag-zeitung.xcf b/promotion/vag-zeitung.xcf
index 3cad778..9a63e97 100644
Binary files a/promotion/vag-zeitung.xcf and b/promotion/vag-zeitung.xcf differ
diff --git a/promotion/vag-zeitung_p02.xcf b/promotion/vag-zeitung_p02.xcf
index a85c299..cf2ec66 100644
Binary files a/promotion/vag-zeitung_p02.xcf and b/promotion/vag-zeitung_p02.xcf differ
diff --git a/template/mail.tpl b/template/mail.tpl
new file mode 100644
index 0000000..2b16981
--- /dev/null
+++ b/template/mail.tpl
@@ -0,0 +1,15 @@
+% rebase('template/wrapper.tpl')
+
+<%
+import markdown as md
+
+html = md.markdown(markdown)
+%>
+
+<form action="/city/mail/submit/<% print(city) %>" method="post">
+    <input type="text" name="mailaddress" placeholder="E-Mail address" id="mailaddress">
+    <input name='confirm' value='Subscribe to E-Mail notifications' type='submit'/>
+</form>
+
+
+{{!html}}
diff --git a/user.py b/user.py
index 9823c78..ae4a82c 100644
--- a/user.py
+++ b/user.py
@@ -156,6 +156,9 @@ schlitz
                    (self.uid,))
         return db.cur.fetchone()[0]
 
+    def add_subscriber(self, email):
+        db.execute("INSERT INTO mailinglist(user_id, email, active VALUES(?, ?, ?);", (self.uid, email, 1))
+
     def set_badwords(self, words):
         db.execute("UPDATE badwords SET words = ? WHERE user_id = ?;",
                    (words, self.uid))
@@ -201,7 +204,7 @@ schlitz
         db.commit()
 
     def get_twitter_token(self):
-        db.execute("SELECT access_token, access_token_secret FROM twitter_accouts WHERE user_id = ?;",
+        db.execute("SELECT client_id, client_secret FROM twitter_accounts WHERE user_id = ?;",
                    (self.uid, ))
         return db.cur.fetchall()