oauth2 方式获取outlook邮箱收件箱(python)

1.在Azure 门户注册应用程序

  微软文档地址

  重定向的地址配置(微软地址):  https://login.microsoftonline.com/common/oauth2/nativeclient

注册应用地址

2.程序代码

#安装包以及需要的驱动
pip3 install playwrightplaywright install
import base64
import json
import logging
from io import BytesIOfrom playwright.sync_api import sync_playwright
import time
import urllib.parse
import requestsfrom pia.utils.cache import get_redis_value, set_redis_expire
from pia.utils.constants import OUTLOOK_CLIENT_ID, OUTLOOK_TENANT_ID, OUTLOOK_CLIENT_SECRET, OUTLOOK_REDIRECT_URI, \COS_OUTLOOK_DIR, OUTLOOK_TOP
from pia.utils.cos_upload import upload_stream_to_cos, check_exists
from pia.utils.reids_key import OUTLOOK_TOKENlog = logging.getLogger(__name__)#账号登录 官方文档 https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
def get_authorization_code(_user_name, _pass_word):with sync_playwright() as play_wright:browser = play_wright.chromium.launch(headless=True)context = browser.new_context(locale="zh-CN", accept_downloads=True)page = context.new_page()url = f"https://login.microsoftonline.com/{OUTLOOK_TENANT_ID}/oauth2/v2.0/authorize?client_id={OUTLOOK_CLIENT_ID}&response_type=code&redirect_uri={OUTLOOK_REDIRECT_URI}&response_mode=query&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read&state=12345"page.goto(url)page.click("[placeholder=\"电子邮件、电话或\\ Skype\"]")page.fill("[placeholder=\"电子邮件、电话或\\ Skype\"]", _user_name)with page.expect_navigation():page.click("text=下一步")page.click("[placeholder=\"密码\"]")page.fill("[placeholder=\"密码\"]", _pass_word)with page.expect_navigation():page.click("text=登录")page.click("text=是")time.sleep(3)query = dict(urllib.parse.parse_qsl(urllib.parse.urlsplit(page.url).query))authorization_code = query.get('code')context.close()browser.close()return authorization_codedef get_token(authorization_code):param = {'client_id': OUTLOOK_CLIENT_ID,'code': authorization_code,'redirect_uri': OUTLOOK_REDIRECT_URI,'grant_type': 'authorization_code','client_secret': OUTLOOK_CLIENT_SECRET}token_headers = {"Content-Type": "application/x-www-form-urlencoded"}token_url = f'https://login.microsoftonline.com/{OUTLOOK_TENANT_ID}/oauth2/v2.0/token'res = requests.post(url=token_url, headers=token_headers, data=param)access_token = json.loads(res.text).get('access_token')return f'Bearer {access_token}'# api官方文档 https://learn.microsoft.com/en-us/graph/api/mailfolder-list-messages?view=graph-rest-1.0
def get_inbox(authorization, str_start, str_end):condition = '?$filter = 'if str_start:condition += f'ReceivedDateTime ge {str_start} and 'condition += f'receivedDateTime lt {str_end}'# 获取收件箱里面的 邮件endpoint = f"https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messages{condition}&$top={OUTLOOK_TOP}"http_headers = {'Authorization': authorization,'Accept': 'application/json','Content-Type': 'application/json'}data = requests.get(endpoint, headers=http_headers, stream=False).json()return datadef get_email_attachments(authorization, email_id):# 获取收件箱里面的邮件附件endpoint = f"https://graph.microsoft.com/v1.0/me/messages/{email_id}/attachments"http_headers = {'Authorization': authorization,'Accept': 'application/json','Content-Type': 'application/json'}data = requests.get(endpoint, headers=http_headers, stream=False).json()return data#程序入口
def deal_user_email(_user_name, _pass_word, str_start, str_end) -> list:result = []redis_key = f'{OUTLOOK_TOKEN}:{_user_name}'# 缓存authorization = get_redis_value(redis_key)if authorization:passelse:authorization_code = get_authorization_code(_user_name, _pass_word)authorization = get_token(authorization_code)if authorization:set_redis_expire(redis_key, authorization, 60 * 60)if authorization:email = get_inbox(authorization, str_start, str_end)if email:email_values = email.get("value")if email_values:for value in email_values:# 邮件 idemail_id = value.get("id")# 是否存在附件 True/Falsehas_attachments = value.get("hasAttachments")value.update({"attachments": {}})if has_attachments and email_id:attachment_dict = upload_attachment_to_cos(authorization, email_id, _user_name)value.update({"attachments": attachment_dict})result.append(value)else:log.error(f"outlook user_name: {_user_name} Authorization Failed")return result'''
附件上传到cos
'''def upload_attachment_to_cos(authorization, email_id, _user_name):attachment_dict = {}attachments = get_email_attachments(authorization, email_id)if attachments:attachment_values = attachments.get("value")if attachment_values:for _value in attachment_values:# 附件 nameattachment_name = _value.get("name")# 附件 内容attachment_content = _value.get("contentBytes")# Step 1: 解码 Base64 字符串decoded_data = base64.b64decode(attachment_content)# Step 2: 创建一个 BytesIO 对象作为文件流file_stream = BytesIO(decoded_data)object_name = f'{COS_OUTLOOK_DIR}/{_user_name}/{email_id}/{attachment_name}'is_exists, url = check_exists(object_name)if not is_exists:url = upload_stream_to_cos(file_stream, object_name)attachment_dict.update({attachment_name: url})return attachment_dict
import traceback
from datetime import datetime, timedeltafrom django.core.management import BaseCommand
import logging
import uuidfrom django.db import transactionfrom pia.models import PiaOutLookTask, PiaOutLookData
from pia.utils.aes import decrypted
from pia.utils.outlook import deal_user_emaillogging = logging.getLogger('task')#任务的方式拉取
class Command(BaseCommand):def add_arguments(self, parser):parser.add_argument('trace_id', type=str)def handle(self, *args, **options):trace_id = options["trace_id"]if not trace_id:trace_id = str(uuid.uuid4())self.trace_id = trace_idself.writeLog('outlook email start')outlook_task = PiaOutLookTask.objects.values("id", "user_name", "pwd", "execution_time")for x in outlook_task:_id = x.get("id")user_name = x.get("user_name")self.writeLog(f'############## outlook email user_name:{user_name} start ##############')pwd = x.get("pwd")execution_time = x.get("execution_time")# 获取当前时间current_time = datetime.now()# 格式化为 YYYY-MM-DDend_time = current_time.strftime('%Y-%m-%dT%H:%M:%S')try:if user_name and pwd:_pwd = decrypted(pwd)result = deal_user_email(user_name, _pwd, f'{execution_time}Z', F'{end_time}Z')with transaction.atomic():PiaOutLookTask.objects.filter(id=_id).update(status=0, execution_time=end_time)outlook_data = PiaOutLookData.objects.filter(outlook_task_id=_id, start_time=execution_time,end_time=end_time)if outlook_data:outlook_data.update(content=result)else:PiaOutLookData.objects.create(outlook_task_id=_id, start_time=execution_time,end_time=end_time, content=result)self.writeLog(f'############## outlook email user_name:{user_name} end ##############')except Exception:PiaOutLookTask.objects.filter(id=_id).update(status=1, execution_time=end_time)self.writeLog(f'##############  outlook email user_name:{user_name} execution failed::::{traceback.format_exc()}')self.writeLog('outlook email end')def writeLog(self, msg: str):logging.info(f'[{self.trace_id}] {msg}')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/418546.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MAT:一款针对MSSQL服务器的安全检测与审计工具

关于MAT MAT是一款针对MSSQL服务器的安全检测与审计工具,该工具使用C#开发,可以帮助广大研究人员快速识别和发现MSSQL 服务器中的安全问题,并实现安全检测与审计目的。 功能介绍 1、执行自动检查并识别安全问题; 2、允许通过 Win…

暑期档总结:哪部国漫年番表现更优?

“暑期档”可能是所有档期中绵延时间最长的,作为该时间段主力的学生人群,在学业压力较小的假期中,需要更多娱乐方式来填充生活。除了电影之外,动画番剧越来越成为这一群体的不二选择,各个动画制作公司也会选择把精彩剧…

Datawhle X 李宏毅苹果书AI夏令营深度学习笔记之——卷积神经网络的前世今生

一、卷积神经网络简介 卷积神经网络(Convolutional Neural Network, CNN)是一种深度学习模型,尤其擅长处理图像和视频等高维度的数据。CNN 通过模仿人类视觉系统的工作方式,自动学习数据中的空间层次结构,使得它在计算…

GDB 查看汇编

查看汇编 x disassemble

24秋开学考

文件上传 上传一个.php的格式,上面说是非法的文件格式。 2.传了一个phpinfo.gif,说什么在目录里。 3.有两个页面一个labs1一个labs2 ,当在第一个页面上传1.jpg,在第二个页面上传1.jpg时,给了我们一个目录,在测试其他时…

Linux下的Makefile与进度条程序

目录 Linux下的Makefile与进度条程序 Makefile与make Makefile与make介绍 创建第一个Makefile并使用make Makefile文件基本格式介绍 Makefile依赖方法执行过程 Makefile通用写法 进度条程序 实现效果 前置知识 回车(\r)与换行(\n) 输出缓冲区 实现进度条 Linux下的…

15、Django Admin添加自定义字段功能

修改模型类HeroAdmin admin.register(Hero) class HeroAdmin(admin.ModelAdmin):change_list_template "entities/heroes_changelist.html"... # 此处原代码不动,只增加此前后代码def get_urls(self):urls super().get_urls()my_urls [path(immort…

溜狗牵绳行为检测-目标检测数据集(包括VOC格式、YOLO格式)

溜狗牵绳行为检测-目标检测数据集(包括VOC格式、YOLO格式) 数据集: 链接:https://pan.baidu.com/s/1CwLEAKcdlh9hbcBNh_Awdw?pwdiu6b 提取码:iu6b数据集信息介绍: 共有 1980 张图像和一一对应的标注文件…

7.统一网关-Gateway

文章目录 1.统一网关介绍2.网关开发3.predicate4.Route Predicate Factories(路由断言工厂)4.1Path 路由断言工厂4.2.Method 路由断言工厂4.3 Header 路由断言工厂4.4 Query 路由断言工厂4.5 Host 路由断言工厂4.6 After 路由断言工厂4.7 Before 路由断言工厂4.8 Between 路由断…

超声波测距模块HC-SR04(基于STM32F103C8T6HAL库)

超声波测距模块参考资料 1.电路连接及引脚配置 触发信号PA3只需要输出10us的高电平,所以直接设置成 普通的GPIO端口即可;回响信号使用外部中断,上升沿信号产生外部中断,打开定时器,下降沿再产生一次中断,读…

国内外大模型汇总(包括科大星火、文心一言、通义千问、智普清言、华为大模型)

国内外大模型汇总 1. 科大讯飞星火认知大模型 主要特点: 多语言能力:以中文为核心,同时支持多语言处理,能够进行跨语种的语言理解和生成。 广泛的任务能力:具备内容生成、语言理解、知识问答、推理、数学计算、代码…

强化网络安全:通过802.1X协议保障远程接入设备安全认证

随着远程办公和移动设备的普及,企业网络面临着前所未有的安全挑战。为了确保网络的安全性,同时提供无缝的用户体验,我们的 ASP 身份认证平台引入了先进的 802.1X 认证协议,确保只有经过认证的设备才能接入您的网络。本文档将详细介…

Kafka【六】Linux下安装Kafka(Zookeeper)集群

Kafka从早期的消息传输系统转型为开源分布式事件流处理平台系统,所以很多核心组件,核心操作都是基于分布式多节点的。本文这里采用三台虚拟机模拟真实物理主机搭建Zookeeper集群和kafka集群。 VMware可以使用户在一台计算机上同时运行多个操作系统&…

使用AI写WebSocket知识是一种怎么样的体验?

一、WebSocket基础知识 1. WebSocket概念 1.1 为什么会出现WebSocket 一般的Http请求我们只有主动去请求接口,才能获取到服务器的数据。例如前后端分离的开发场景,自嘲为切图仔的前端大佬找你要一个配置信息的接口,我们后端开发三下两下开…

Windows下的Redis启动报错Redis service failed to start

报错原因:Redis服务没有找到log文件 解决方案: 1、在Redis目录下打开redis.windows-service.conf文件 2、找到logfile存放目录,一般默认为Logs/redis_log.txt 3、在Redis目录创建Logs文件夹,在Logs文件夹下创建redis_log.txt文件…

机器学习数学公式推导之降维

文章目录 降维线性降维-主成分分析 PCA损失函数SVD 与 PCoASVD 的基本形式SVD 的计算p-PCA 小结 P22 (系列五) 降维1-背景 本文参考 B站UP: shuhuai008 🌹🌹 降维 我们知道,解决过拟合的问题除了正则化和添加数据之外,降维就是最…

自己部门日均1000+告警?如何减少90%无效告警?

目录标题 一、告警的类别1.技术告警1.1基础设施告警1.2基本服务告警 2.业务告警3.监控大盘告警 二、为何需要告警治理?三、治理迫在眉睫1.1告警治理策略1.2核心监控告警点1.3避免告警反模式1.4告警规约制定1.5自动化处理 一、告警的类别 一般的告警分为以下几点&am…

连续信号的matlab表示

复习信号与系统以及matlab 在matlab中连续信号使用较小的采样间隔来表四 1.单位阶跃信号 阶跃信号:一个理想的单位阶跃信号在时间 t 0 之前值为0,在 t 0 及之后值突然变为常数 A(通常取 A 1) %matlab表示连续信号,是让信号的采样间隔很小…

数据类型转换

1. 基本数据类型转换 1.1 自动类型转换 1.2 注意 1.3 强制类型转换 2. String 与基本数据类型的转换 2.1 基本数据类型转 String public class StringConvert{public static void main(String []args){//基本数据类型-->Stringbyte a1;short b10;int c100;long d1000;…

什么是网络安全?

目录 网络安全定义 网络安全如何运作? 1.人 2.基础设施 3.漏洞 4.技术 网络安全的演变 未来十年的网络安全将会是什么样子? 网络安全为何对企业如此重要? 网络安全的类型 1.网络安全 2.应用程序安全 3.信息安全 4.运营安全 5.灾…