美文网首页干货代码改变世界湿货
使用AWS亚马逊云搭建Gmail转发服务(一)

使用AWS亚马逊云搭建Gmail转发服务(一)

作者: 青南 | 来源:发表于2014-12-30 18:49 被阅读415次

    故事背景

    2014年12月28号开始,Gmail被伟大的墙从协议上封禁,POP3、SMTP、IAMP全部阵亡。于是不仅网页不能打开Gmail,连邮件客服端都不能使用Gmail收发邮件了。

    Gmail在国内的用户相当的广泛,难道就真的不用了吗?当然不是。虽然使用VPN可以翻出长城,但是开着VPN做其他事情又不太方便。于是,一种Gmail的转发服务变得重要起来。

    这篇文章将详细介绍如何使用亚马逊云AWS的免费主机EC2,配合Gmail的API来编写一个Gmail的转发程序。程序在设定时间内访问Gmail收件箱,发现新邮件以后,就通过另一个邮箱转发到国内邮箱中。每一次转发记录到一个日志文件中,并使用Flask搭建网站来,从而直观的检查接收发送记录。

    AWS的免费主机EC2的申请不是本文的重点,网上有很多教程,故略去不讲。
    Flask环境的搭建不是本文重点,网上有很多教程,故略去不讲。

    本篇先讲解Gmail API的使用,下一篇讲解如何制作转发程序。

    授权之路

    既然要是用Gmail的API,那就要开通Gmail的授权。Google的官方英文教程请戳->Run a Gmail App in Python

    打开Gmail API

    访问https://console.developers.google.com/project,单击“建立档案”选项,新建一个项目。我这里新建的项目叫做“gmail”,如下图:

    单击新建的档案“gmail”,在左侧点击“API和验证”,选择“API”,然后再右侧中间搜索框中输入Gmail,找到后打开。如下图:

    然后点击左侧“凭证”,选择“建立新的用户端ID”

    这个时候注意一定要选择第三项,才能正确生成json文件。选择第三项,并填写完一些信息后,做如下选择,并点击“建立用户端ID”

    接下来,下载json文件。

    验证机器

    在服务器上新建ghelper文件夹:

    mkdir ghelper
    cd ghelper
    

    然后安装Google API Python Client库。建议使用pip安装而不是easy_install,因为pip安装的库文件可以卸载,而easy_install安装的库文件不能卸载。

    sudo pip install --upgrade google-api-python-client
    

    为了使代码中的run.tools()能够正常执行,还需要安装gflags:

    sudo pip install python-gflags
    

    将json文件上传到AWS服务器上,我放在了~/wwwproject/ghelper目录下面,并且重命名为client_secret.json,这样代码就不需要进行修改了。同时在本目录下面新建ghelper_api.py文件,文件内容为官方指南中的验证机器的代码,如下:

    import httplib2
    
    from apiclient.discovery import build
    from oauth2client.client import flow_from_clientsecrets
    from oauth2client.file import Storage
    from oauth2client.tools import run
    
    # Path to the client_secret.json file downloaded from the Developer Console
    CLIENT_SECRET_FILE = 'client_secret.json'
    
    # Check https://developers.google.com/gmail/api/auth/scopes for all available scopes
    OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.readonly'
    
    # Location of the credentials storage file
    STORAGE = Storage('gmail.storage')
    
    # Start the OAuth flow to retrieve credentials
    flow = flow_from_clientsecrets(CLIENT_SECRET_FILE, scope=OAUTH_SCOPE)
    http = httplib2.Http()
    
    # Try to retrieve credentials from storage or run the flow to generate them
    credentials = STORAGE.get()
    if credentials is None or credentials.invalid:
      credentials = run(flow, STORAGE, http=http)
    
    # Authorize the httplib2.Http object with our credentials
    http = credentials.authorize(http)
    
    # Build the Gmail service from discovery
    gmail_service = build('gmail', 'v1', http=http)
    
    # Retrieve a page of threads
    threads = gmail_service.users().threads().list(userId='me').execute()
    
    # Print ID for each thread
    if threads['threads']:
      for thread in threads['threads']:
        print 'Thread ID: %s' % (thread['id'])
    

    运行ghelper_api.py,进入Google验证阶段。

    python ghelper_api.py
    

    在红线处按回车键就可以进入输入模式。输入gmail和密码以后,移动光标到“Sign in”回车,然后进入如下页面:

    输入你的信息,验证通过以后会让你进入开启浏览器的javascript功能。可是Linux服务器哪来的浏览器?这个时候按键盘的Ctrl + Z来取消。

    继续输入:

    python ghelper_api.py --noauth_local_webserver
    

    会提示离线验证,如果仍然失败的话,就继续Ctrl+Z然后再输入上面的代码,很快就会让你离线验证:

    复制他给出的网址,并在自己电脑上登录后,复制他给出的代码并粘贴回服务器上。验证通过。

    使用API

    打开API Reference,查看Gmail API的用法。

    这里用Users.messages的list和get方法来演示API的使用。

    先查看list的说明:

    Lists the messages in the user's mailbox.

    列出邮箱里的信息。这里实际上列出来的是每一封邮件的id,于是,使用这个id,通过get就能获得邮件的内容。

    通过查看list和get的使用范例:

    list:
    https://developers.google.com/gmail/api/v1/reference/users/messages/list
    get:
    https://developers.google.com/gmail/api/v1/reference/users/messages/get

    构造出以下的完整代码:

    #-*-coding:utf-8 -*-
    import httplib2
    
    from apiclient.discovery import build
    from oauth2client.client import flow_from_clientsecrets
    from oauth2client.file import Storage
    from oauth2client.tools import run
    from apiclient import errors
    import base64
    import email
    
    
    # Path to the client_secret.json file downloaded from the Developer Console
    CLIENT_SECRET_FILE = 'client_secret.json'
    
    # Check https://developers.google.com/gmail/api/auth/scopes for all available scopes
    OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.readonly'
    
    # Location of the credentials storage file
    STORAGE = Storage('gmail.storage')
    
    # Start the OAuth flow to retrieve credentials
    flow = flow_from_clientsecrets(CLIENT_SECRET_FILE, scope=OAUTH_SCOPE)
    http = httplib2.Http()
    
    # Try to retrieve credentials from storage or run the flow to generate them
    credentials = STORAGE.get()
    if credentials is None or credentials.invalid:
      credentials = run(flow, STORAGE, http=http)
    
    # Authorize the httplib2.Http object with our credentials
    http = credentials.authorize(http)
    
    # Build the Gmail service from discovery
    gmail_service = build('gmail', 'v1', http=http)
    
    # Retrieve a page of threads
    # threads = gmail_service.users().threads().list(userId='me').execute()
    
    # # Print ID for each thread
    # if threads['threads']:
    #   for thread in threads['threads']:
    #     print 'Thread ID: %s' % (thread['id'])
    
    def ListMessagesWithLabels(service, user_id, label_ids=[]):
      """List all Messages of the user's mailbox with label_ids applied.
    
      Args:
        service: Authorized Gmail API service instance.
        user_id: User's email address. The special value "me"
        can be used to indicate the authenticated user.
        label_ids: Only return Messages with these labelIds applied.
    
      Returns:
        List of Messages that have all required Labels applied. Note that the
        returned list contains Message IDs, you must use get with the
        appropriate id to get the details of a Message.
      """
      try:
        response = service.users().messages().list(userId=user_id,
                                                   labelIds=label_ids).execute()
        messages = []
        if 'messages' in response:
          messages.extend(response['messages'])
    
        while 'nextPageToken' in response:
          page_token = response['nextPageToken']
          response = service.users().messages().list(userId=user_id,
                                                     labelIds=label_ids,
                                                     pageToken=page_token).execute()
          messages.extend(response['messages'])
    
        return messages
      except errors.HttpError, error:
        print 'An error occurred: %s' % error
    
    def GetMessage(service, user_id, msg_id):
      """Get a Message with given ID.
    
      Args:
        service: Authorized Gmail API service instance.
        user_id: User's email address. The special value "me"
        can be used to indicate the authenticated user.
        msg_id: The ID of the Message required.
    
      Returns:
        A Message.
      """
      try:
        message = service.users().messages().get(userId=user_id, id=msg_id).execute()
    
        print 'Message snippet: %s' % message['snippet']
    
        return message
      except errors.HttpError, error:
        print 'An error occurred: %s' % error
    
    a = ListMessagesWithLabels(gmail_service,'me')[0]['id']
    b = GetMessage(gmail_service,'me',a)
    print b['snippet']
    print b['payload']['headers'][3]['value']
    

    通过观察GetMessage返回的数据,可以看到,返回的是一个字典dict,邮件的内容在key为snippet的里面。发件人在['payload']['headers'][3]['value']里面,如图:



    代码在服务器上运行效果如图:

    至此,Gmail API在AWS服务器上的部署完成。下一篇文章将会介绍如何使用Python轮询Gmail的收件箱,并在有新邮件的时候转发到国内邮箱。

    相关文章

      网友评论

        本文标题:使用AWS亚马逊云搭建Gmail转发服务(一)

        本文链接:https://www.haomeiwen.com/subject/xekztttx.html