十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Frappe SMS Log DocType 深度解析:基于 SMS Center 的短信发送日志记录机制

Frappe SMS Log DocType 深度解析:基于 SMS Center 的短信发送日志记录机制 Frappe SMS Log DocType 深度解析基于 SMS Center 的短信发送日志记录机制【免费下载链接】frappeLow code web framework for real world applications, in Python and Javascript项目地址: https://gitcode.com/GitHub_Trending/fr/frappe导读SMS Log是 Frappe 低代码框架Core 模块中专门用于记录短信发送情况的 DocType其官方定位正如 frappe/core/doctype/sms_log/README.md 所概括Log of SMS sent via SMS Center记录通过 SMS Center 发送的短信日志。本文将以该 DocType 为核心结合其 JSON 定义、Python 控制器与 frappe/core/doctype/sms_settings/sms_settings.py 中的真实调用链完整讲解 SMS Log 的字段设计、自动命名规则、权限模型以及它如何在短信网关调用成功后自动落库。读完本文你将掌握 SMS Log 的数据结构、写入时机与查询方式并能据此在自己的 Frappe 应用中正确使用或扩展短信日志能力。一、SMS Log 是什么定位与作用SMS Log 归属于 Frappe 的 Core 模块路径为frappe/core/doctype/sms_log/目录内包含完整的 DocType 四件套sms_log.json —— DocType 结构定义字段、权限、命名规则等元数据sms_log.py —— Python 控制器类SMSLogsms_log.js —— 前端 Form 脚本test_sms_log.py —— 单元测试占位文件它解决的问题非常具体当系统通过外部短信网关SMS Center批量发送短信时需要留痕。SMS Log 将请求发送的号码与消息、实际发送成功的号码、发送时间等关键信息固化下来供管理员审计、排障与统计。它不是主动发起短信的工具而是短信发送链路末端的留痕者。二、字段设计详解一张表看清数据结构根据 sms_log.json 中的fields定义SMS Log 共包含 6 个业务字段全部为read_only: 1只读意味着日志一旦生成便不可在界面上随意修改保证了审计记录的完整性fieldnamefieldtypelabel界面显示说明sender_nameDataSender Name发送方名称字符串sent_onDateSent On发送日期类型为日期不含时间messageSmall TextMessage短信正文小文本类型no_of_requested_smsIntNo of Requested SMS请求发送的短信条数requested_numbersCodeRequested Numbers请求发送的号码清单Code 类型、每行一个no_of_sent_smsIntNo of Sent SMS实际发送成功的条数sent_toCodeSent To实际发送成功的号码清单每行一个从field_order可以还原出表单布局第一行为sender_name与sent_on左右分栏column_break0宽度 50%接着是整行显示的messagesec_break1Section Break之后是第二组左右分栏——左侧no_of_requested_sms与requested_numbers右侧no_of_sent_sms与sent_to。这里值得注意一个设计巧思请求的与已发送的被拆成两套字段。requested_numbers/no_of_requested_sms记录的是发起方提交的完整目标清单而sent_to/no_of_sent_sms记录的是网关实际返回 2xx 成功的子集。这两组数据的差值即发送失败的部分为后续重发或排查提供了直接依据。DocType 层面还有几个值得留意的元配置autoname: SYS-SMS-.#####—— 使用 Frappe 的自动命名系列series规则新记录的主键形如SYS-SMS-00001天然可读且便于检索engine: InnoDB、sort_field: creation、sort_order: DESC—— 列表默认按创建时间倒序最新日志排在最前track_changes: 1—— 开启变更追踪icon: fa fa-mobile-phone—— 列表/工作区中的图标标识。三、Python 控制器与类型注解SMS Log 的 Python 控制器 非常简单类SMSLog继承自frappe.model.document.Document声明了_DOCTYPE_NAME SMS Log逻辑体为空pass。类内剩余部分是 Frappe 自动生成的类型注解块# begin: auto-generated types借助frappe.types.DF为每个字段标注了 Python 类型例如message: DF.SmallText | Noneno_of_requested_sms: DF.Intrequested_numbers: DF.Code | Nonesender_name: DF.Data | Nonesent_on: DF.Date | Nonesent_to: DF.Code | None这说明 SMS Log 是一个纯数据载体型 DocType它自身不含任何业务逻辑全部写入逻辑由调用方SMS Settings 模块负责。这种薄控制器 厚调用方的设计让日志类 DocType 保持稳定、易于被其他模块复用。前端脚本 sms_log.js 同样精简仅在refresh事件中留了空钩子进一步印证其展示型定位——它不需要复杂的交互逻辑界面只负责呈现审计数据。四、权限模型谁可以看短信日志日志涉及用户手机号与短信内容属于敏感数据。因此 sms_log.json 的permissions数组将访问权严格限定在单一角色角色roleSystem Manager系统管理员权限位read、print、report、email均为 1即允许查看、打印、纳入报表、通过邮件发送记录也就是说普通用户包括能发短信的受控角色默认无法读取 SMS Log。这与 sms_settings.py 中的权限函数check_sms_permission形成发送端松、审计端紧的配合发送短信时System Manager直接放行其他角色需在 SMS Settings 的allowed_roles表中被显式授权否则抛出frappe.PermissionError而发送产生的日志则只有系统管理员能查看。五、源码级原理日志是如何被写入的SMS Log 本身不写自己写入逻辑位于 frappe/core/doctype/sms_settings/sms_settings.py 的create_sms_log函数中。完整调用链如下入口send_smsfrappe.whitelist()先调用check_sms_permission()校验权限再转交_send_smsHook 优先级_send_sms先检查frappe.get_hooks(send_sms)若应用注册了send_smshook则调用 hook 指向的自定义实现便于集成第三方短信服务商参数归一化receiver_list若是 JSON 字符串则反序列化为列表再经validate_receiver_nos清洗——去除号码中的空格、-、(、)等无效字符空列表直接throw报错网关路由读取 SMS Settings 单例中的sms_gateway_url为空则提示Please Update SMS Settings否则走send_via_gateway逐号发送与统计send_via_gateway按receiver_parameter逐个号码构造请求参数并调用send_request只要网关返回状态码落在200 status 300区间就把该号码追加进success_list落库只要success_list非空就调用create_sms_log(args, success_list)生成一条 SMS Log。create_sms_log的实现与字段一一对应def create_sms_log(args, sent_to): # SMS Log doctype was removed; skip silently if it isnt available # (apps that still ship it will continue to log). if not frappe.db.exists(DocType, SMS Log): return sl frappe.new_doc(SMS Log) sl.sent_on nowdate() sl.message args[message].decode(utf-8) sl.no_of_requested_sms len(args[receiver_list]) sl.requested_numbers \n.join(args[receiver_list]) sl.no_of_sent_sms len(sent_to) sl.sent_to \n.join(sent_to) sl.flags.ignore_permissions True sl.save()从这段代码可以读出几个实现事实sent_on取nowdate()当天日期与字段的Date类型一致只精确到日message先经frappe.safe_decode解码再编码为 UTF-8在create_sms_log中再decode(utf-8)还原为文本确保中文等多字节内容不损坏多号码以换行符\n拼接分别存入requested_numbers与sent_to因此界面上的 Code 字段天然按行展示每个号码no_of_requested_sms取请求列表长度no_of_sent_sms取成功列表长度两者可能不相等差值即失败数量sl.flags.ignore_permissions True绕过权限校验直接保存——因为写日志的动作发生在服务端内部流程不应因当前调用者权限不足而中断存在性防御frappe.db.exists(DocType, SMS Log)先检查 DocType 是否存在不存在则静默跳过。源码注释明确指出 SMS Log 曾被从某些发行版中移除仍内置该 DocType 的应用会继续正常记录日志——这保证了send_via_gateway的兼容性。此外从代码观察可以推断当前版本的create_sms_log并未给sender_name字段赋值该字段保留在 DocType 定义中供扩展或历史数据使用调用send_sms时传入的sender_name参数目前仅用于 hook 自定义实现。若需要写入发送方名称可在应用层通过 hook 或子类化补充。六、测试现状与二次开发指引test_sms_log.py 目前仅定义了继承unittest.TestCase的空测试类TestSMSLog没有任何测试用例。如果你想在自己的 Frappe 环境中为 SMS Log 补充自动化测试可以围绕create_sms_log的以下行为编写断言传入args与sent_to后能创建一条sent_on为当天的记录no_of_requested_sms等于请求列表长度、no_of_sent_sms等于成功列表长度多号码场景下requested_numbers/sent_to中的换行拼接符合预期在不存在SMS LogDocType 的环境中调用不会抛异常静默跳过。二次开发时还可以利用以下既有能力查询审计通过 Desk 的 DocType 列表页按creation倒序查看或使用frappe.db.get_all(SMS Log, ...)在代码中检索System Manager角色还拥有report权限可将其纳入自定义报表发送接入如果接入的是自有网关优先通过send_smshook 机制实现复用其权限校验与号码清洗逻辑并在自定义实现中决定是否继续调用create_sms_log落库扩展字段如需记录发送方的用户、关联单据或网关响应码可在 DocType 上增加字段并在 hook 实现中同步写入注意保持read_only的审计属性。七、小结SMS Log 是一个小而完整的审计型 DocType六 个只读字段精确刻画了一次短信发送的请求面与结果面SYS-SMS-.#####命名让记录天然可读System Manager独占权限保障了数据安全而 sms_settings.py 中的create_sms_log则展示了 Frappe 中服务端流程自动写日志的标准范式——ignore_permissions绕过、nowdate()记时、换行拼接号码清单每一项都是可以直接复用的最佳实践。理解了这个模块你就掌握了在 Frappe 中设计同类审计/日志 DocType 的完整思路。【免费下载链接】frappeLow code web framework for real world applications, in Python and Javascript项目地址: https://gitcode.com/GitHub_Trending/fr/frappe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表