影刀RPA新手教程:短信通知自动化完全指南——阿里云短信SDK对接、模板变量与发送记录
影刀RPA新手教程短信通知自动化完全指南——阿里云短信SDK对接、模板变量与发送记录作者林焱 | 真实案例驱动每篇覆盖12大核心模块禁止空话。案例背景库存预警短信救了一次大促大促前一天库存同步系统出了bug有3个核心SKU的库存显示为负数。系统触发了短信告警我凌晨收到短信立即起来处理避免了大促期间超卖。这套短信告警系统就是用影刀RPA 阿里云短信服务搭的。短信是最可靠的告警渠道不受网络、App通知权限的影响手机能收信号就能收到。一、安装与准备工作阿里云短信服务不是免费的要先开通并购买套餐包。登录阿里云控制台 → 短信服务 → 国内消息。需要提前准备好的东西AccessKeyId 和 AccessKeySecret在访问控制RAM里创建短信签名需要审核一般1-2个工作日短信模板需要审核一般1个工作日我当时的签名审核被驳回了两次原因是签名必须与公司营业执照上的名称相关。如果你的公司名是北京某某科技有限公司签名填某某就能过填我的系统就过不了。AccessKey不要用在主账号下创建要去RAM访问控制里创建一个子用户只给短信发送的权限。我当时用了主账号的AccessKey后来代码泄露以为是私有的Git仓库结果是公开仓库被人拿去发短信一夜之间套餐包里的5000条短信全用完了。二、元素定位无界面操作纯API对接短信发送是纯后端操作不需要元素定位。但签名和模板的创建要在阿里云控制台完成可以用影刀的网页自动化来批量创建模板。用影刀的启动新浏览器指令打开短信控制台。用XPath定位添加模板按钮//button[contains(text(),添加模板)]模板内容里可以用变量格式是${code}这种。阿里云短信的变量格式${参数名}在发送时传入对应的值。我当时踩过这个坑模板里写了${name}和${code}发送时只传了name没传code阿里云返回变量缺失短信发送失败。模板变量有类型限制验证码类型只能是数字通知类可以是数字字母中文。三、变量与数据类型短信参数的正确组装阿里云短信API的请求参数参数类型说明PhoneNumbers字符串手机号多个用逗号分隔SignName字符串签名TemplateCode字符串模板CODETemplateParam字符串模板变量JSON格式TemplateParam是JSON字符串不是JSON对象正确写法{\name\:\张三\,\code\:\1234\}错误写法{name:张三,code:1234}在影刀里组装TemplateParam用配置参数指令先组装字典再用Python的json.dumps()转成字符串importjson template_param{name:张三,code:1234}param_strjson.dumps(template_param,ensure_asciiFalse)print(param_str)ensure_asciiFalse很重要否则中文会被转成\uXXXX格式阿里云有可能解析失败。我当时踩过这个坑没加ensure_asciiFalse中文转成了Unicode编码阿里云解析变量值时出错短信内容里的变量显示成了未知。四、流程控制按告警级别决定是否发短信拼多多店群自动化报活动上架短信是有成本的不能什么都发短信。我的分级策略提示级不发短信只发群消息警告级发短信给值班人员严重级发短信给所有人连续发3次每次间隔5分钟用影刀的如果…否则指令如果 告警级别 严重 手机号列表 [13800138000,13800138001,13800138002] 最大发送次数 3 发送间隔 300 否则如果 告警级别 警告 手机号列表 [13800138000] # 只发给值班人 最大发送次数 1 发送间隔 0 否则 结束流程 # 提示级不发短信 结束如果循环用在批量发送场景。多个手机号用逗号拼接成一个字符串阿里云支持一次调用发给多个人手机号字符串 遍历 手机号列表 手机号字符串 手机号字符串 当前手机号 , 结束遍历 去掉最后一个逗号阿里云限制一次最多发1000个手机号。五、网页自动化从监控台抓取告警信息告警信息来自业务监控台用影刀的启动新浏览器打开监控页面。用等待元素出现指令等页面加载完成再用获取元素文本指令抓取告警详情。XPath 正则组合定位有些元素的ID是动态的XPath用contains()函数模糊匹配//div[contains(class,alert) and contains(class,error)]如果页面内容是通过WebSocket推送的影刀的元素捕获有可能抓不到。解决方案用执行JavaScript指令直接读页面的JS变量// 在影刀执行JavaScript指令里执行returnwindow.__alert_data__;返回结果存到影刀变量里。我当时遇到过一个页面告警数据是存在localStorage里的页面上不显示但接口已经拿到了。用执行JavaScript指令读localStorage.getItem(alert_data)拿到了数据。六、数据处理把告警信息格式化成短信内容短信长度有限制单条短信最长70个汉字含签名超过会拆成多条计费。阿里云会自动拆分长短信但拆分后按多条计费成本会高。处理策略短信内容尽量精简。模板设计签名某某科技 模板内容 告警{name}请及时登录后台处理时间{time}。{name}是告警名称{time}是时间。字符数控制在50个汉字以内留有余地。动态内容里的数字要做格式化如果 订单数 10000 显示 万级以上 否则如果 订单数 1000 显示 千级 否则 显示 订单数 笔 结束如果我当时踩过这个坑告警内容里直接拼了完整的错误堆栈一条短信拆成了7条成本暴涨。后来所有短信内容都做长度检查超过50字就截断完整内容放到邮件里。七、鼠标键盘图像短信发送不涉界面操作短信发送是纯API操作不涉及鼠标键盘和图像。但短信模板的审核状态要在阿里云控制台查看可以用影刀定时检查审核状态审核通过后自动发一条测试短信。用影刀的启动新浏览器指令打开短信控制台。用获取元素文本指令读取模板状态//table[classtemplate-table]//tr[td[contains(text(),告警通知)]]/td[last()]如果状态从审核中变成审核通过触发测试短信发送。我当时踩过这个坑模板审核被驳回了但我没检查审核状态一直用这个模板发短信全部失败。现在流程里每次发短信前先调查询短信模板API确认模板状态是可用。八、进阶技能短信发送记录查询与对账阿里云短信API提供了查询发送记录的接口可以用来做发送对账。API地址GET https://dysmsapi.aliyuncs.com/ 参数 Action QuerySendDetails PhoneNumber 手机号 SendDate 日期格式 YYYYMMDD PageSize 50 CurrentPage 1返回结果里包含每条短信的发送状态、接收状态、失败原因。在影刀里每次发完短信把发送记录写到本地CSV文件写入CSV 时间手机号模板CODE发送状态阿里云返回码每天用另一个影刀流程对账发送记录和阿里云控制台的账单发现有差异比如本地记录成功但账单里没扣费或者反过来要告警。我当时第一次做对账发现本地记录显示发送成功200条但阿里云账单里扣了210条的费用。查了发送记录有10条被运营商拦截了返回状态是失败但阿里云已经计费了。短信发送成功不等于用户收到了运营商拦截是不退费的。九、平台实战在影刀配置短信发送任务短信发送任务分两种触发方式定时触发每天定时发送日报短信事件触发业务异常时立即发送告警短信定时触发在影刀控制台配置Cron表达式0 9 * * *每天9点发送昨日数据汇总短信给管理人员。事件触发要用影刀的开放API业务系统发生异常时调API触发影刀流程。开放API的调用方式POST https://api.winrobot360.com/oapi/dispatch/v2/job/start Header Authorization: Bearer {accessToken} Body { appUuid: 应用UUID, params: { alert_msg: 具体告警内容, alert_level: 严重 } }我当时踩过这个坑开放API的并发限制是每秒5次大批量告警时触发失败。解决方式在业务系统侧做告警合并同一个类型的告警5分钟内只触发一次影刀流程。十、系统联动短信 邮件 群消息三重保障短信虽然可靠但内容长度有限只能传关键信息。我的方案短信负责通知到人邮件负责传递详情群消息负责团队可见。在影刀流程里按顺序调用三个通道步骤1发短信告警核心信息 步骤2发邮件完整错误详情 截图 步骤3发群消息团队同步三个通道互不影响用尝试捕获包住每个通道尝试 发短信 捕获异常 记录日志 短信发送失败 异常信息 结束尝试 尝试 发邮件 捕获异常 记录日志 邮件发送失败 异常信息 结束尝试我当时有一次短信通道挂了阿里云短信服务故障但因为邮件和群消息正常还是有人看到了告警。从那以后所有关键告警都必须多通道发送不能只依赖一个通道。十一、工程化规范短信发送的可观测性短信是付费服务必须有完整的发送记录定期审计。规范一所有短信发送必须记录日志格式统一[短信发送] 时间 | 模板CODE | 手机号脱敏| 发送状态 | 阿里云返回码规范二手机号脱敏存储只保留前3位和后4位TEMU店群矩阵自动化运营核价报活动脱敏手机号 手机号[0:3] **** 手机号[7:11]规范三设置月度短信预算超过预算自动停止发送并告警。在影刀流程里每次发送前读取当月已发送条数超过预算就跳过发送并发告警。我当时没做预算控制有个bug导致告警短信无限循环发送一晚上发了3000多条套餐包直接用完。后来在所有短信发送流程里都加了同一告警类型5分钟内最多发1次的频率限制。十二、速查表与常见报错报错1isv.BUSINESS_LIMIT_CONTROL原因短信发送频率超过限制同一个手机号每分钟最多1条每小时最多5条。解决在流程里加发送频率控制同一个手机号间隔至少60秒。报错2isv.TEMPLATE_ILLEGAL原因模板不合法或者模板变量不匹配。解决检查模板内容和发送时传入的变量是否一致。报错3isv.SIGN_NAME_ILLEGAL原因签名不合法或者签名未审核通过。解决去阿里云控制台确认签名状态是可用。报错4isv.PARAM_NOT_SUPPORT原因模板变量类型不匹配比如模板定义的是验证码类型仅数字但传入了字母。解决检查模板变量类型定义发送时做类型校验。阿里云短信常见返回码速查返回码含义处理方式OK成功无需处理isv.BUSINESS_LIMIT_CONTROL限频加等待时间isv.TEMPLATE_ILLEGAL模板错误检查模板isv.SIGN_NAME_ILLEGAL签名错误检查签名isv.AMOUNT_NOT_ENOUGH余额不足充值完整案例代码参考阿里云短信发送Python封装在影刀执行Python代码指令里调用importrequestsimportjsonimporttimefromdatetimeimportdatetime ACCESS_KEY_ID你的AccessKeyIdACCESS_KEY_SECRET你的AccessKeySecretdefsend_sms(phone_numbers,sign_name,template_code,template_param): 发送短信 phone_numbers: 字符串多个手机号逗号分隔 sign_name: 签名 template_code: 模板CODE template_param: 字典模板变量 fromaliyunsdkcore.clientimportAcsClientfromaliyunsdkcore.requestimportCommonRequest clientAcsClient(ACCESS_KEY_ID,ACCESS_KEY_SECRET,cn-hangzhou)requestCommonRequest()request.set_accept_format(json)request.set_domain(dysmsapi.aliyuncs.com)request.set_method(POST)request.set_protocol_type(https)request.set_version(2017-05-25)request.set_action_name(SendSms)request.add_query_param(PhoneNumbers,phone_numbers)request.add_query_param(SignName,sign_name)request.add_query_param(TemplateCode,template_code)request.add_query_param(TemplateParam,json.dumps(template_param,ensure_asciiFalse))responseclient.do_action_with_http_request(request)resultjson.loads(response.decode(utf-8))returnresult# 查询发送记录defquery_send_details(phone_number,send_date,page1,page_size50):fromaliyunsdkcore.clientimportAcsClientfromaliyunsdkcore.requestimportCommonRequest clientAcsClient(ACCESS_KEY_ID,ACCESS_KEY_SECRET,cn-hangzhou)requestCommonRequest()request.set_accept_format(json)request.set_domain(dysmsapi.aliyuncs.com)request.set_method(POST)request.set_protocol_type(https)request.set_version(2017-05-25)request.set_action_name(QuerySendDetails)request.add_query_param(PhoneNumber,phone_number)request.add_query_param(SendDate,send_date)request.add_query_param(PageSize,page_size)request.add_query_param(CurrentPage,page)responseclient.do_action_with_http_request(request)returnjson.loads(response.decode(utf-8))XPath元素定位参考阿里云短信控制台# 模板审核状态 //table[classtemplate-list]//tr[td[1]/text()告警通知]/td[contains(class,status)]/text() # 签名状态 //table[classsign-list]//tr[td[1]/text()某某科技]/td[contains(class,status)]/text() # 发送记录 //table[classsend-record]//tr[1]/td/text()我当时踩过这个坑三个最深刻的教训教训一AccessKey放在代码里。早期版本AccessKey是硬编码的后来代码要发给同事看我用记事本打开截图马赛克了中间部分。但截图里还是有人猜出了完整Key短信被恶意调用。现在所有密钥都走影刀的应用参数代码里不出现任何明文密钥。教训二没做发送频率限制。告警触发逻辑有bug同一条告警1秒内触发了50次发了50条短信到我的手机。阿里云自动限频了但我已经被吵醒了。现在所有短信发送都加频率限制同一个内容、同一个手机号5分钟内最多发1次。教训三模板变量没做长度校验。短信模板里变量长度理论上不限但实际上变量内容太长会被运营商拦截。现在所有传入模板变量的内容都做长度校验超过20个字符的做截断处理。延伸阿里云短信SDK的完整封装代码包含发送、查询、对账功能我都整理到了 home.linyan.cloud。还有一套短信发送频率控制器的实现支持多告警类型独立限频可直接用到生产环境。#影刀RPA #RPA教程 #短信通知 #阿里云短信 #自动化告警 #林焱作者林焱