-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
301 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
name: Run | ||
|
||
on: | ||
workflow_dispatch: | ||
repository_dispatch: | ||
|
||
jobs: | ||
build: | ||
|
||
if: github.actor == github.repository_owner | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@main | ||
- name: Run | ||
uses: GabrielBB/xvfb-action@v1 | ||
with: | ||
run: dotnet run | ||
env: | ||
CONF: ${{ secrets.CONF }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>disable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="PuppeteerSharp" Version="6.2.0" /> | ||
<PackageReference Include="StackExchange.Redis" Version="2.5.43" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.1.32328.378 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Note163Checkin", "Note163Checkin.csproj", "{A5132704-C07F-4689-8D84-A9F3EBEC6947}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{A5132704-C07F-4689-8D84-A9F3EBEC6947}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{A5132704-C07F-4689-8D84-A9F3EBEC6947}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{A5132704-C07F-4689-8D84-A9F3EBEC6947}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{A5132704-C07F-4689-8D84-A9F3EBEC6947}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {A5F3DCA6-F4AC-4CE1-B72E-D85664BA280A} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
using Newtonsoft.Json.Linq; | ||
using PuppeteerSharp; | ||
using StackExchange.Redis; | ||
using System.Text.Json; | ||
|
||
HttpClient _scClient = null; | ||
Conf _conf = Deserialize<Conf>(GetEnvValue("CONF")); | ||
if (!string.IsNullOrWhiteSpace(_conf.ScKey)) | ||
{ | ||
_scClient = new HttpClient(); | ||
} | ||
|
||
#region redis | ||
|
||
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect($"{_conf.RdsServer},password={_conf.RdsPwd},name=Note163Checkin,defaultDatabase=0,allowadmin=true,abortConnect=false"); | ||
IDatabase db = redis.GetDatabase(); | ||
bool isRedis = db.IsConnected("test"); | ||
Console.WriteLine("redis:{0}", isRedis ? "有效" : "无效"); | ||
|
||
#endregion | ||
|
||
Console.WriteLine("有道云笔记签到开始运行..."); | ||
for (int i = 0; i < _conf.Users.Length; i++) | ||
{ | ||
User user = _conf.Users[i]; | ||
string title = $"账号 {i + 1}: {user.Task} "; | ||
Console.WriteLine($"共 {_conf.Users.Length} 个账号,正在运行{title}..."); | ||
|
||
#region 获取cookie | ||
|
||
string cookie = string.Empty; | ||
bool isInvalid = true; string result = string.Empty; | ||
|
||
string redisKey = $"Note163_{user.Username}"; | ||
if (isRedis) | ||
{ | ||
var redisValue = await db.StringGetAsync(redisKey); | ||
if (redisValue.HasValue) | ||
{ | ||
cookie = redisValue.ToString(); | ||
(isInvalid, result) = await IsInvalid(cookie); | ||
Console.WriteLine("redis获取cookie,状态:{0}", isInvalid ? "无效" : "有效"); | ||
} | ||
} | ||
|
||
if (isInvalid) | ||
{ | ||
cookie = await Login(user.Username, user.Password); | ||
(isInvalid, result) = await IsInvalid(cookie); | ||
Console.WriteLine("login获取cookie,状态:{0}", isInvalid ? "无效" : "有效"); | ||
if (isInvalid) | ||
{//Cookie失效 | ||
await Notify($"{title}Cookie失效,请检查登录状态!", true); | ||
continue; | ||
} | ||
} | ||
|
||
if (isRedis) | ||
{ | ||
Console.WriteLine($"redis更新cookie:{await db.StringSetAsync(redisKey, cookie)}"); | ||
} | ||
|
||
#endregion | ||
|
||
using var client = new HttpClient(); | ||
client.DefaultRequestHeaders.Add("User-Agent", "ynote-android"); | ||
client.DefaultRequestHeaders.Add("Cookie", cookie); | ||
|
||
long space = 0; | ||
space += Deserialize<YdNoteRsp>(result).RewardSpace; | ||
|
||
//签到 | ||
result = await (await client.PostAsync("https://note.youdao.com/yws/mapi/user?method=checkin", null)) | ||
.Content.ReadAsStringAsync(); | ||
space += Deserialize<YdNoteRsp>(result).Space; | ||
|
||
//看广告 | ||
for (int j = 0; j < 3; j++) | ||
{ | ||
result = await (await client.PostAsync("https://note.youdao.com/yws/mapi/user?method=adPrompt", null)) | ||
.Content.ReadAsStringAsync(); | ||
space += Deserialize<YdNoteRsp>(result).Space; | ||
} | ||
|
||
//看视频广告 | ||
for (int j = 0; j < 3; j++) | ||
{ | ||
result = await (await client.PostAsync("https://note.youdao.com/yws/mapi/user?method=adRandomPrompt", null)) | ||
.Content.ReadAsStringAsync(); | ||
space += Deserialize<YdNoteRsp>(result).Space; | ||
} | ||
|
||
await Notify($"有道云笔记{title}签到成功,共获得空间 {space / 1048576} M"); | ||
} | ||
Console.WriteLine("签到运行完毕"); | ||
|
||
async Task<(bool isInvalid, string result)> IsInvalid(string cookie) | ||
{ | ||
using var client = new HttpClient(); | ||
client.DefaultRequestHeaders.Add("User-Agent", "ynote-android"); | ||
client.DefaultRequestHeaders.Add("Cookie", cookie); | ||
//每日打开客户端(即登陆) | ||
string result = await (await client.PostAsync("https://note.youdao.com/yws/api/daupromotion?method=sync", null)) | ||
.Content.ReadAsStringAsync(); | ||
return (result.Contains("error", StringComparison.OrdinalIgnoreCase), result); | ||
} | ||
|
||
async Task<string> Login(string username, string password) | ||
{ | ||
var launchOptions = new LaunchOptions | ||
{ | ||
Headless = false, | ||
DefaultViewport = null, | ||
ExecutablePath = @"/usr/bin/google-chrome" | ||
}; | ||
var browser = await Puppeteer.LaunchAsync(launchOptions); | ||
Page page = await browser.DefaultContext.NewPageAsync(); | ||
|
||
await page.GoToAsync("https://note.youdao.com/web", 60_000); | ||
await page.WaitForSelectorAsync(".login-btn", new WaitForSelectorOptions { Visible = true }); | ||
await page.TypeAsync(".login-username", username); | ||
await page.TypeAsync(".login-password", password); | ||
await Task.Delay(5_000); | ||
await page.ClickAsync(".login-btn"); | ||
await page.WaitForSelectorAsync("ydoc-app", new WaitForSelectorOptions { Visible = true }); | ||
|
||
var client = await page.Target.CreateCDPSessionAsync(); | ||
var ckObj = await client.SendAsync("Network.getAllCookies"); | ||
var cks = ckObj.Value<JArray>("cookies") | ||
.Where(p => p.Value<string>("domain").Contains("note.youdao.com")) | ||
.Select(p => $"{p.Value<string>("name")}={p.Value<string>("value")}"); | ||
|
||
await browser.DisposeAsync(); | ||
return string.Join(';', cks); | ||
} | ||
|
||
async Task Notify(string msg, bool isFailed = false) | ||
{ | ||
Console.WriteLine(msg); | ||
if (_conf.ScType == "Always" || (isFailed && _conf.ScType == "Failed")) | ||
{ | ||
await _scClient?.GetAsync($"https://sc.ftqq.com/{_conf.ScKey}.send?text={msg}"); | ||
} | ||
} | ||
|
||
T Deserialize<T>(string json) => JsonSerializer.Deserialize<T>(json, new JsonSerializerOptions | ||
{ | ||
PropertyNameCaseInsensitive = true, | ||
ReadCommentHandling = JsonCommentHandling.Skip | ||
}); | ||
|
||
string GetEnvValue(string key) => Environment.GetEnvironmentVariable(key); | ||
|
||
#region Conf | ||
|
||
class Conf | ||
{ | ||
public User[] Users { get; set; } | ||
public string ScKey { get; set; } | ||
public string ScType { get; set; } | ||
public string RdsServer { get; set; } | ||
public string RdsPwd { get; set; } | ||
} | ||
|
||
class User | ||
{ | ||
public string Task { get; set; } | ||
public string Username { get; set; } | ||
public string Password { get; set; } | ||
} | ||
|
||
#endregion | ||
|
||
class YdNoteRsp | ||
{ | ||
/// <summary> | ||
/// Sync奖励空间 | ||
/// </summary> | ||
public int RewardSpace { get; set; } | ||
|
||
/// <summary> | ||
/// 其他奖励空间 | ||
/// </summary> | ||
public int Space { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Note163Checkin | ||
|
||
## 一、Fork 仓库 | ||
|
||
**点击右上角的`Fork`** | ||
 | ||
|
||
## 二、添加 Secret | ||
|
||
**`Settings`->`Secrets`->`New secret`,添加以下Secret:** | ||
- `Conf`:其值如下: | ||
```json | ||
{ | ||
"Users": [{ | ||
"Task": "CC", //自定义名字,选填 | ||
"Username": "[email protected]", //账号 | ||
"Password": "aaa" //密码 | ||
}, { | ||
"Task": "MM", | ||
"Username": "[email protected]", | ||
"Password": "111" | ||
} | ||
], | ||
"ScKey": "", //server酱sckey,不填不开启 | ||
"ScType": "Failed", //通知类型. Always:始终通知; Failed:失败时通知; 不填/其他:不通知; | ||
"RdsServer": "xxx.redislabs.com:1234", //redis地址,选填 | ||
"RdsPwd": "ppp" //redis密码,选填 | ||
} | ||
``` | ||
`RdsServer`和`RdsPwd`是选填的,用于配置redis,来存储cookie。后续可以重用这个cookie,避免频繁登录账号。建议配置一下,可以使用[redislabs](https://app.redislabs.com/)的免费套餐。 | ||
|
||
**步骤图示如下:** | ||
 | ||
|
||
## 三、运行 | ||
|
||
**`Actions`->`Run`->`Run workflow`**: | ||
 | ||
|
||
**注意**:本项目**不会**自动运行,需要自行在`.github/workflows/main.yml`添加定时任务。 | ||
|
||
## 四、查看运行结果 | ||
|
||
**`Actions`->`Run`->`build`**,能看到下图,表示运行成功 | ||
 | ||
|
||
## 注意事项 | ||
|
||
24小时内频繁登录可能会触发验证,程序就会登录失败。此时需要在网页上手动登录一次(需要输入验证码),登录成功后再次运行本程序即可。 | ||
|
||
## 参考 | ||
|
||
参考了以下项目: | ||
- [ydao](https://github.com/yygtboy/ydao/) | ||
- [node-script](https://github.com/SunSeekerX/node-script) | ||
- [youdaoyun](https://github.com/hezhizheng/youdaoyun) |