Exemplo n.º 1
0
def index():
    # If we have an access_token, we may interact with the Nylas Server
    if 'access_token' in session:
        client = APIClient(APP_ID, APP_SECRET, session['access_token'])
        message = None
        while not message:
            try:
                # Get the latest message from namespace zero.
                message = client.messages.first()
                if not message:  # A new account takes a little time to sync
                    print "No messages yet. Checking again in 2 seconds."
                    time.sleep(2)
            except Exception as e:
                print(e.message)
                return Response("<html>An error occurred.</html>")
        # Format the output
        text = "<html><h1>Here's a message from your inbox:</h1><b>From:</b> "
        for sender in message["from"]:
            text += "{} &lt;{}&gt;".format(sender['name'], sender['email'])
        text += "<br /><b>Subject:</b> " + message.subject
        text += "<br /><b>Body:</b> " + message.body
        text += "</html>"

        # Return result to the client
        return Response(text)
    else:
        # We don't have an access token, so we're going to use OAuth to
        # authenticate the user

        # Ask flask to generate the url corresponding to the login_callback
        # route. This is similar to using reverse() in django.
        redirect_uri = url_for('.login_callback', _external=True)

        client = APIClient(APP_ID, APP_SECRET)
        return redirect(client.authentication_url(redirect_uri))
Exemplo n.º 2
0
def login_callback():
    if 'error' in request.args:
        return "Login error: {0}".format(request.args['error'])

    client = APIClient(APP_ID, APP_SECRET)
    code = request.args.get('code')
    session['access_token'] = client.token_for_code(code)
    return index()
Exemplo n.º 3
0
def login():
    if request.endpoint != 'login_callback':
        if 'access_token' not in session:
            redirect_uri = url_for('.login_callback', _external=True)
            client = APIClient(APP_ID, APP_SECRET)
            return redirect(client.authentication_url(redirect_uri))
        else:
            create_todo_tag()
Exemplo n.º 4
0
def login_callback():
    if 'error' in request.args:
        return "Login error: {0}".format(request.args['error'])

    # Exchange the authorization code for an access token
    client = APIClient(APP_ID, APP_SECRET)
    code = request.args.get('code')
    session['access_token'] = client.token_for_code(code)
    return redirect(url_for('threads_contacts', offset=0))
Exemplo n.º 5
0
def login_callback():
    if 'error' in request.args:
        return "Login error: {0}".format(request.args['error'])

    # Exchange the authorization code for an access token
    client = APIClient(APP_ID, APP_SECRET)
    code = request.args.get('code')
    token = client.token_for_code(code)
    return token
Exemplo n.º 6
0
def login_callback():
    if 'error' in request.args:
        return "Login error: {0}".format(request.args['error'])

    # Exchange the authorization code for an access token
    client = APIClient(APP_ID, APP_SECRET)
    code = request.args.get('code')
    session['access_token'] = client.token_for_code(code)
    return index()
Exemplo n.º 7
0
def index(pagenr):
    session['contact_mails'] = []
    session['contact_addresses'] = []
    offset = pagenr
    # If we have an access_token, we may interact with the Nylas Server
    if 'access_token' in session:
        client = APIClient(APP_ID, APP_SECRET, session['access_token'])
        message = None
        while len(session['contact_addresses']) + 1 < pagenr * 10:
            try:
                # Get the latest message from namespace zero.
                messages = client.messages.where(**{'in': 'all', 'limit': 20, 'offset':offset})
                for message in messages:
                    #print message['from'][0]['email']
                    if message['from'][0]['email'] not in session['contact_addresses']:
                        contact_mail = {
                        'id': len(session['contact_addresses']),
                        'date': message['date'],
                        'name': message['from'][0]['name'],
                        'email': message['from'][0]['email'],
                        'snippet': message['snippet'],
                        'unread': message['unread']
                        }
                        session['contact_mails'].append(contact_mail)
                        session['contact_addresses'].append(message['from'][0]['email'])
                #if messages.sender[0]['email'] not in session['emails']:
                if not messages:  # A new account takes a little time to sync
                    print "No messages yet. Checking again in 2 seconds."
                    time.sleep(2)
            except Exception as e:
                print(e.message)
                return Response("<html>An error occurred.</html>")
            offset += 1
        if pagenr - 1 == 0:
            start = 0
            end = 10
        else:
            start = (pagenr - 1) * 10
            end = pagenr * 10


        response = {'contacts': session['contact_mails'][start:end]}
        js = json.dumps(response)
        resp = Response(js, status=200, mimetype='application/json')
        return resp

    else:
        # We don't have an access token, so we're going to use OAuth to
        # authenticate the user

        # Ask flask to generate the url corresponding to the login_callback
        # route. This is similar to using reverse() in django.
        redirect_uri = url_for('.login_callback', _external=True)

        client = APIClient(APP_ID, APP_SECRET)
        return redirect(client.authentication_url(redirect_uri))
Exemplo n.º 8
0
def index():
    # We don't have an access token, so we're going to use OAuth to
    # authenticate the user

    # Ask flask to generate the url corresponding to the login_callback
    # route. This is similar to using reverse() in django.
    redirect_uri = url_for('.login_callback', _external=True)

    client = APIClient(APP_ID, APP_SECRET)
    return redirect(client.authentication_url(redirect_uri))
Exemplo n.º 9
0
def index():
    # We don't have an access token, so we're going to use OAuth to
    # authenticate the user

    # Ask flask to generate the url corresponding to the login_callback
    # route. This is similar to using reverse() in django.
    redirect_uri = url_for('.login_callback', _external=True)

    client = APIClient(APP_ID, APP_SECRET)
    return redirect(client.authentication_url(redirect_uri))
Exemplo n.º 10
0
def login_imap_callback(request):
    res = {'website': WEBSITE}

    # logger.info(request)
    code = request.GET['code']

    APP_ID = "e2qdjgra07ea3p3idcv1bea1z"
    APP_SECRET = "dprso40e0tjqk989fab76hqq"
    # Exchange the authorization code for an access token
    client = APIClient(APP_ID, APP_SECRET)
    logger.info(code)
    access_token = client.token_for_code(code)
    logger.info(access_token)

    return HttpResponseRedirect('/editor')
Exemplo n.º 11
0
def index():
    # If the user has already connected to Google via OAuth,
    # `google.authorized` will be True. We also need to be sure that
    # we have a refresh token from Google. If we don't have both of those,
    # that indicates that we haven't correctly connected with Google.
    if not (google.authorized and "refresh_token" in google.token):
        # Google requires HTTPS. The template will display a handy warning,
        # unless we've overridden the check.
        return render_template(
            "before_google.html",
            insecure_override=os.environ.get("OAUTHLIB_INSECURE_TRANSPORT"),
        )

    if "nylas_access_token" not in session:
        # The user has already connected to Google via OAuth,
        # but hasn't yet passed those credentials to Nylas.
        # We'll redirect the user to the right place to make that happen.
        return redirect(url_for("after_google"))

    # If we've gotten to this point, then the user has already connected
    # to both Google and Nylas.
    # Let's set up the SDK client with the OAuth token:
    client = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=session["nylas_access_token"],
    )

    # We'll use the Nylas client to fetch information from Nylas
    # about the current user, and pass that to the template.
    account = client.account
    return render_template("after_connected.html",
                           account=account,
                           client=client)
Exemplo n.º 12
0
def email_fetch():

    client = APIClient(login["nylas_app_id"], login["nylas_app_secret"],
                       login["nylas_token"])

    for message in client.messages.where(unread=True):
        soup = BeautifulSoup(message.body, 'html.parser')
        message.mark_as_read(
        )  # Immediately mark as read to prevent email from being caught up to in the future
        print(str(message))
        print(str(message["from"]))
        print(str(message["cc"]))

        print(soup.get_text())

        if (message["from"][0]["email"]
            ).lower().find("@backtotheroots.com") > 0:
            # Get plaintext, feed to body_get which trims 'Thanks,' forward, find if there are any valid commands
            if not find_command(body_get(soup.get_text())):
                print(body_get(soup.get_text()))
                print("pre-sending-mail")
                mail_sending.send_mail_noattach(
                    message_templates["invalid_command"],
                    message["from"][0]["email"], "")

    return
Exemplo n.º 13
0
def api_client_with_app_id(access_token, api_url, app_id, app_secret):
    return APIClient(
        app_id=app_id,
        app_secret=app_secret,
        access_token=access_token,
        api_server=api_url,
    )
Exemplo n.º 14
0
def verify_auth_status():
    """
    This is an API that verifies the authorization status. Called when user loads up the page.
    """
    from cloud_sql import sql_handler
    uid = flask.session['uid']
    logging.info(f'verifying auth sync status for uid {uid}')
    access_token, email = sql_handler.get_nylas_authorize_info(uid)
    if not access_token:
        logging.info(f'The account {uid} has not authorized yet')
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    try:
        nylas_client = APIClient(
            app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
            app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
            access_token=access_token,
        )
        sync_state = nylas_client.account.sync_state
        logging.info(f'Current syncing status is {sync_state}')
        logging.info(f'The account {uid} is in sync')
        response = flask.jsonify({'email': email or flask.session['email']})
        response.status_code = 200
        return response
    except Exception as e:

        # Here we simplify the status into binary cases.
        # for more statuses, check https://docs.nylas.com/reference#account-sync-status
        logging.warning(f'The account {uid} need resync')
        response = flask.jsonify({'status': 'Need resync'})
        response.status_code = 200
        return response
Exemplo n.º 15
0
def files():
    """
    POST: upload attachment
    GET: get attachment status.
    """
    from cloud_sql import sql_handler
    uid = flask.session.get('uid')
    data = flask.request.files
    logging.info(f'Receiving request {data} for session uid {uid}')
    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    logging.info(f'Retrieved Nylas access token {access_token}')
    nylas = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )
    if flask.request.method == 'POST':
        try:
            # check if the post request has the file part
            logging.info(f'{[key for key in flask.request.files.keys()]}')
            if 'file' not in flask.request.files and 'UploadFiles' not in flask.request.files:
                logging.info('No file part')
                return flask.redirect(flask.request.url)
            file = flask.request.files['UploadFiles'] or flask.request.files['file']
            # if user does not select file, browser also
            # submit an empty part without filename
            if file.filename == '':
                logging.info('No selected file')
                return flask.redirect(flask.request.url)
            if file:
                filename = secure_filename(file.filename)
                logging.info(f'receiving file name {filename}')
                # file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))

                nylas_file = nylas.files.create()
                nylas_file.filename = file.filename
                nylas_file.stream = file
                # .save() saves the file to Nylas, file.id can then be used to attach the file to an email
                nylas_file.save()
                response = flask.jsonify({'file_id': nylas_file.id})
                response.status_code = 200
            return response
        except Exception as e:
            logging.error(f'Uploading attachment failed! Error message is {str(e)}')
            response = flask.jsonify({'error': f'Uploading attachment failed! Error message is {str(e)}'})
            response.status_code = 400
            return response
    elif flask.request.method == 'GET':
        file_id = flask.request.args.get('file_id')
        if not file_id:
            response = flask.jsonify({'error': 'need valid file_id query param'})
            response.status_code = 412
        nylas_file = nylas.files.get(file_id)
        response = flask.jsonify({'file': nylas_file})
        response.status_code = 200
        return response
Exemplo n.º 16
0
def send_email():
    from cloud_sql import sql_handler
    uid = flask.session.get('uid')
    data = flask.request.json
    logging.info(f'Receiving request {data} for session uid {uid}')
    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    logging.info(f'Retrieved Nylas access token {access_token}')
    nylas = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )
    try:
        draft = nylas.drafts.create()
        draft.subject = data.get('subject')
        draft.body = data.get('body')
        draft.to = data.get('to')
        draft.cc = data.get('cc')
        draft.send()
        logging.info('email sent successfully')
        response = flask.jsonify('email sent successfully')
        response.status_code = 200
        return response
    except Exception as e:
        logging.error(f'Sending email failed! Error message is {str(e)}')
        response = flask.jsonify(str(e))
        response.status_code = 400
        return response
Exemplo n.º 17
0
def emails(id):
    from nylas import APIClient

    nylas = APIClient(creds.CLIENT_ID, creds.CLIENT_SECRET, creds.ACCESS_TOKEN)

    data = nylas.messages.get(id)

    return render_template("emails.html", data=data)
Exemplo n.º 18
0
def emailsearch():
    from nylas import APIClient

    nylas = APIClient(creds.CLIENT_ID, creds.CLIENT_SECRET, creds.ACCESS_TOKEN)

    data = Search()

    return render_template("email-search.html", data=data)
Exemplo n.º 19
0
def index(pagenr):
    session['contact_mails'] = []
    session['contact_addresses'] = []
    offset = pagenr
    # If we have an access_token, we may interact with the Nylas Server
    if 'access_token' in session:
        client = APIClient(APP_ID, APP_SECRET, session['access_token'])
        threads = None
        while not threads:
            try:
                # Get the latest message from namespace zero.
                threads = client.threads.where(**{'in': 'all', 'limit': 20, 'offset':0, 'view':'expanded' })
                if not threads:  # A new account takes a little time to sync
                    print "No messages yet. Checking again in 2 seconds."
                    time.sleep(2)
            except Exception as e:
                print(e.message)
                return Response("<html>An error occurred.</html>")
        # Format the output
        text = 'mit navn det står med prikker'
        for thread in threads:
                    text += thread.snippet
        #text = "<html><h1>Here's a message from your inbox:</h1><b>From:</b> "
        #for sender in message["from"]:
        #    text += "{} &lt;{}&gt;".format(sender['name'], sender['email'])
        #text += "<br /><b>Subject:</b> " + message.subject
        #text += "<br /><b>Body:</b> " + message.body
        #text += "</html>"

        # Return result to the client
        return Response(text)
    else:
        # We don't have an access token, so we're going to use OAuth to
        # authenticate the user

        # Ask flask to generate the url corresponding to the login_callback
        # route. This is similar to using reverse() in django.
        redirect_uri = url_for('.login_callback', _external=True)

        client = APIClient(APP_ID, APP_SECRET)
        return redirect(client.authentication_url(redirect_uri))
Exemplo n.º 20
0
def callback(request):
    # Get the state saved in session
    expected_state = request.session.pop('auth_state', '')
    # Make the token request

    token = get_token_from_code(request.get_full_path(), expected_state)
    # Get the user's profile
    user = get_user(token)
    # #Get nylas code
    api_client = APIClient(app_id="57j65z6aezdxuocajwwegvkyx",
                           app_secret="du2z08iomhm6remzvzyhk8bz9")
    response_body = {
        "client_id": api_client.app_id,
        "name": user['givenName'],
        "email_address": user['mail'],
        "provider": "office365",
        "settings": {
            "microsoft_client_id": settings['app_id'],
            "microsoft_client_secret": settings['app_secret'],
            "microsoft_refresh_token": token['refresh_token'],
            "redirect_uri": settings['redirect'],
        },
        "scopes": "email.read_only,calendar"
    }
    nylas_authorize_resp = requests.post(
        "https://api.nylas.com/connect/authorize", json=response_body)

    nylas_code = nylas_authorize_resp.json()["code"]

    # Get nylas access_token

    nylas_token_data = {
        "client_id": api_client.app_id,
        "client_secret": api_client.app_secret,
        "code": nylas_code,
    }

    nylas_token_resp = requests.post("https://api.nylas.com/connect/token",
                                     json=nylas_token_data)

    if not nylas_token_resp.ok:
        message = nylas_token_resp.json()["message"]
        return requests.Response('Bad Request')

    nylas_access_token = nylas_token_resp.json()["access_token"]

    print(nylas_access_token)

    # Save token and user
    store_token(request, token)
    store_user(request, user)

    return HttpResponseRedirect(reverse('home'))
Exemplo n.º 21
0
def revoke_auth():
    """
    This API essentially unauthorize and removes the customer from the Nylas authentication, along with auth for the
    Calendar and email accounts.
    """

    from cloud_sql import sql_handler
    uid = flask.session['uid']
    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        logging.info(f'The account {uid} has not authorized yet')
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    nylas_client = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token,
    )
    nylas_client.revoke_all_tokens()
    response = flask.jsonify('OK')
    response.status_code = 200
    return response
Exemplo n.º 22
0
def success():
    if "nylas_access_token" not in session:
        return render_template("missing_token.html")

    client = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=session["nylas_access_token"],
    )

    # We'll use the Nylas client to fetch information from Nylas
    # about the current user, and pass that to the template.
    account = client.account
    return render_template("success.html", account=account)
Exemplo n.º 23
0
def events(event_id):
    from cloud_sql import sql_handler
    if not event_id:
        logging.error('Need a valid event id')
        response = flask.jsonify('Need a valid event id')
        response.status_code = 400
        return response
    uid = flask.session.get('uid')
    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        logging.info(f'The account {uid} has not authorized yet')
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    nylas_client = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )
    try:
        if flask.request.method == "GET":
            event = nylas_client.events.get(event_id)
            response = flask.jsonify(event_to_dict(event))
            response.status_code = 200
            return response
        elif flask.request.method == "DELETE":
            nylas_client.events.delete(event_id, notify_participants='true')
            response = flask.jsonify('{Status: OK}')
            response.status_code = 200
            return response
        elif flask.request.method == "PUT":
            data = flask.request.json
            event = nylas_client.events.where(event_id=event_id).first()
            if not event:
                response = flask.jsonify('unable to modify event')
                response.status_code = 400
                return response
            event = update_event_from_json(event, data, event.calendar_id)
            event.save(notify_participants='true')
            logging.info('Calendar event updated successfully')
            response = flask.jsonify('Calendar event updated successfully')
            response.status_code = 200
            return response
    except Exception as e:
        response = flask.jsonify(str(e))
        response.status_code = 400
        return response
Exemplo n.º 24
0
def get_email_thread():
    from cloud_sql import sql_handler
    uid = flask.session.get('uid')
    data = flask.request.json
    logging.info(f'Receiving request {data} for session uid {uid}')

    search_email = flask.request.args.get('email')
    sender_email = flask.session.get('email')
    if not search_email:
        response = flask.jsonify({'error': 'need valid search_email query param'})
        response.status_code = 412
        return response

    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    logging.info(f'Retrieved Nylas access token {access_token}')
    nylas = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )
    try:
        # Return all messages found in the user's inbox
        full_message = []
        messages_to = nylas.messages.where(to=search_email)
        for m in messages_to:
            message = message_to_dict(m)
            if len(message['from']) > 0 and message['from'][0]['email'] == sender_email:
                full_message.append(message)

        messages_from = nylas.messages.where(from_=search_email)
        for m in messages_from:
            message = message_to_dict(m)
            if len(message['to']) > 0 and message['to'][0]['email'] == sender_email:
                full_message.append(message)
        full_message.sort(key=lambda x: x['received_at'], reverse=True)
        response = flask.jsonify(full_message[0:50])
        response.status_code = 200
        return response
    except Exception as e:
        logging.error(f'Sending email failed! Error message is {str(e)}')
        response = flask.jsonify(str(e))
        response.status_code = 400
        return response
Exemplo n.º 25
0
def create_calendar_event():
    from cloud_sql import sql_handler
    uid = flask.session.get('uid')
    data = flask.request.json
    logging.info(f'Receiving request {data} for session uid {uid}')
    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    nylas = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )

    # Most user accounts have multiple calendars where events are stored
    calendars = nylas.calendars.all()
    calendar_id = ''
    for calendar in calendars:
        # Print the name and description of each calendar and whether or not the calendar is read only
        logging.info("Name: {} | Description: {} | Read Only: {} | ID: {}".format(
            calendar.name, calendar.description, calendar.read_only, calendar.id))
        if calendar.read_only:
            continue
        calendar_id = calendar.id
        logging.info(f'Found a valid writable calendar {calendar.name}')
    if not calendar_id:
        response = flask.jsonify({'status': 'No writable calendar found!'})
        response.status_code = 400
        return response

    # Create a new event
    event = nylas.events.create()
    event = update_event_from_json(event, data, calendar_id)

    # .save()must be called to save the event to the third party provider
    # The event object must have values assigned to calendar_id and when before you can save it.
    event.save(notify_participants='true')
    # notify_participants='true' will send a notification email to
    # all email addresses specified in the participant subobject
    logging.info('calendar event created successfully')
    response = flask.jsonify('calendar event created successfully')
    response.status_code = 200
    return response
Exemplo n.º 26
0
def send_email_util(subject, body, to_email, to_name,
               bcc_email='*****@*****.**', bcc_name='lifo customer support',
               uid=None):
    """
    This method is a generic email sending util without attachments.
    """
    from cloud_sql import sql_handler
    if not uid:
        uid = flask.session.get('uid')
    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    logging.info(f'Retrieved Nylas access token')
    nylas = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )
    try:
        draft = nylas.drafts.create()
        draft.subject = subject
        draft.to = [{'email': to_email, 'name': to_name}]

        # bcc our Lifo's internal support account to allow better tracking.
        draft.bcc = [{'email': bcc_email, 'name': bcc_name}]
        draft.body = body
        draft.tracking = {'links': 'true',
                          'opens': 'true',
                          'thread_replies': 'true',
                          }
        draft.send()
        logging.info('email sent successfully')
        response = flask.jsonify('email sent successfully')
        response.status_code = 200
        return response
    except Exception as e:
        logging.error(f'Sending email failed! Error message is {str(e)}')
        response = flask.jsonify(str(e))
        response.status_code = 400
        return response
Exemplo n.º 27
0
def authorize(request):

    api_client = APIClient(app_id="57j65z6aezdxuocajwwegvkyx",
                           app_secret="du2z08iomhm6remzvzyhk8bz9")

    response_body = {
        "client_id": api_client.app_id,
        "name": "alexandra",
        "email_address": request.data.get('email'),
        "provider": "outlook",
        "settings": {
            "username": request.data.get('email'),
            "password": request.data.get('password'),
        }
    }

    nylas_authorize_resp = requests.post(
        "https://api.nylas.com/connect/authorize", json=response_body)
    print(nylas_authorize_resp.json())
    # nylas_code = nylas_authorize_resp.json()["code"]

    nylas_code = 'd80cOfUCvwW-teOcAtvh'
    state = 'WM6D'
    nylas_token_data = {
        "client_id": api_client.app_id,
        "client_secret": api_client.app_secret,
        "code": nylas_code,
        "state": state
    }

    nylas_token_resp = requests.post("https://api.nylas.com/connect/token",
                                     json=nylas_token_data)

    if not nylas_token_resp.ok:
        message = nylas_token_resp.json()["message"]
        return Response('Bad Request')

    nylas_access_token = nylas_token_resp.json()["access_token"]

    data = {"code": nylas_code, "access_token": nylas_access_token}
    return Response(data)
Exemplo n.º 28
0
def index():
    if 'google_credentials' not in flask.session:
        return flask.render_template('index.html')

    # The user has authorized with google at this point but we will need to
    # connect the account to Nylas
    if 'nylas_access_token' not in flask.session:
        google_credentials = flask.session['google_credentials']
        google_access_token = google_credentials['access_token']
        email_address = get_email(google_access_token)
        google_refresh_token = google_credentials['refresh_token']
        connect_to_nylas(google_refresh_token, email_address)
        return flask.redirect(flask.url_for('index'))

    # Google account has been setup, let's use Nylas' python SDK to retrieve an
    # email
    client = APIClient(NYLAS_CLIENT_ID, NYLAS_CLIENT_SECRET,
                       flask.session['nylas_access_token'])

    # Display the latest email message!
    return client.threads.first().messages.first().body
Exemplo n.º 29
0
def get_thread_by_id():
    from cloud_sql import sql_handler
    uid = flask.session.get('uid')
    data = flask.request.json
    logging.info(f'Receiving request {data} for session uid {uid}')

    thread_id = flask.request.args.get('thread_id')
    if not thread_id:
        response = flask.jsonify({'error': 'need valid thread_id query param'})
        response.status_code = 412
        return response

    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    logging.info(f'Retrieved Nylas access token {access_token}')
    nylas = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )

    try:
        full_message = []
        messages = nylas.messages.where(thread_id=thread_id)
        for m in messages:
            message = message_to_dict(m)
            full_message.append(message)
        full_message.sort(key=lambda x: x['received_at'])
        response = flask.jsonify(full_message)
        response.status_code = 200
        return response
    except Exception as e:
        logging.error(f'Sending email failed! Error message is {str(e)}')
        response = flask.jsonify(str(e))
        response.status_code = 400
        return response
Exemplo n.º 30
0
def index():
    # If the user has already connected to Nylas via OAuth,
    # `nylas.authorized` will be True. Otherwise, it will be False.
    if not nylas.authorized:
        # OAuth requires HTTPS. The template will display a handy warning,
        # unless we've overridden the check.
        return render_template(
            "before_authorized.html",
            insecure_override=os.environ.get("OAUTHLIB_INSECURE_TRANSPORT"),
        )

    # If we've gotten to this point, then the user has already connected
    # to Nylas via OAuth. Let's set up the SDK client with the OAuth token:
    nylas_client = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=nylas.access_token,
    )

    # We'll use the Nylas client to fetch information from Nylas
    # about the current user, and pass that to the template.
    account = nylas_client.account
    return render_template("after_authorized.html", account=account)
Exemplo n.º 31
0
def get_lifo_events():
    """
    Currently we rely on the hardcoded LIFO_CALENDAR_EVENT_SIGNATURE for events filtering.
    In future we may want to save all the events created by our product, and then get accordingly. 
    But this will force us to fully manage the events life cycle.
    """
    from cloud_sql import sql_handler
    uid = flask.session.get('uid')
    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        logging.info(f'The account {uid} has not authorized yet')
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    nylas_client = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )
    events = nylas_client.events.where(description=LIFO_CALENDAR_EVENT_SIGNATURE)
    logging.info(f'Found events {str(events)}')
    response = flask.jsonify([event_to_dict(event) for event in events])
    response.status_code = 200
    return response
Exemplo n.º 32
0
def threads_contacts(offset):
    # If we have an access_token, we may interact with the Nylas Server
    #session['access_token'] = 'aC8stzQsDBR0ywlOmhCuyIBdu5uJYc'
    if 'access_token' in session:
        client = APIClient(APP_ID, APP_SECRET, session['access_token'])
        print session['access_token']
        if 'threads_contacts' not in session:
            session['threads_contacts'] = []
        if 'threads_contacts_addresses' not in session:
            session['threads_contacts_addresses'] = []
        if 'threads_contacts_offset' not in session:
            session['threads_contacts_offset'] = 0
        if 'threads_contacts_ids' not in session:
            session['threads_contacts_ids'] = []
        last_thread = False
        #session['threads_contacts'] = []
        #session['threads_contacts_addresses'] = []
        #session['threads_contacts_offset'] = 0
        #session['threads_contacts_ids'] = []
        while (len(session['threads_contacts']) + 1 < (offset + 1) * 10):
            threadcounter = 0

            for thread in client.threads.where(offset=session['threads_contacts_offset'], limit=99, in_='inbox'): #**{'in':'all', 'limit':40, 'offset':2}:
                threadcounter = threadcounter + 1
                if len(thread.participants) <= 2:
                    if len(thread.participants) == 1:
                        name = thread.participants[0]['name']
                        email = thread.participants[0]['email']
                    if len(thread.participants) == 2:
                        for participant in thread.participants:
                            if participant['email'] != '*****@*****.**':
                                name = participant['name']
                                email = participant['email']

                    if email not in session['threads_contacts_addresses'] and thread['id'] not in session['threads_contacts_ids']:
                                contact_thread = {
                                'id': thread['id'],
                                'date': thread['last_message_timestamp'],
                                'name': name, #thread.participants[0]['name'],
                                'email': email, #thread.participants[0]['email'],
                                'snippet': thread['snippet'],
                                'unread': thread['unread'],
                                'type': 'email'
                                }
                                session['threads_contacts'].append(contact_thread)
                                session['threads_contacts_addresses'].append(email)
                                session['threads_contacts_ids'].append(thread['id'])

                if (len(thread.participants) > 2) and (thread['id'] not in session['threads_contacts_ids']):
                    name = ''
                    emails = ''
                    for participant in thread.participants:
                        if participant['name']:
                            name += participant['name'] + ', '
                            emails += participant['email'] + ', '
                        else:
                            name += participant['email'] + ', '
                            emails += participant['email'] + ', '

                    contact_thread = {
                                'id': thread['id'],
                                'date': thread['last_message_timestamp'],
                                'name': name,
                                'email': emails,
                                'snippet': thread['snippet'],
                                'unread': thread['unread'],
                                'type': 'thread'
                                }
                    session['threads_contacts'].append(contact_thread)
                    session['threads_contacts_ids'].append(thread['id'])


            session['threads_contacts_offset'] = session['threads_contacts_offset'] + 1
            if threadcounter < 99:
                last_thread = True
                break

            # Return result to the client
        if offset == 0:
            start = 0
            end = 10
        else:
            start = offset * 10
            end = (offset + 1) * 10
        response = {'contacts': session['threads_contacts'][start:end], 'lastThread': last_thread}
        js = json.dumps(response)
        resp = Response(js, status=200, mimetype='application/json')
        return resp
    else:
        # We don't have an access token, so we're going to use OAuth to
        # authenticate the user

        # Ask flask to generate the url corresponding to the login_callback
        # route. This is similar to using reverse() in django.
        redirect_uri = url_for('.login_callback', _external=True)

        client = APIClient(APP_ID, APP_SECRET)
        return redirect(client.authentication_url(redirect_uri))
Exemplo n.º 33
0
def api_client(api_url):
    return APIClient(app_id=None,
                     app_secret=None,
                     access_token=None,
                     api_server=api_url)
Exemplo n.º 34
0
        """
        This example will only work if you replace the fake configuration
        values in `config.json` with real configuration values.
        The following config values need to be replaced:
        {keys}
        Consult the README.md file in this directory for more information.
    """
    ).format(keys=", ".join(cfg_needs_replacing))
    print(message, file=sys.stderr)
    sys.exit(1)

# Teach Flask how to find out that it's behind an ngrok proxy
app.wsgi_app = ProxyFix(app.wsgi_app)

redirect_url = "https://nylas-customer-example.herokuapp.com/login_callback"
client = APIClient(app.config["NYLAS_OAUTH_CLIENT_ID"],
                   app.config["NYLAS_OAUTH_CLIENT_SECRET"])


# Define what Flask should do when someone visits the root URL of this website.
@app.route("/", methods=['GET'])
def index():
    # If the user has already connected to Nylas via OAuth,
    # `nylas.authorized` will be True. Otherwise, it will be False.
    if session.get('access_token') is not None:
        # If we've gotten to this point, then the user has already connected
        # to Nylas via OAuth. Let's set up the SDK client with the OAuth token:
        client.access_token = session['access_token']

        # We'll use the Nylas client to fetch information from Nylas
        # about the current user, and pass that to the template.
        try:
Exemplo n.º 35
0
#!/usr/bin/python

import time
from nylas import APIClient
from nylas.util import generate_id

APP_ID = '[YOUR_APP_ID]'
APP_SECRET = '[YOUR_APP_SECRET]'
ACCESS_TOKEN = '[YOUR_ACCESS_TOKEN]'
client = APIClient(APP_ID, APP_SECRET, ACCESS_TOKEN)

subject = generate_id()

f = open('test.py', 'r')
data = f.read()
f.close()

myfile = client.files.create()
myfile.filename = 'test.py'
myfile.data = data

# Create a new draft
draft = client.drafts.create()
draft.to = [{'name': 'Charles Gruenwald', 'email': '*****@*****.**'}]
draft.subject = subject
draft.body = ""
draft.attach(myfile)
draft.send()

x = 0
th = client.threads.where({'in': 'Sent', 'subject': subject}).first()
Exemplo n.º 36
0
def authorize():
    """
    This API authenticate for a chosen scope, and saves the nylas access code to cloud sql.
    Note: this API is the single entry point for authorization flow, and it will deactivate all previous access tokens
    for the given Nylas id.
    :return: flask response, 200 if success, 400 if failed.
    """
    from cloud_sql import sql_handler
    nylas_code = flask.request.args.get('code')
    error = flask.request.args.get('error')

    uid = flask.session['uid']
    logging.info(f'verifying auth sync status for uid {uid}')
    access_token = sql_handler.get_nylas_access_token(uid)

    # this is to handle potential authorization errors including access denied by customers.
    if error:
        logging.error(f'Authorization failed due to error: {error}')
        response = flask.jsonify(error)
        response.status_code = 400
        return response
    nylas_client = APIClient(app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
                             app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"])
    if not nylas_code:
        scope = flask.request.args.get('scope')
        if not scope:
            logging.error('Need a valid scope string, currently supporting: calendar,email.send,email.modify')
            scope = 'calendar,email.send,email.modify'
        redirect_url = 'http://auth.lifo.ai/authorize'
        logging.info(f'receiving request for scope {scope}, and redirect to {redirect_url}')
        flask.session['scope'] = scope

        # Redirect your user to the auth_url
        auth_url = nylas_client.authentication_url(
            redirect_url,
            scopes=scope
        )
        return flask.redirect(auth_url)
    else:
        # note, here we have not handled the declined auth case
        logging.info(f'authentication success with code: {nylas_code}')
        access_token = nylas_client.token_for_code(nylas_code)
        nylas_client = APIClient(
            app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
            app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
            access_token=access_token,
        )

        # Revoke all tokens except for the new one
        nylas_client.revoke_all_tokens(keep_access_token=access_token)

        account = nylas_client.account
        nylas_account_id = account.id
        nylas_email = account.email_address

        uid = flask.session['uid']
        scope = flask.session['scope']
        logging.info(f'handling auth for firebase uid: {uid} for scope {scope} and nylas id {nylas_account_id}')

        # Note: here we automatically handle the Nylas id changing case, as each user is recognized by their firebase
        # uid, and any new Nylas ids will be overwritten. This does bring in limitations: a user can only authorize one
        # Calendar account, which is not an issue for foreseeable future.
        sql_handler.save_nylas_token(uid, nylas_access_token=access_token, nylas_account_id=nylas_account_id, email=nylas_email)
    return render_template("authorize_succeed.html")
Exemplo n.º 37
0
def send_single_email_with_template():
    """
    This method sends email with template, and replace:
    ${receiver_name} with to_name
    ${file_id} (if any) with file_id
    """
    from cloud_sql import sql_handler
    uid = flask.session.get('uid')
    data = flask.request.json
    logging.info(f'Receiving request {data} for session uid {uid}')
    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    logging.info(f'Retrieved nylas access token')
    nylas = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )
    try:
        draft = nylas.drafts.create()
        if not data.get('subject') or not data.get('body') or not data.get('to_email') or not data.get('to_name'):
            response = flask.jsonify({'error': 'need valid file_id query param'})
            response.status_code = 412
        draft.subject = data.get('subject')
        body = data.get('body')

        #Note: should to_name be account_id instead?
        body = body.replace("$(receiver_name)", data.get('to_name'))

        # note: need to anonymize the email for external url usage.
        body = body.replace("$(inf_email)", data.get('to_email'))
        brand_campaign_id = data.get('brand_campaign_id')
        body = body.replace("$(brand_campaign_id)", brand_campaign_id)

        draft.to = [{'email': data.get('to_email'), 'name': data.get('to_name')}]

        # bcc our Lifo's internal support account to allow better tracking.
        draft.bcc = [{'email': '*****@*****.**', 'name': 'lifo customer support'}]
        if data.get('file_id'):
            file = nylas.files.get(data.get('file_id'))
            draft.attach(file)
            body = body.replace("$(file_id)", file.id)

        # when reply a thread
        if data.get('reply_to_message_id'):
            draft.reply_to_message_id = data.get('reply_to_message_id')
        draft.body = body
        draft.tracking = {'links': 'true',
                          'opens': 'true',
                          'thread_replies': 'true',
                          'payload': data.get('campaign_name')
                          }

        """
        Here we access influencer sub_collection under each brand campaign. This is to replicate the following
        function from Nodejs side under api_nodejs service. 
            function access_influencer_subcollection(brand_campaign_id) {
                return db.collection(BRAND_CAMPAIGN_COLLECTIONS).doc(brand_campaign_id)
                    .collection(INFLUENCER_COLLECTIONS);
            }
        """
        inf_account_id = data.get('account_id')
        if inf_account_id != 'lifo' and data.get('to_name') != 'lifo' and 'lifo.ai' not in data.get('to_email'):
            emails_ref = db.collection(BRAND_CAMPAIGN_COLLECTIONS,
                                       brand_campaign_id,
                                       INFLUENCER_COLLECTIONS,
                                       inf_account_id,
                                       EMAILS_COLLECTIONS)
            hash_value = hashlib.sha256(body.encode('utf-8')).hexdigest()
            same_email_list = emails_ref.where('subject', u'==', draft.subject).where('body_hash', u'==', hash_value).get()
            logging.info(f'Found repeated email list {same_email_list}')
            if len(same_email_list) > 0:
                logging.info('Repeatedly sending the same emails!')
                response = flask.jsonify({'status': 'Repeated emails'})
                response.status_code = 429
                return response

            email_history = {
                'ts': firestore.SERVER_TIMESTAMP,
                'body': draft.body,
                'body_hash': hash_value,
                'subject': draft.subject,
                'to': draft.to,
                'file_id': data.get('file_id')
            }
            emails_ref.document().set(email_history)
        send_result = draft.send()
        logging.info(send_result)
        # Update influencer status
        influencer_ref = db.document(BRAND_CAMPAIGN_COLLECTIONS,
                                         brand_campaign_id,
                                         INFLUENCER_COLLECTIONS,
                                         inf_account_id)
        influencer_update_body = {}
        if data.get('for_contract'):
            influencer_update_body['inf_contract_status'] = 'Email sent'
            if not data.get('reply_to_message_id'):
                influencer_update_body['inf_contract_thread'] = send_result['thread_id']
                influencer_update_body['contract_received_time'] = time.time()
        else:
            influencer_update_body['inf_contacting_status'] = 'Email sent'
            if not data.get('reply_to_message_id'):
                influencer_update_body['inf_offer_thread'] = send_result['thread_id']
                influencer_update_body['offer_received_time'] = time.time()
        influencer_ref.set(
            influencer_update_body,
            merge=True
        )

        logging.info('email sent successfully')
        response = flask.jsonify(send_result)
        response.status_code = 200
        return response
    except Exception as e:
        logging.error(f'Sending email failed! Error message is {str(e)}')
        response = flask.jsonify(str(e))
        response.status_code = 400
        return response
Exemplo n.º 38
0
def send_email_to_brand():
    """
    This method sends email with template, and replace:
    ${receiver_name} with to_name
    ${file_id} (if any) with file_id
    """
    from cloud_sql import sql_handler
    uid = flask.session.get('uid')
    sender_name = flask.session.get('name')
    sender_email = flask.session.get('email')
    # Some user does not have 'name' field, add a temp hack here
    if not sender_name:
        sender_name = sender_email
    data = flask.request.json
    logging.info(f'Receiving request {data} for session uid {uid}')
    access_token = sql_handler.get_nylas_access_token(uid)
    if not access_token:
        response = flask.jsonify({'status': 'no auth'})
        response.status_code = 402
        return response
    logging.info(f'Retrieved nylas access token {access_token}')
    nylas = APIClient(
        app_id=app.config["NYLAS_OAUTH_CLIENT_ID"],
        app_secret=app.config["NYLAS_OAUTH_CLIENT_SECRET"],
        access_token=access_token
    )
    try:
        draft = nylas.drafts.create()
        if not data.get('subject') or not data.get('body') or not data.get('to_email') or not data.get('to_name'):
            response = flask.jsonify({'error': 'need valid file_id query param'})
            response.status_code = 412
        draft.subject = data.get('subject')
        body = data.get('body')
        body = body.replace("$(receiver_name)", data.get('to_name'))
        draft.to = [{'email': data.get('to_email'), 'name': data.get('to_name')}]

        # bcc our Lifo's internal support account to allow better tracking.
        draft.bcc = [{'email': '*****@*****.**', 'name': 'lifo customer support'}]
        if data.get('file_id'):
            file = nylas.files.get(data.get('file_id'))
            draft.attach(file)
            body = body.replace("$(file_id)", file.id)
        draft.body = body
        draft.tracking = {'links': 'true',
                          'opens': 'true',
                          'thread_replies': 'true',
                          'payload': data.get('campaign_name') or f'{sender_name} <{sender_email}>'
                          }

        brand_campaign_id = data.get('brand_campaign_id')
        emails_ref = db.collection(BRAND_CAMPAIGN_COLLECTIONS,
                                   brand_campaign_id,
                                   EMAILS_COLLECTIONS)
        email_history = {
            'ts': firestore.SERVER_TIMESTAMP,
            'body': draft.body,
            'subject': draft.subject,
            'to': draft.to,
            'file_id': data.get('file_id')
        }
        emails_ref.document().set(email_history)
        draft.send()
        logging.info('email sent successfully')
        response = flask.jsonify('email sent successfully')
        response.status_code = 200
        return response
    except Exception as e:
        logging.error(f'Sending email failed! Error message is {str(e)}')
        response = flask.jsonify(str(e))
        response.status_code = 400
        return response