Beispiel #1
0
def get_tasks(chat_id):
    email_address = dc.get_email_address(chat_id)
    service = ac.get_gmail_service(email_address)

    before = datetime.date.today().strftime("%Y/%m/%d").replace("/0", "/")
    after = (datetime.date.today() +
             relativedelta(days=-3)).strftime("%y/%m/%d").replace("/0", "/")
    query = "from:(service@{}) subject:python after:{} before:{}".format(
        SERVICE_NAME, after, before)

    response = service.users().messages().list(userId="me", q=query).execute()
    messages = []

    if 'messages' in response:
        messages.extend(response['messages'])

    while 'nextPageToken' in response:
        page_token = response['nextPageToken']
        response = service.users().messages().list(
            userId="me", q=query, pageToken=page_token).execute()
        messages.extend(response['messages'])
    mime_msgs = []
    for m in messages:
        mime_msgs.append(get_mime_msg(service, m["id"]))

    log_line("GF tasks were received!")
    return mime_msgs
Beispiel #2
0
def encrypt(data):
    log_line("Creds try encript!")
    cipher = AES.new(DB_KEY, AES.MODE_EAX)
    nonce = cipher.nonce
    cipher_text, tag = cipher.encrypt_and_digest(data)

    log_line("Creds encrypt_and_digest!")
    return cipher_text, tag, nonce
Beispiel #3
0
def change_latest_history_id(email_address, new_historyId):
    try:
        exec_data_manipulation_query(
            "UPDATE email_historyIds SET last_historyId = {} WHERE email = \'{}\'"
            .format(new_historyId, email_address))
    except psycopg2.IntegrityError:
        log_line("Update was failed!")
        raise NotFoundException(email_address, "email", "email_historyIds")
Beispiel #4
0
 def set_webhook(self):
     if not bool(self.bot.get_webhook_info().url):
         try:
             self.bot.setWebhook("https://{}.herokuapp.com/{}".format(NAME, TOKEN))
             log_line("Webhook was set")
         except telegram.error.RetryAfter:
             log_line("telegram.error.RetryAfter WAS ENCOUNTERED :(")
             sleep(2)
             self.set_webhook()
Beispiel #5
0
def receive_email_notification():
    response = request.get_json(force=True)
    encrypted_message_data = response["message"]["data"]
    message_data = json.loads(base64.b64decode(encrypted_message_data))
    try:
        process_email_notification(message_data)
    except dc.NotFoundException:
        log_line("FAILED TO RECEIVE NOTIFICATION!")
        return "Unauthorized", 401
    return "OK", 200
Beispiel #6
0
def decrypt(cipher_text, tag, nonce):
    cipher = AES.new(DB_KEY, AES.MODE_EAX, nonce=nonce)
    plaintext = cipher.decrypt(cipher_text)
    try:
        cipher.verify(tag)
        log_line("Decryption went fine!")
        return plaintext
    except ValueError:
        log_line("Decryption went wrong!")
        raise CipherException
Beispiel #7
0
def create_tables():
    try:
        exec_data_manipulation_query(
            "CREATE TABLE email_credentials (email text, cipher_text bytea, tag bytea, nonce bytea, PRIMARY KEY (email))"
        )
        # raise NotImplementedError
        # exec_data_manipulation_query("alter table email_historyIds add primary key ( email )")
        # exec_data_manipulation_query("alter table email_chats add primary key ( email )")
    except psycopg2.ProgrammingError:
        log_line("email_historyIds already exists!")
Beispiel #8
0
def repr_mime_msg(msg):
    mail_emoji = "\U00002709"
    body = ""
    for part in msg.walk():
        if part.get_content_type() == "text/plain":
            body += part.get_payload(decode=True).decode("UTF-8")
    representation = ("From : {}{}\nSubject : {}\n{}\n"
                      .format(mail_emoji, msg["From"], msg["Subject"], body))
    # log_line(representation)
    log_line("Message representation was received!")
    return representation
Beispiel #9
0
 def send_mime_msg(self, chat_id, mime_msg):
     text_msg = repr_mime_msg(mime_msg)
     if len(text_msg) > 4096:
         text_msg = "TEXT IS TOO LONG\n\n" + text_msg
         log_line("Mime message was TOO LONG!")
         while len(text_msg) > 0:
             self.bot.sendMessage(chat_id=chat_id, text=text_msg[:4000],
                                  disable_web_page_preview=True, parse_mode=telegram.ParseMode.MARKDOWN)
             text_msg = text_msg[4000:]
     self.bot.sendMessage(chat_id=chat_id, text=text_msg,
                          disable_web_page_preview=True, parse_mode=telegram.ParseMode.MARKDOWN)
     log_line("Mime message was sent!")
Beispiel #10
0
 def get_body(html=True):
     body = ""
     content_type = "text/html" if html else "text/plain"
     for part in mime_msg.walk():
         if "multipart" not in part.get_content_type(
         ) and part.get_content_type() == content_type:
             body += "{}\n".format(
                 part.get_payload(decode=True).decode("UTF-8"))
     if html:
         log_line("BODY : " + body)
         body = html2text.html2text(body)
         log_line("PARSED BODY : " + body)
     return body
def start_watch(email_address):
    service = get_gmail_service(email_address)

    topic_path = "projects/{}/topics/{}".format(GCP_PROJECT_NAME, GCP_TOPIC_NAME)
    gmail_request = {"labelIds": ["UNREAD"],
                     "labelFilterAction": "include",
                     "topicName": topic_path}

    service.users().stop(userId="me").execute()

    watch_res = service.users().watch(userId="me", body=gmail_request).execute()
    log_line("Result of watch : " + str(watch_res))

    return watch_res
Beispiel #12
0
def process_email_notification(message_data):
    email_address = message_data["emailAddress"]
    start_history_id = dc.get_latest_historyId(email_address)
    chat_id = dc.get_chat_id(email_address)

    bot.send_message(chat_id=chat_id,
                     text="You have received this historyId : " + str(message_data["historyId"]))
    # bot.send_message(chat_id=chat_id,
    #                 text="You have received these changes : " + str(changes)[:4000])

    messages = gc.get_new_messages(email_address, start_history_id)

    for mime_msg in messages:
        bot.send_mime_msg(chat_id=chat_id,
                          mime_msg=mime_msg)

    log_line("Email notification was processed!")
Beispiel #13
0
def store_credentials(email_address, credentials):
    log_line("Creds try store!")
    cipher_text, tag, nonce = encrypt(credentials)
    cipher_text, tag, nonce = [
        psycopg2.Binary(data) for data in (cipher_text, tag, nonce)
    ]
    log_line("Creds encrypted!")
    try:
        exec_data_manipulation_query(
            "INSERT INTO email_credentials (email, cipher_text, tag, nonce) VALUES (\'{}\', {}, {}, {})"
            .format(email_address, cipher_text, tag, nonce))
        log_line("User " + email_address +
                 " was successfully added to email_credentials table!")
    except psycopg2.IntegrityError:
        log_line("email_credentials already contains " + email_address +
                 " key!")
    except Exception as e:
        log_line(str(e) + " key!")
def exchange_code(authorization_code):
    """Exchange an authorization code for OAuth 2.0 credentials.

    Args:
      authorization_code: Authorization code to exchange for OAuth 2.0
                          credentials.
    Returns:
      oauth2client.client.OAuth2Credentials instance.
    Raises:
      CodeExchangeException: an error occurred.
    """
    flow = OAuth2WebServerFlow(client_id=CLIENT_ID,
                               client_secret=CLIENT_SECRET,
                               scope=SCOPES)
    flow.redirect_uri = REDIRECT_URI
    try:
        credentials = flow.step2_exchange(authorization_code)
        return credentials
    except FlowExchangeError as err:
        log_line('An error occurred: ' + str(err))
        raise CodeExchangeException(None)
def get_user_info(credentials):
    """Send a request to the UserInfo API to retrieve the user's information.

    Args:
      credentials: oauth2client.client.OAuth2Credentials instance to authorize the
                   request.
    Returns:
      User information as a dict.
    """
    user_info_service = build(
        serviceName='oauth2', version='v2',
        http=credentials.authorize(Http()))
    user_info = None
    try:
        user_info = user_info_service.userinfo().get().execute()
    except HttpError as e:
        log_line('An error occurred: ' + str(e))
    if user_info and user_info.get('email'):
        return user_info
    else:
        raise NoUserInfoException()
Beispiel #16
0
def save_user(email_address, chat_id, base_history_id):
    try:
        exec_data_manipulation_query(
            "INSERT INTO email_chats (email, chat) VALUES (\'{}\', {})".format(
                email_address, chat_id))
        log_line("User " + email_address +
                 " was successfully added to email_chats table!")
    except psycopg2.IntegrityError:
        log_line("email_chats already contains " + email_address + " key!")
    try:
        exec_data_manipulation_query(
            "INSERT INTO email_historyIds (email, base_historyId, last_historyId) VALUES (\'{}\', {}, {})"
            .format(email_address, base_history_id, base_history_id))
        log_line("User " + email_address +
                 " was successfully added to email_historyIds table!")
    except psycopg2.IntegrityError:
        log_line("email_historyIds already contains " + email_address +
                 " key!")
Beispiel #17
0
def start(bot, update, args):
    log_line("Started!")
    if args:
        code = ac.get_code(args[0])
        if not code:
            update.effective_message.reply_text("What does " + ''.join(args) + " mean? Try again please!")
            log_line("Start parameters were wrong!")
            return
        log_line("Bot has received the key!")
        update.effective_message.reply_text("Hello there, Telegram user!")
        ac.authorize_user(code, update.effective_chat.id)
    else:
        # store = oauth_file.Storage(str(update.effective_user.id) + "_token.json")
        authorize_url = ac.get_authorization_url()
        update.effective_message.reply_text(authorize_url)
def store_credentials(email_address, credentials):
    """Store OAuth 2.0 credentials in the application's database.

    This function stores the provided OAuth 2.0 credentials using the user ID as
    key.

    Args:
      email_address: User's email address.
      credentials: OAuth 2.0 credentials to store.
    Raises:
    """
    json_creds = credentials.to_json().encode()
    log_line("# 1" + str(type(json_creds)))
    log_line("# 2" + str(json_creds))
    dc.store_credentials(email_address, json_creds)
    log_line("Creds stored!")
def get_credentials(authorization_code):
    """Retrieve credentials using the provided authorization code.

    This function exchanges the authorization code for an access token and queries
    the UserInfo API to retrieve the user's e-mail address.
    If a refresh token has been retrieved along with an access token, it is stored
    in the application database using the user's e-mail address as key.
    If no refresh token has been retrieved, the function checks in the application
    database for one and returns it if found or raises a NoRefreshTokenException
    with the authorization URL to redirect the user to.

    Args:
      authorization_code: Authorization code to use to retrieve an access token.
    Returns:
      oauth2client.client.OAuth2Credentials instance containing an access and
      refresh token.
    Raises:
      CodeExchangeError: Could not exchange the authorization code.
      NoRefreshTokenException: No refresh token could be retrieved from the
                               available sources.
    """
    try:
        credentials = exchange_code(authorization_code)
        email_address = get_user_info(credentials).get('email')
        log_line("Refresh token:" + str(credentials.refresh_token))
        if credentials.refresh_token is not None:
            store_credentials(email_address, credentials)
            return credentials
        else:
            credentials = get_stored_credentials(email_address)
            if credentials and credentials.refresh_token is not None:
                return credentials
    except CodeExchangeException as err:
        log_line('An error occurred during code exchange.\n')
        # Drive apps should try to retrieve the user and credentials for the current session.
        # If none is available, redirect the user to the authorization URL.
        err.authorization_url = get_authorization_url()
        raise err
    except NoUserInfoException:
        log_line('No user info could be retrieved.\n')
        # No refresh token has been retrieved.
        authorization_url = get_authorization_url()
        raise NoRefreshTokenException(authorization_url)
Beispiel #20
0
def get_database_connection():
    try:
        return psycopg2.connect(DATABASE_URL, sslmode='require')
    except:
        log_line("Unable to connect to database!")
Beispiel #21
0
def echo(bot, update):
    update.effective_message.reply_text(update.effective_message.text)
    log_line("Answered!")
Beispiel #22
0
def get_new_messages(email_address, start_history_id):
    gmail_service = ac.get_gmail_service(email_address)
    changes = get_changes(email_address, gmail_service, start_history_id)
    messages = get_msgs_from_changes(changes, gmail_service)
    log_line("New messages were received")
    return messages
Beispiel #23
0
def help_(bot, update):
    chat_id = update.effective_chat.id
    ac.renew_watch(chat_id)
    log_line("Watch was revoked!")
Beispiel #24
0
def error(bot, update, error_):
    log_line("Update {} caused error {}".format(str(update), str(error_)))
Beispiel #25
0
def webhook():
    msg = request.get_json(force=True)
    bot.process_msg(msg)
    log_line("Message was processed")
    return "Hello there!"
Beispiel #26
0
 def __init__(self, value, column, table):
     msg = "{} was not found in {} column of {} table!\n".format(
         value, column, table)
     super().__init__(msg)
     log_line(msg)