执行思路:使用金山文档的每日定时任务,执行阿里云盘签到接口。
无需部署,无需服务器,每个月更新一次token。
无需部署,无需服务器,每个月更新一次token。
先看本人的自动签到效果:
废话不多说,方法如下:
1、进入金山文档网页版
2、随便新建一个空表格,点击【效率】-【高级开发】-【AirScript脚本编辑器】
3、点击【创建脚本】-【文档共享脚本】
4、创建成功后随便命名,我这里命名为:阿里云盘签到
5、点击【服务】-【添加服务】
6、将三个服务全部添加
使用此代码一定要使用修改后的模版:https://kdocs.cn/l/ceQR4HpZ6op1
使用此代码一定要使用修改后的模版:https://kdocs.cn/l/ceQR4HpZ6op1
使用此代码一定要使用修改后的模版:https://kdocs.cn/l/ceQR4HpZ6op1
1.日志效果展示:
2.邮箱效果展示:
3.表格创建:
4.多账号单独管理:
修改后模版:https://kdocs.cn/l/ceQR4HpZ6op1
5.新增内容:
- 新增给多账号发送邮件
实现原理:使用循环变量来读取表单中的邮箱地址,直到遇到空值为止。每次读取到一个邮箱地址,都将其添加 到jsyxList数组中。然后,通过循环遍历jsyxList数组,并为每个邮箱地址发送邮件。
- 新增每个人的签到内容只会发送给同一行的对应邮箱地址
实现原理:将循环的范围从2到20改为对于每一行数据,获取对应的refresh_token、sflq和jsyx的值,并进行相应的判断和处理。如果refresh_token、sflq和jsyx的值符合条件(不为空且需要领取奖励且有接收邮箱地址),则进行签到和发送邮件的操作。签到成功后,将相关的签到内容存储在value变量中,然后将其发送给对应的邮箱地址。
- 新增邮件发送状态,监测发送邮件成功与失败
实现原理:在签到成功后使用log函数单独打印了"账号:13X***XXX-签到成功"的日志。然后,在发送邮件时,在调用log函数之前将签到内容存储在value变量中,并使用了try...catch语句来捕获邮件发送时可能发生的错误。在成功发送邮件时,会将成功信息记录到日志中,而在发送失败时,会将失败的具体错误信息记录到日志中。
- 新增每月最后一天,自动领取未领取的奖励
实现原理:使用 Date 对象获取当前日期和时间信息,并通过相关方法获得当前日期的字符串表示和月份的最后一天。然后,通过 for 循环遍历奖励数据的行,逐行获取相关数据进行处理。
6.代码对比:
对比最初的代码,以下是对代码进行的优化和改进的列表:
- 引入日期时间处理:添加了获取当前日期并格式化的功能,使用toLocaleDateString方法获取当前日期,并将其作为签到通知的主题一部分。
- 函数封装:将延迟等待的逻辑封装成了sleep函数,用于等待一段时间。这使得代码更加模块化和可读性更高。
- 错误处理和异常捕获:在发起网络请求和其他关键操作中增加了错误处理和异常捕获的逻辑,以便在出现错误时能够提供错误提示并及时终止代码的执行。
- 优化日志输出:在代码中添加了日志输出函数log,用于将信息打印到控制台,并在发送邮件时打印相应的状态和错误信息。
- 变量命名优化:对部分变量进行了更具描述性的命名,使代码更易读。
- 代码结构清晰:3.0代码使用了更具描述性的变量命名,并将不同功能的代码块进行了适当的分离,提高了代码的可读性和可维护性。
- 循环遍历优化:使用了let关键字声明循环变量row,避免了变量作用域的问题。同时,将循环起始值和结束条件直接写在循环语句中,简化了代码。
- 列索引灵活配置:通过在代码中定义变量tokenColumn、signInColumn等,可以根据需求方便地修改Excel表格中各列的索引,增加了代码的可配置性。
- 异常处理改进:对于网络请求获取token和领取奖励的部分,添加了try-catch语句来捕获可能出现的异常,并给出相应的错误提示信息,提高了代码的健壮性。
- 邮件发送优化:根据不同的条件和配置,灵活地选择使用自定义邮箱还是默认的SMTP邮箱发送邮件。使用了模板字符串和配置变量,简化了邮件发送部分的代码。
综上所述,对代码进行了结构优化、错误处理、日志输出优化以及变量命名优化,提高了代码的可读性、可维护性和错误处理能力,使得代码更加健壮和易于使用。
7.修改后的代码:
var myDate = new Date(); // 创建一个表示当前时间的 Date 对象 var data_time = myDate.toLocaleDateString(); // 获取当前日期的字符串表示 function sleep(d) { for (var t = Date.now(); Date.now() - t <= d;); // 使程序暂停执行一段时间 } function log(message) { console.log(message); // 打印消息到控制台 // TODO: 将日志写入文件 } var tokenColumn = "A"; // 设置列号变量为 "A" var signInColumn = "B"; // 设置列号变量为 "B" var rewardColumn = "C"; // 设置列号变量为 "C" var emailColumn = "F"; // 设置列号变量为 "F" var sendEmailColumn = "G"; // 设置列号变量为 "G" var resultColumn = "J"; // 设置列号变量为 "J" for (let row = 2; row <= 20; row++) { // 循环遍历从第 2 行到第 20 行的数据 var refresh_token = Application.Range(tokenColumn + row).Text; // 获取指定单元格的值 var sflq = Application.Range(signInColumn + row).Text; // 获取指定单元格的值 var sflqReward = Application.Range(rewardColumn + row).Text; // 获取指定单元格的值 var jsyx = Application.Range(emailColumn + row).Text; // 获取指定单元格的值 var sendEmail = Application.Range(sendEmailColumn + row).Text; // 获取指定单元格的值 var customEmailResult = Application.Range(resultColumn + row).Text; // 获取指定单元格的值 var emailConfigured = Application.Range("J1").Text; // 获取指定单元格的值 var zdy_host = Application.Range("J2").Text; // 获取指定单元格的值 var zdy_post = parseInt(Application.Range("J3").Text); // 获取指定单元格的值并转换为整数 var zdy_username = Application.Range("J4").Text; // 获取指定单元格的值 var zdy_pasd = Application.Range("J5").Text; // 获取指定单元格的值 if (sflq == "是") { // 如果“是否签到”为“是” if (refresh_token != "") { // 如果刷新令牌不为空 // 发起网络请求-获取token let data = HTTP.post("https://auth.aliyundrive.com/v2/account/token", JSON.stringify({ "grant_type": "refresh_token", "refresh_token": refresh_token }) ); data = data.json(); // 将响应数据解析为 JSON 格式 var access_token = data['access_token']; // 获取访问令牌 var phone = data["user_name"]; // 获取用户名 if (access_token == undefined) { // 如果访问令牌未定义 log("单元格【" + tokenColumn + row + "】内的token值错误,程序执行失败,请重新复制正确的token值"); continue; // 跳过当前行的后续操作 } try { var access_token2 = 'Bearer ' + access_token; // 构建包含访问令牌的请求头 // 签到 let data2 = HTTP.post("https://member.aliyundrive.com/v1/activity/sign_in_list", JSON.stringify({ "_rx-s": "mobile" }), { headers: { "Authorization": access_token2 } } ); data2 = data2.json(); // 将响应数据解析为 JSON 格式 var signin_count = data2['result']['signInCount']; // 获取签到次数 var logMessage = "账号:" + phone + " - 签到成功,本月累计签到 " + signin_count + " 天"; var rewardMessage = ""; if (sflqReward == "是") { // 如果“是否领取奖励”为“是” if (sflq == "是") { // 如果“是否签到”为“是” try { // 领取奖励 let data3 = HTTP.post( "https://member.aliyundrive.com/v1/activity/sign_in_reward?_rx-s=mobile", JSON.stringify({ "signInDay": signin_count }), { headers: { "Authorization": access_token2 } } ); data3 = data3.json(); // 将响应数据解析为 JSON 格式 var rewardName = data3["result"]["name"]; // 获取奖励名称 var rewardDescription = data3["result"]["description"]; // 获取奖励描述 rewardMessage = " " + rewardName + " - " + rewardDescription; } catch (error) { if (error.response && error.response.data && error.response.data.error) { var errorMessage = error.response.data.error; // 获取错误信息 if (errorMessage.includes(" - 今天奖励已领取")) { rewardMessage = " - 今天奖励已领取"; log("账号:" + phone + " - " + rewardMessage); } else { log("账号:" + phone + " - 奖励领取失败:" + errorMessage); } } else { log("账号:" + phone + " - 奖励领取失败"); } } } else { rewardMessage = " - 奖励待领取"; } } else { rewardMessage = " - 奖励待领取"; } log(logMessage + rewardMessage); if (sendEmail == "是") { // 如果“是否发送邮件”为“是” try { let mailer; if (customEmailResult == "是") { // 如果“是否自定义邮箱”为“是” var customEmail = Application.Range(resultColumn + row).Text; // 获取指定单元格的值 if (emailConfigured === "是") { // 如果配置了自定义邮箱 mailer = SMTP.login({ host: zdy_host, port: zdy_post, username: zdy_username, password: zdy_pasd, secure: true }); mailer.send({ from: "阿里云盘签到<" + zdy_username + ">", to: customEmail, subject: "阿里云盘签到通知 - " + data_time, text: logMessage + rewardMessage }); } else { // 如果未配置自定义邮箱,默认使用示例邮箱 mailer = SMTP.login({ host: "smtp.163.com", port: 465, username: "[email protected]", password: "QADSEMPKDHDAVWVD", secure: true }); mailer.send({ from: "阿里云盘签到<[email protected]>", to: customEmail, subject: "阿里云盘签到通知 - " + data_time, text: logMessage + rewardMessage }); } log("账号:" + phone + " - 已发送邮件至:" + customEmail); } else { // 如果“是否自定义邮箱”为“否” if (emailConfigured === "是") { // 如果配置了自定义邮箱 mailer = SMTP.login({ host: zdy_host, port: zdy_post, username: zdy_username, password: zdy_pasd, secure: true }); mailer.send({ from: "阿里云盘签到<" + zdy_username + ">", to: jsyx, subject: "阿里云盘签到通知 - " + data_time, text: logMessage + rewardMessage }); } else { // 如果未配置自定义邮箱,默认使用示例邮箱 mailer = SMTP.login({ host: "smtp.163.com", port: 465, username: "[email protected]", password: "QADSEMPKDHDAVWVD", secure: true }); mailer.send({ from: "阿里云盘签到<[email protected]>", to: jsyx, subject: "阿里云盘签到通知 - " + data_time, text: logMessage + rewardMessage }); } log("账号:" + phone + " - 已发送邮件至:" + jsyx); } } catch (error) { log("账号:" + phone + " - 发送邮件失败:" + error); } } } catch { log("单元格【" + tokenColumn + row + "】内的token签到失败"); continue; // 跳过当前行的后续操作 } } else { log("账号:" + phone + " 不签到"); } } } var currentDate = new Date(); // 创建一个表示当前时间的 Date 对象 var currentDay = currentDate.getDate(); // 获取当前日期的天数 var lastDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0).getDate(); // 获取当月的最后一天的日期 if (currentDay === lastDayOfMonth) { // 如果当前日期是当月的最后一天 for (let row = 2; row <= 20; row++) { // 循环遍历从第 2 行到第 20 行的数据 var sflq = Application.Range(signInColumn + row).Text; // 获取指定单元格的值 var sflqReward = Application.Range(rewardColumn + row).Text; // 获取指定单元格的值 if (sflq === "是" && sflqReward === "是") { // 如果“是否签到”和“是否领取奖励”均为“是” var refresh_token = Application.Range(tokenColumn + row).Text; // 获取指定单元格的值 var jsyx = Application.Range(emailColumn + row).Text; // 获取指定单元格的值 var phone = "账号:" + phone; // 构建账号信息字符串 if (refresh_token !== "") { // 如果刷新令牌不为空 // 发起网络请求-获取token let data = HTTP.post("https://auth.aliyundrive.com/v2/account/token", JSON.stringify({ "grant_type": "refresh_token", "refresh_token": refresh_token }) ); data = data.json(); // 将响应数据解析为 JSON 格式 var access_token = data['access_token']; // 获取访问令牌 if (access_token === undefined) { // 如果访问令牌未定义 log("单元格【" + tokenColumn + row + "】内的token值错误,程序执行失败,请重新复制正确的token值"); continue; // 跳过当前行的后续操作 } try { var access_token2 = 'Bearer ' + access_token; // 构建包含访问令牌的请求头 // 领取奖励 let data4 = HTTP.post( "https://member.aliyundrive.com/v1/activity/sign_in_reward?_rx-s=mobile", JSON.stringify({ "signInDay": lastDayOfMonth }), { headers: { "Authorization": access_token2 } } ); data4 = data4.json(); // 将响应数据解析为 JSON 格式 var claimStatus = data4["result"]["status"]; // 获取奖励状态 var day = lastDayOfMonth; // 获取最后一天的日期 if (claimStatus === "CLAIMED") { log("账号:" + phone + " - 第 " + day + " 天奖励领取成功"); } else { log("账号:" + phone + " - 第 " + day + " 天奖励领取失败"); } } catch { log("单元格【" + tokenColumn + row + "】内的token签到失败"); continue; // 跳过当前行的后续操作 } } else { log("账号:" + phone + " 不签到"); } } } log("自动领取未领取奖励完成。"); }
8.快速获取 token 值
//在控制台输入
var token = JSON.parse(localStorage.getItem('token'));
console.log('refresh_token:', token.refresh_token);
9.如何获取自己的SMTP
这里我以网易邮箱为例:
打开网易官网:https://mail.163.com/,登录账号
10.QQ邮箱获取自己的SMTP
请查看这篇内容:使用QQ邮箱发送邮件,QQ邮箱的smtp设置
- SMTP服务器:http://smtp.qq.com
- SMTP端口号:465。必须填这个端口号,否则会报错