Amazon Pinpoint SDK for Python(Boto3)代码示例:从发送邮件、SMS 到模板消息的完整实战指南
示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载本篇指南以 python/example_code/pinpoint/README.md 为核心骨架系统讲解如何使用 AWS SDK for PythonBoto3调用 Amazon Pinpoint 服务通过实际源码覆盖四种典型消息发送场景API 发送简单邮件、API 发送 SMS、SMTP 接口发送邮件、以及基于消息模板的邮件/SMS 发送。读完本文你将掌握send_messages请求结构的完整写法、各类参数的取值与注意事项以及如何在本地用 pytest 对 Pinpoint 代码做单元测试。概述Amazon Pinpoint 与 Boto3Amazon Pinpoint 帮助你通过电子邮件、短信、语音消息和推送通知与客户互动。Amazon Pinpoint 是 AWS 提供的多渠道客户互动服务可用于营销推广、事务性通知等场景。在 aws-doc-sdk-examples 仓库的 python/example_code/pinpoint 目录下提供了使用 AWS SDK for PythonBoto3操作 Amazon Pinpoint 的完整可运行示例。所有示例均围绕 Pinpoint 的核心 APIsend_messages展开覆盖邮件与 SMS 两种渠道并区分“直接发送”与“模板发送”两种模式。从源码结构看该目录下的示例文件遵循“独立单动作”的组织方式——每个文件都包含一个main()入口和可复用的发送函数既可以直接从命令行运行演示也可以将发送函数导入到自己的业务代码中复用文件发送场景pinpoint_send_email_message_api.py通过 Pinpoint API 发送含 HTML 与纯文本双版本内容的邮件pinpoint_send_sms_message_api.py通过 Pinpoint API 发送 SMS 短信pinpoint_send_email_smtp.py通过 Amazon Pinpoint SMTP 服务器发送邮件pinpoint_send_templated_email_message.py使用预定义邮件模板发送邮件pinpoint_send_templated_sms_message.py使用预定义 SMS 模板发送短信⚠ 重要提醒成本与权限运行本目录代码前需要了解以下约束运行这些代码可能会在你的 AWS 账户中产生费用。请参考 AWS Pricing 与 Free Tier 了解定价。运行测试同样可能产生费用集成测试会真实调用 AWS 服务。建议遵循最低权限原则least privilege至少只授予完成任务所需的最小权限集。这些代码并未在所有 AWS 区域完成测试请确认你的目标区域支持 Amazon Pinpoint。在实际生产环境中还应特别注意发件地址与收件地址的验证要求详见下文各示例的参数说明。环境准备前置条件与依赖安装前置条件按照 python/README.md 中的说明你需要拥有 AWS 账户并按 AWS Tools and SDKs Shared Configuration and Credentials Reference Guide 配置默认凭证与默认区域通常通过~/.aws/credentials与~/.aws/config完成。Python 3.6 或更高版本。安装依赖在虚拟环境中安装示例所需的依赖包python -m pip install -r requirements.txt本目录的 requirements.txt 内容如下boto31.26.79 pytest7.2.1其中boto31.26.79提供了pinpoint服务的客户端pytest7.2.1用于运行 test 目录下的单元测试。推荐的标准操作流程是先进入示例目录创建并激活虚拟环境再安装依赖python -m venv .venv source .venv/bin/activate # Linux、macOS 或 UnixWindows 下使用 .venv\Scripts\activate python -m pip install -r requirements.txt单动作示例调用单个服务函数原 README 将示例归类为Single actions单动作即展示如何调用单个服务函数的代码片段核心入口是 SendMessages —— pinpoint_send_email_message_api.py#L11。实际上目录内 5 个示例文件都围绕同一个服务调用send_messages展开区别仅在于MessageRequest的载荷结构。下面逐一深入讲解。1. 通过 API 发送简单邮件对应文件pinpoint_send_email_message_api.py核心函数send_email_message的签名与参数说明如下def send_email_message( pinpoint_client, app_id, sender, to_addresses, char_set, subject, html_message, text_message, ):各参数含义pinpoint_clientBoto3 Pinpoint 客户端由boto3.client(pinpoint)创建。app_id发送消息时使用的 Amazon Pinpoint 项目 ID。sender发件人地址From。该地址必须在发送邮件的 AWS 区域中完成 Pinpoint 验证。to_addresses收件人地址列表To。如果你的 Pinpoint 账户仍处于沙箱sandbox状态这些地址必须经过验证。char_set主题行和邮件正文使用的字符编码示例中使用UTF-8。subject邮件主题。html_message面向支持 HTML 的邮件客户端的邮件正文。text_message面向不支持 HTML 的邮件客户端的纯文本正文。返回值一个 dict键为收件人地址、值为对应的 Message ID。核心的 API 请求结构response pinpoint_client.send_messages( ApplicationIdapp_id, MessageRequest{ Addresses: { to_address: {ChannelType: EMAIL} for to_address in to_addresses }, MessageConfiguration: { EmailMessage: { FromAddress: sender, SimpleEmail: { Subject: {Charset: char_set, Data: subject}, HtmlPart: {Charset: char_set, Data: html_message}, TextPart: {Charset: char_set, Data: text_message}, }, } }, }, )关键设计点Addresses中每个收件地址通过ChannelType: EMAIL显式指定消息渠道使同一个MessageRequest可以混合不同渠道的收件人。SimpleEmail结构同时提供HtmlPart与TextPart邮件客户端会自动选择可渲染的版本从而兼顾 HTML 与纯文本用户。字符编码通过Charset单独指定可以灵活适配多语言内容。错误处理与返回解析try: response pinpoint_client.send_messages(...) except ClientError: logger.exception(Couldnt send email.) raise else: return { to_address: message[MessageId] for to_address, message in response[MessageResponse][Result].items() }发送失败时抛出botocore.exceptions.ClientError成功时从MessageResponse.Result中逐地址提取MessageId方便后续做送达追踪。2. 通过 API 发送 SMS 短信对应文件pinpoint_send_sms_message_api.py核心函数签名def send_sms_message( pinpoint_client, app_id, origination_number, destination_number, message, message_type, ):参数要点app_idPinpoint 项目 ID该项目的 SMS 渠道必须已启用。destination_number收件人手机号必须使用 E.164 格式例如14255550142。origination_number发件手机号必须与你的 Pinpoint 账户关联且为 E.164 格式。messageSMS 消息正文内容。message_type消息类型。发送时效性敏感内容指定TRANSACTIONAL营销推广内容指定PROMOTIONAL——该字段直接决定 Pinpoint 对短信的优先级路由与计费模式。返回值消息 ID字符串。请求结构response pinpoint_client.send_messages( ApplicationIdapp_id, MessageRequest{ Addresses: {destination_number: {ChannelType: SMS}}, MessageConfiguration: { SMSMessage: { Body: message, MessageType: message_type, OriginationNumber: origination_number, } }, }, )main()中的示例参数为origination_number 12065550199、destination_number 14255550142、message_type TRANSACTIONAL。返回时通过response[MessageResponse][Result][destination_number][MessageId]取得消息 ID。3. 通过 SMTP 接口发送邮件对应文件pinpoint_send_email_smtp.py与 API 方式不同SMTP 方式不依赖 Boto3 客户端而是使用 Python 标准库smtplib与email.mime直接连接 Amazon Pinpoint SMTP 服务器。核心函数def send_smtp_message( smtp_server, smtp_username, smtp_password, sender, to_address, cc_address, subject, html_message, text_message, ):内部实现要点构造 MIME 消息使用MIMEMultipart(alternative)作为容器分别用MIMEText(html_message, html)和MIMEText(text_message, plain)附加 HTML 与纯文本两个版本建立安全连接依次调用smtp_server.ehlo()→starttls()→ehlo()smtplib文档建议在starttls()前后各调用一次ehlo()→login(smtp_username, smtp_password)发送消息smtp_server.sendmail(sender, to_address, msg.as_string())。注释中还提示可用set_debuglevel(1)将 SMTP 服务器响应输出到 stdout 便于排错。连接参数在main()中定义host email-smtp.us-west-2.amazonaws.com如果使用的区域不是美国西部俄勒冈us-west-2需要替换为该区域对应的 Amazon Pinpoint SMTP 端点。port 587标准 SMTP 提交端口。凭证smtp_username AKIAIOSFODNN7EXAMPLE示例中的 IAM 访问密钥占位值需要替换为你的 Pinpoint SMTP 用户名smtp_password从环境变量SMTP_PASSWORD中读取避免把凭证硬编码进代码smtp_password environ[SMTP_PASSWORD]使用with smtplib.SMTP(host, port) as smtp_server:确保会话结束后连接自动关闭。4. 使用模板发送邮件对应文件pinpoint_send_templated_email_message.py模板发送将邮件内容的管理从代码中剥离出来——正文、主题等由 Pinpoint 中预先创建的模板维护代码只需引用模板名称与版本。核心函数def send_templated_email_message( pinpoint_client, project_id, sender, to_addresses, template_name, template_version ):请求结构的关键差异在于增加了TemplateConfiguration并且EmailMessage中不再内联SimpleEmail内容response pinpoint_client.send_messages( ApplicationIdproject_id, MessageRequest{ Addresses: { to_address: {ChannelType: EMAIL} for to_address in to_addresses }, MessageConfiguration: {EmailMessage: {FromAddress: sender}}, TemplateConfiguration: { EmailTemplate: { Name: template_name, Version: template_version, } }, }, )template_name指定使用的邮件模板名称template_version指定模板版本号main()中示例为My_Email_Template与1。模板机制便于在 Pinpoint 控制台统一维护文案并通过版本号实现灰度升级。5. 使用模板发送 SMS对应文件pinpoint_send_templated_sms_message.pydef send_templated_sms_message( pinpoint_client, project_id, destination_number, message_type, origination_number, template_name, template_version, ):请求结构将模板配置挂载到SMSTemplate键下SMSMessage中同样不再内联Bodyresponse pinpoint_client.send_messages( ApplicationIdproject_id, MessageRequest{ Addresses: {destination_number: {ChannelType: SMS}}, MessageConfiguration: { SMSMessage: { MessageType: message_type, OriginationNumber: origination_number, } }, TemplateConfiguration: { SMSTemplate: {Name: template_name, Version: template_version} }, }, )值得注意的是该文件的main()在创建客户端时显式指定了区域boto3.client(pinpoint, region_nameregion)示例region us-east-1与其余文件依赖默认区域配置的方式形成对照——当默认区域与 Pinpoint 项目所在区域不一致时应显式传入region_name。运行示例原 README 的指令说明如下每个文件都可以在命令提示符下单独运行。例如要发送一封邮件在命令提示符下运行python pinpoint_send_email_message_api.py同理其余 4 个文件均可按相同方式独立执行python pinpoint_send_sms_message_api.py python pinpoint_send_email_smtp.py python pinpoint_send_templated_email_message.py python pinpoint_send_templated_sms_message.py运行前请务必将代码中的占位值替换为真实参数app_id/project_id替换为你的 Pinpoint 项目 ID示例值形如ce796be37f32f178af652b26eexamplesender替换为已完成验证的发件地址to_address/destination_number替换为已验证的收件地址或 E.164 格式手机号origination_number替换为与账户关联的发件号码SMTP 方式还需设置SMTP_PASSWORD环境变量。每个文件运行成功后会打印类似Message sent! Message IDs: {...}或Email sent!的输出。需要更多参数说明时可参考各文件的main()函数与函数 docstring。测试单元测试与集成测试原 README 指出运行测试的通用说明参见 python/README.md#Tests并提醒运行测试可能产生 AWS 费用。本目录的测试代码位于 python/example_code/pinpoint/testconftest.py加载公共测试夹具其中sys.path.append(../..)使测试可以导入python/test_tools下的工具模块。test_pinpoint.py覆盖 5 个示例文件的单元测试。单元测试botocore Stubber 机制单元测试使用 botocore Stubber 对服务调用进行桩响应stub运行时不向 AWS 发送真实请求返回模拟响应因此不会产生费用。测试借助make_stubber夹具与 python/test_tools/pinpoint_stubber.py 中的PinpointStubber类协同工作。以test_send_email_message为例它通过pytest.mark.parametrize(error_code, [None, TestException])同时验证成功路径与异常路径pinpoint_stubber.stub_send_email_messages( app_id, sender, [to_address], char_set, subject, html_message, text_message, [message_id], error_codeerror_code, )成功分支error_code is None断言返回的消息 ID 与桩值一致失败分支error_code TestException断言调用抛出ClientError且exc_info.value.response[Error][Code]与错误码匹配。PinpointStubber中对应实现了 4 个桩函数其expected_params与示例代码中的请求结构严格一一对应例如 stub_send_email_messages 与 stub_send_sms_message 分别校验了 EMAIL/SMS 的MessageRequest载荷与TemplateConfiguration结构。这从侧面印证了示例代码中请求参数的真实性——测试期望的参数与发送代码实际构造的参数必须完全一致否则桩会抛出参数不匹配错误。SMTP 示例的测试test_send_smtp_message则使用mock.MagicMock()模拟 SMTP 会话断言login使用正确的用户名/密码、sendmail以(sender, to_address, 消息内容)被调用。运行单元测试排除集成标记不产生费用python -m pytest -m not integ集成测试真实调用 AWS集成测试会向 AWS 发起真实请求、创建并销毁账户中的资源可能产生费用请谨慎运行python -m pytest -m integ更多资源Amazon Pinpoint 开发者指南Amazon Pinpoint API 参考SDK for Python (Boto3) Amazon Pinpoint 参考Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.SPDX-License-Identifier: Apache-2.0赞分享示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载相关推荐使用 PythonBoto3调用 Amazon Pinpoint SMS and Voice 发送语音消息从源码到实战使用 PythonBoto3调用 Amazon Pinpoint SMS and Voice 发送语音消息从源码到实战 导读 本文基于 aws doc s示例工程教程后端使用 AWS SDK for JavaScript v2 调用 Amazon Pinpoint SMS and Voice API 发送语音消息使用 AWS SDK for JavaScript v2 调用 Amazon Pinpoint SMS and Voice API 发送语音消息 Amazon示例工程教程后端使用 AWS SDK for PythonBoto3操作 Amazon Aurora完整示例与实战指南使用 AWS SDK for PythonBoto3操作 Amazon Aurora完整示例与实战指南 本指南以 python/example_code/示例工程教程后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

开店选址调研:用地图 API 做竞对密度盘点

开店选址调研:用地图 API 做竞对密度盘点

开店选址调研:用地图 API 做竞对密度盘点 开奶茶店、咖啡店、健身房之前,谁都想知道一个问题:这条街上已经有多少家同行了?传统做法是踩点、数铺、问中介,一天能看两条街。用地图 API 可以一晚扫完半个城区,而且结论是可复算的——同一个坐标、同一个缩放级别,下个月再跑一遍…

2026/9/30 0:39:46 阅读更多 →
工业互联网协议 Goose 协议实战:从 SCD/CID 到组播配置的 TaoToken 接入指南

工业互联网协议 Goose 协议实战:从 SCD/CID 到组播配置的 TaoToken 接入指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 4:28:33 阅读更多 →
【Claude Code】实践:让 LLM 输出 HTML 而非 Markdown 的配置骨架——从 settings.json 到 CC Switch 的落地路径

【Claude Code】实践:让 LLM 输出 HTML 而非 Markdown 的配置骨架——从 settings.json 到 CC Switch 的落地路径

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 13:38:25 阅读更多 →

最新新闻

5个1280比特大状态置换算法的设计与分析

5个1280比特大状态置换算法的设计与分析

5个1280比特大状态置换算法的设计与分析以下是5个风格迥异、完全独创的1280比特(20个64-bit字)大状态置换设计方案。每个方案都避开了Keccak、Xoodoo、Gimli等标准套路,分别从拓扑流体、遗传剪接、声学共振、四元数几何、分形统计五个截然不同…

2026/10/1 2:43:04 阅读更多 →
找代码的第二种方式:cocoindex-code的ccc grep AST结构化搜索完全教程

找代码的第二种方式:cocoindex-code的ccc grep AST结构化搜索完全教程

找代码的第二种方式:cocoindex-code的ccc grep AST结构化搜索完全教程 【免费下载链接】cocoindex-code A super light-weight embedded code search engine CLI (AST based) that just works - improves speed and efficiency for coding agent 🌟 Star…

2026/10/1 2:43:04 阅读更多 →
市政许可公开情报如何被利用?解析精准钓鱼攻击机理与防御体系

市政许可公开情报如何被利用?解析精准钓鱼攻击机理与防御体系

1. 项目源起:为什么盯上市政许可这块“公开情报”做安全这些年,我一直有个体会:真正难防的攻击,往往不是用了多高级的漏洞,而是攻击者对目标了解得实在太深。去年我们团队做了一次针对市政建设相关企业的钓鱼演练&…

2026/10/1 2:43:04 阅读更多 →
一个监听器服务多个大模型:Lucebox模型负载均衡与多GPU部署实战

一个监听器服务多个大模型:Lucebox模型负载均衡与多GPU部署实战

一个监听器服务多个大模型:Lucebox模型负载均衡与多GPU部署实战 【免费下载链接】lucebox LLM speculative inference server for heterogeneous hardware & consumer GPUs 项目地址: https://gitcode.com/gh_mirrors/lu/lucebox Lucebox 是一个面向消费…

2026/10/1 2:43:04 阅读更多 →
TLS密码套件解析:ECDHE、RSA、AES-GCM与SHA256原理实战

TLS密码套件解析:ECDHE、RSA、AES-GCM与SHA256原理实战

1. 这串字符不是密码,而是TLS握手时的“加密契约”你第一次在Wireshark里抓包看到TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256这一长串字母数字组合时,大概率会下意识把它当成某种密钥、证书或错误代码——我刚接触TLS协议时也这么想。直到某次线上服务突然报…

2026/10/1 2:43:04 阅读更多 →
Zhzznengti《智能体》词条汉语拼音字母标调拼写实测案例

Zhzznengti《智能体》词条汉语拼音字母标调拼写实测案例

此文基于这项规则:汉语拼音字母标调规则 Zhzznengti Zhzznengti (agent) shzhh nenggou ganzh huanljngr bng caequh xngdon y shlxan tedng muzbiao d dailix ti. Tap key s ruanjanc, yngrjanc huo yi g xirtonx, jusbeir ziczhuxing, shsdyingxing h jiohuz ne…

2026/10/1 2:42:03 阅读更多 →

日新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →