阿里网盘自动签到

使用金山文档的每日定时任务,执行阿里云盘签到接口。

使用此代码一定要使用修改后的模版:https://kdocs.cn/l/ceQR4HpZ6op1

1.日志效果展示:

img

2.邮箱效果展示:

img

单/多账号下只发送与对应账号相关内容

img

一个人多个账号签到信息也是单独发送

3.表格创建:

img

请创建普通表格,智能表格定时签到不生效

4.多账号单独管理:

修改后模版:https://kdocs.cn/l/ceQR4HpZ6op1

img

对原有模版进行修改

5.新增内容:

  • 新增给多账号发送邮件
    实现原理:使用循环变量来读取表单中的邮箱地址,直到遇到空值为止。每次读取到一个邮箱地址,都将其添加 到jsyxList数组中。然后,通过循环遍历jsyxList数组,并为每个邮箱地址发送邮件。

  • 新增每个人的签到内容只会发送给同一行的对应邮箱地址
    实现原理:将循环的范围从2到20改为对于每一行数据,获取对应的refresh_tokensflqjsyx的值,并进行相应的判断和处理。如果refresh_tokensflqjsyx的值符合条件(不为空且需要领取奖励且有接收邮箱地址),则进行签到和发送邮件的操作。签到成功后,将相关的签到内容存储在value变量中,然后将其发送给对应的邮箱地址。

  • 新增邮件发送状态,监测发送邮件成功与失败
    实现原理:在签到成功后使用log函数单独打印了”账号:13X***XXX-签到成功”的日志。然后,在发送邮件时,在调用log函数之前将签到内容存储在value变量中,并使用了try...catch语句来捕获邮件发送时可能发生的错误。在成功发送邮件时,会将成功信息记录到日志中,而在发送失败时,会将失败的具体错误信息记录到日志中。

  • 新增每月最后一天,自动领取未领取的奖励
    实现原理:使用 Date 对象获取当前日期和时间信息,并通过相关方法获得当前日期的字符串表示和月份的最后一天。然后,通过 for 循环遍历奖励数据的行,逐行获取相关数据进行处理。

6.代码对比:

对比最初的代码,以下是对代码进行的优化和改进的列表:

  1. 引入日期时间处理:添加了获取当前日期并格式化的功能,使用toLocaleDateString方法获取当前日期,并将其作为签到通知的主题一部分。
  2. 函数封装:将延迟等待的逻辑封装成了sleep函数,用于等待一段时间。这使得代码更加模块化和可读性更高。
  3. 错误处理和异常捕获:在发起网络请求和其他关键操作中增加了错误处理和异常捕获的逻辑,以便在出现错误时能够提供错误提示并及时终止代码的执行。
  4. 优化日志输出:在代码中添加了日志输出函数log,用于将信息打印到控制台,并在发送邮件时打印相应的状态和错误信息。
  5. 变量命名优化:对部分变量进行了更具描述性的命名,使代码更易读。
  6. 代码结构清晰:3.0代码使用了更具描述性的变量命名,并将不同功能的代码块进行了适当的分离,提高了代码的可读性和可维护性。
  7. 循环遍历优化:使用了let关键字声明循环变量row,避免了变量作用域的问题。同时,将循环起始值和结束条件直接写在循环语句中,简化了代码。
  8. 列索引灵活配置:通过在代码中定义变量tokenColumnsignInColumn等,可以根据需求方便地修改Excel表格中各列的索引,增加了代码的可配置性。
  9. 异常处理改进:对于网络请求获取token和领取奖励的部分,添加了try-catch语句来捕获可能出现的异常,并给出相应的错误提示信息,提高了代码的健壮性。
  10. 邮件发送优化:根据不同的条件和配置,灵活地选择使用自定义邮箱还是默认的SMTP邮箱发送邮件。使用了模板字符串和配置变量,简化了邮件发送部分的代码。

综上所述,对代码进行了结构优化、错误处理、日志输出优化以及变量命名优化,提高了代码的可读性、可维护性和错误处理能力,使得代码更加健壮和易于使用。

7.修改后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
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: "fs8484848@163.com",
password: "QADSEMPKDHDAVWVD",
secure: true
});
mailer.send({
from: "阿里云盘签到<fs8484848@163.com>",
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: "fs8484848@163.com",
password: "QADSEMPKDHDAVWVD",
secure: true
});
mailer.send({
from: "阿里云盘签到<fs8484848@163.com>",
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 值

1
2
3
//在控制台输入
var token = JSON.parse(localStorage.getItem('token'));
console.log('refresh_token:', token.refresh_token);

img

打开控制台粘贴代码回车即可

9.如何获取自己的SMTP

这里我以网易邮箱为例:
打开网易官网:https://mail.163.com/,登录账号

img

img

10.QQ邮箱获取自己的SMTP

首先要开启QQ邮箱的smtp服务,默认是关闭的。

登录QQ邮箱,点“设置” - “帐户”。

img

找到“POP3/SMTP服务”和“IMAP/SMTP服务”项,点“开启”。

img

开启之后,点击“生成授权码”。这个授权码将作为邮箱的身份认证密码

img

然后到系统后台,在“系统管理” - “系统设置” - “邮件设置”中进行设置。

img

  • SMTP服务器:smtp.qq.com
  • SMTP端口号:465。必须填这个端口号,否则会报错。
  • 身份认证用户名:填完整的邮箱名,如:123456789@qq.com,包括@qq.com部分。
  • 身份认证密码:填上述的QQ邮箱授权码。注意,不是QQ邮箱的登录密码。
  • SMTP身份认证。选“是”。
  • SSL加密。选“是”。

设置好之后,一定要先点“保存”,然后再进行邮件发送测试。测试邮件不要写“测试”、“123”之类的文字,以免被认为是垃圾邮件,被禁止发送。尽量模仿一篇正式的邮件进行发送测试。

如果配置不正确,不管哪一项的配置不正确,出现的错误信息基本都一样的,大致为:

1
org.springframework.mail.MailAuthenticationException: Authentication failed; nested exception is javax.mail.AuthenticationFailedException: 530 Error: A secure connection is requiered(such as ssl). More information at http://service.mail.qq.com/cgi-bin/help?id=28

如果出现下面的错误信息,则是因为使用了QQ邮箱的登录密码或者是密码错误,应该使用上述的QQ邮箱授权码

1
org.springframework.mail.MailAuthenticationException: Authentication failed; nested exception is javax.mail.
  • SMTP服务器:http://smtp.qq.com
  • SMTP端口号:465。必须填这个端口号,否则会报错