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

author:青南

date: 2014-12-30 15:41:35

categories: Python

tags: [Gmail,AWS,API,Flask]

故事背景

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转发服务(一)的更多相关文章

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

    title: 使用AWS亚马逊云搭建Gmail转发服务(三) author:青南 date: 2015-01-02 15:42:22 categories: [Python] tags: [log,G ...

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

    title: 使用AWS亚马逊云搭建Gmail转发服务(二) author:青南 date: 2014-12-31 14:44:27 categories: [Python] tags: [Pytho ...

  3. [转]Amazon AWS亚马逊云服务免费一年VPS主机成功申请和使用方法

    今天部落将再次为大家介绍如何成功申请到来自亚马逊的Amazon AWS免费一年的VPS主机服务.亚马逊公司这个就不用介绍了,是美国最大的一家网络电子商务公司,亚马逊弹性计算云Amazon EC2更是鼎 ...

  4. 当 EDA 遇到 Serverless,亚马逊云科技出招了

    近二三十年来,软件开发领域毫无疑问是发展最为迅速的行业之一. 在上个世纪九十年代,世界上市值最高的公司大多是资源类或者重工业类的公司,例如埃克森美孚或者通用汽车,而现在市值最高的公司中,纯粹的软件公司 ...

  5. AWS系列之一 亚马逊云服务概述

    云计算经过这几年的发展,已经不再是是一个高大上的名词,而是已经应用到寻常百姓家的技术.每天如果你和互联网打交道,那么或多或少都会和云扯上关系.gmail.github.各种网盘.GAE.heroku等 ...

  6. 亚马逊云服务器AWS安装CentOS

    亚马逊云服务器默认创建的实例,在停止之后再启动的情况下,IP会发生改变.所以我们最好先创建一个弹性IP,即EIP,不过我也不清楚这个费用. 1.按如图操作创建一个弹性IP,弹性IP创建之后可以随便绑定 ...

  7. 【AWS】亚马逊云常用服务解释

    新公司使用的是亚马逊服务,刚开始的时候,对很多名词不太明白,总结了一下如下 1,EC2 这个是亚马逊的一种服务器服务,可以理解为跟vmware差不多,EC2为虚拟机提供载体,EC2上跑虚拟机服务器. ...

  8. 使用亚马逊云服务器EC2做深度学习(三)配置TensorFlow

    这是<使用亚马逊云服务器EC2做深度学习>系列的第三篇文章. (一)申请竞价实例  (二)配置Jupyter Notebook服务器  (三)配置TensorFlow  (四)配置好的系统 ...

  9. 亚马逊云架设WordPress博客

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 这篇文章介绍如何在亚马逊云架设WordPress博客.最强的云,加上最流行的建站工 ...

随机推荐

  1. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

  2. ASP.NET Core 1.1 简介

    ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...

  3. Security Policy:行级安全(Row-Level Security)

    行级安全RLS(Row-Level Security)是在数据行级别上控制用户的访问,控制用户只能访问数据库表的特定数据行.断言是逻辑表达式,在SQL Server 2016中,RLS是基于安全断言( ...

  4. CENTOS 6.5 平台离线编译安装 PHP5.6.6

    一.下载php源码包 http://cn2.php.net/get/php-5.6.6.tar.gz/from/this/mirror 二.编译 编译之前可能会缺少一些必要的依赖包,加载一个本地yum ...

  5. VisualStudio2013 如何打开之前版本开发的(.vdproj )安装项目

    当你的项目使用早于 visualstudio2013 的版本开发并且使用 Visual Studio Installer 制作安装项目时,在升级至 VS2013 后会发现新安装项目无法打开, VS20 ...

  6. 23种设计模式--责任链模式-Chain of Responsibility Pattern

    一.责任链模式的介绍 责任链模式用简单点的话来说,将责任一步一步传下去,这就是责任,想到这个我们可以相当击鼓传花,这个是为了方便记忆,另外就是我们在项目中经常用到的审批流程等这一类的场景时我们就可以考 ...

  7. RSA算法

    RSA.h #ifndef _RSA_H #define _RSA_H #include<stdio.h> #include<iostream> #include<mat ...

  8. Docker与CI持续集成/CD

    背景        Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制 ...

  9. Javascript中的valueOf与toString

    基本上,javascript中所有数据类型都拥有valueOf和toString这两个方法,null除外.它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下. t ...

  10. Angular2 Hello World 之 RC6

    angular2还没有发布正式版,确实有点不靠谱,变化太频繁,之前写的demo直接将js升级到最新版之后发现就不能用了……所以现在在写一篇demo——基于RC6.参考:http://web3.code ...