├── .github
├── pull.yml
└── workflows
│ ├── 10000.yaml
│ ├── bika.yaml
│ ├── bilibili.yaml
│ ├── iqiyi.yaml
│ ├── repo_sync.yml
│ ├── tieba.yaml
│ ├── v2ex.yaml
│ ├── v_video.yaml
│ ├── wps.yaml
│ └── xiaomi.yaml
├── Env.js
├── Env.min.js
├── LICENSE
├── README.md
├── RepoSync.md
├── backUp
├── TG_PUSH.md
└── gitSync.md
├── function
├── 10000
│ └── 10000.js
├── bika
│ ├── bika.py
│ └── sendNotify.py
├── bilibili
│ ├── bilibili.py
│ ├── bilibiliapi.py
│ └── sendNotify.py
├── iQIYI-DailyBonus
│ ├── iQIYI-bak.js
│ └── iqiyi.js
├── q_video
│ └── q_video.js
├── sendNotify.js
├── sendNotify.py
├── tieba
│ └── tieba.js
├── v2ex
│ └── v2ex.js
├── wps
│ ├── sendNotify.py
│ └── wps_invitation.py
└── xiaomi_sports
│ ├── sendNotify.py
│ └── xiaomi.py
├── icon
├── DD_bot.png
├── TG_PUSH1.png
├── TG_PUSH2.png
├── TG_PUSH3.png
├── bark.jpg
├── create_new_sync_yaml.png
├── git1.jpg
├── git10.jpg
├── git11.jpg
├── git12.jpg
├── git13.jpg
├── git14.jpg
├── git2.jpg
├── git3.jpg
├── git4.jpg
├── git5.jpg
├── git6.jpg
├── git7.png
├── git8.jpg
├── git9.jpg
├── new_access_token.png
├── new_repository_secret.png
├── open_actions_permissions.png
├── reposync_result.png
├── run_reposync_actions.png
├── set_sectet_pat.png
├── set_up_workflow.png
└── your_new_token.png
├── package.json
└── requirements.txt
/.github/pull.yml:
--------------------------------------------------------------------------------
1 | version: "1"
2 | rules: # Array of rules
3 | - base: master # Required. Target branch
4 | upstream: BlueskyClouds:master # Required. Must be in the same fork network.
5 | mergeMethod: hardreset # Optional, one of [none, merge, squash, rebase, hardreset], Default: none.
6 | mergeUnstable: true # Optional, merge pull request even when the mergeable_state is not clean. Default: false
--------------------------------------------------------------------------------
/.github/workflows/10000.yaml:
--------------------------------------------------------------------------------
1 | name: 中国电信签到
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "0 */8 * * *"
7 | #电信经常签到不成功所以让他每八小时执行一下,一天三次
8 | watch:
9 | types: [started]
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 | if: github.event.repository.owner.id == github.event.sender.id
15 | steps:
16 | - uses: actions/checkout@v1
17 | - name: Use Node.js 10.x
18 | uses: actions/setup-node@v1
19 | with:
20 | node-version: 10.x
21 | - name: npm install
22 | run: |
23 | npm install
24 | - name: "运行【中国电信签到】"
25 | run: |
26 | node function/10000/10000.js
27 | env:
28 | TELECOM_MOBILE: ${{ secrets.TELECOM_MOBILE }}
29 | SEND_KEY: ${{ secrets.SEND_KEY }}
30 | PUSH_KEY: ${{ secrets.PUSH_KEY }}
31 | BARK_PUSH: ${{ secrets.BARK_PUSH }}
32 | PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN}}
33 | PUSH_PLUS_USER: ${{ secrets.PUSH_PLUS_USER}}
34 | QYWX_AM: ${{ secrets.QYWX_AM}}
35 | QYWX_KEY: ${{ secrets.QYWX_KEY}}
36 | TG_PROXY_HOST: ${{ secrets.TG_PROXY_HOST}}
37 | TG_PROXY_PORT: ${{ secrets.TG_PROXY_PORT}}
38 | IGOT_PUSH_KEY: ${{ secrets.IGOT_PUSH_KEY}}
39 | TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
40 | TG_USER_ID: ${{ secrets.TG_USER_ID }}
41 | BARK_SOUND: ${{ secrets.BARK_SOUND }}
42 | DD_BOT_TOKEN: ${{ secrets.DD_BOT_TOKEN }}
43 | DD_BOT_SECRET: ${{ secrets.DD_BOT_SECRET }}
44 | #最后推送 2021年4月09日
45 |
--------------------------------------------------------------------------------
/.github/workflows/bika.yaml:
--------------------------------------------------------------------------------
1 | name: 哔咔漫画自动打哔咔
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "01 04 * * *"
7 | watch:
8 | types: [started]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | if: github.event.repository.owner.id == github.event.sender.id
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v2
17 |
18 | - name: "Set up Python"
19 | uses: actions/setup-python@v1
20 | with:
21 | python-version: 3.8
22 |
23 | - name: "安装依赖包"
24 | run: pip install -r ./requirements.txt
25 |
26 | - name: "运行 哔咔漫画自动打哔咔"
27 | run: python3 function/bika/bika.py
28 | env:
29 | BIKA_USER: ${{ secrets.BIKA_USER }}
30 | BIKA_PASS: ${{ secrets.BIKA_PASS }}
31 | SEND_KEY: ${{ secrets.SEND_KEY }}
32 | PUSH_KEY: ${{ secrets.PUSH_KEY }}
33 | BARK_PUSH: ${{ secrets.BARK_PUSH }}
34 | PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN}}
35 | PUSH_PLUS_USER: ${{ secrets.PUSH_PLUS_USER}}
36 | TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
37 | TG_USER_ID: ${{ secrets.TG_USER_ID }}
38 | BARK_SOUND: ${{ secrets.BARK_SOUND }}
39 | DD_BOT_TOKEN: ${{ secrets.DD_BOT_TOKEN }}
40 | DD_BOT_SECRET: ${{ secrets.DD_BOT_SECRET }}
41 | QYWX_AM: ${{ secrets.QYWX_AM}}
42 | #最后推送 2021年4月22日
43 |
--------------------------------------------------------------------------------
/.github/workflows/bilibili.yaml:
--------------------------------------------------------------------------------
1 | name: 哔哩哔哩签到
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "5 16 * * *"
7 | watch:
8 | types: [started]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | if: github.event.repository.owner.id == github.event.sender.id
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v2
17 |
18 | - name: "Set up Python"
19 | uses: actions/setup-python@v1
20 | with:
21 | python-version: 3.8
22 |
23 | - name: "安装依赖包"
24 | run: pip install -r ./requirements.txt
25 |
26 | - name: "运行 哔哩哔哩签到"
27 | run: python3 function/bilibili/bilibili.py
28 | env:
29 | BILI_USER: ${{ secrets.BILI_USER }}
30 | BILI_PASS: ${{ secrets.BILI_PASS }}
31 | BILI_COOKIE: ${{ secrets.BILI_COOKIE }}
32 | BILI_NUM: ${{ secrets.BILI_NUM }}
33 | BILI_TYPE: ${{ secrets.BILI_TYPE }}
34 | SEND_KEY: ${{ secrets.SEND_KEY }}
35 | PUSH_KEY: ${{ secrets.PUSH_KEY }}
36 | BARK_PUSH: ${{ secrets.BARK_PUSH }}
37 | PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN}}
38 | PUSH_PLUS_USER: ${{ secrets.PUSH_PLUS_USER}}
39 | TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
40 | TG_USER_ID: ${{ secrets.TG_USER_ID }}
41 | BARK_SOUND: ${{ secrets.BARK_SOUND }}
42 | DD_BOT_TOKEN: ${{ secrets.DD_BOT_TOKEN }}
43 | DD_BOT_SECRET: ${{ secrets.DD_BOT_SECRET }}
44 | QYWX_AM: ${{ secrets.QYWX_AM}}
45 | #最后推送 2021年4月22日
--------------------------------------------------------------------------------
/.github/workflows/iqiyi.yaml:
--------------------------------------------------------------------------------
1 | name: 爱奇艺会员签到
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "*/20 16 * * *"
7 | watch:
8 | types: [started]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | if: github.event.repository.owner.id == github.event.sender.id
14 | steps:
15 | - uses: actions/checkout@v1
16 | - name: Use Node.js 10.x
17 | uses: actions/setup-node@v1
18 | with:
19 | node-version: 10.x
20 | - name: npm install
21 | run: |
22 | npm install
23 | - name: "运行【爱奇艺会员签到】"
24 | run: |
25 | node function/iQIYI-DailyBonus/iqiyi.js
26 | env:
27 | iQIYI_COOKIE: ${{ secrets.iQIYI_COOKIE }}
28 | SEND_KEY: ${{ secrets.SEND_KEY }}
29 | PUSH_KEY: ${{ secrets.PUSH_KEY }}
30 | BARK_PUSH: ${{ secrets.BARK_PUSH }}
31 | PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN}}
32 | PUSH_PLUS_USER: ${{ secrets.PUSH_PLUS_USER}}
33 | QYWX_KEY: ${{ secrets.QYWX_KEY}}
34 | QYWX_AM: ${{ secrets.QYWX_AM}}
35 | TG_PROXY_HOST: ${{ secrets.TG_PROXY_HOST}}
36 | TG_PROXY_PORT: ${{ secrets.TG_PROXY_PORT}}
37 | IGOT_PUSH_KEY: ${{ secrets.IGOT_PUSH_KEY}}
38 | TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
39 | TG_USER_ID: ${{ secrets.TG_USER_ID }}
40 | BARK_SOUND: ${{ secrets.BARK_SOUND }}
41 | DD_BOT_TOKEN: ${{ secrets.DD_BOT_TOKEN }}
42 | DD_BOT_SECRET: ${{ secrets.DD_BOT_SECRET }}
43 | #最后推送 2021年4月09日
44 |
--------------------------------------------------------------------------------
/.github/workflows/repo_sync.yml:
--------------------------------------------------------------------------------
1 | name: 自动同步-Actions
2 | on:
3 | schedule:
4 | - cron: '1 0,8,15 * * *'
5 | workflow_dispatch:
6 | watch:
7 | types: started
8 | repository_dispatch:
9 | types: 同步仓库
10 | jobs:
11 | repo-sync:
12 | env:
13 | PAT: ${{ secrets.PAT || github.event.client_payload.PAT }} #此处PAT需要申请,教程详见:https://www.jianshu.com/p/bb82b3ad1d11
14 | runs-on: ubuntu-latest
15 | if: github.event.repository.owner.id == github.event.sender.id
16 | steps:
17 | - uses: actions/checkout@v2
18 | with:
19 | persist-credentials: false
20 |
21 | - name: sync scripts
22 | uses: repo-sync/github-sync@v2
23 | if: env.PAT
24 | with:
25 | source_repo: "https://github.com/BlueSkyClouds/My-Actions.git"
26 | source_branch: "master"
27 | destination_branch: "master"
28 | github_token: ${{ secrets.PAT || github.event.client_payload.PAT }}
29 | #最后推送 2021年4月09日
--------------------------------------------------------------------------------
/.github/workflows/tieba.yaml:
--------------------------------------------------------------------------------
1 | name: 百度签到
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "30 04 * * *"
7 | watch:
8 | types: [started]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | if: github.event.repository.owner.id == github.event.sender.id
14 | steps:
15 | - uses: actions/checkout@v1
16 | - name: Use Node.js 10.x
17 | uses: actions/setup-node@v1
18 | with:
19 | node-version: 10.x
20 | - name: npm install
21 | run: |
22 | npm install
23 | - name: "运行【百度签到】"
24 | run: |
25 | node function/tieba/tieba.js
26 | env:
27 | BDUSS: ${{ secrets.BDUSS }}
28 | JUMP: ${{ secrets.BDUSS-JUMP }}
29 | SEND_KEY: ${{ secrets.SEND_KEY }}
30 | PUSH_KEY: ${{ secrets.PUSH_KEY }}
31 | BARK_PUSH: ${{ secrets.BARK_PUSH }}
32 | PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN}}
33 | PUSH_PLUS_USER: ${{ secrets.PUSH_PLUS_USER}}
34 | QYWX_KEY: ${{ secrets.QYWX_KEY}}
35 | QYWX_AM: ${{ secrets.QYWX_AM}}
36 | TG_PROXY_HOST: ${{ secrets.TG_PROXY_HOST}}
37 | TG_PROXY_PORT: ${{ secrets.TG_PROXY_PORT}}
38 | IGOT_PUSH_KEY: ${{ secrets.IGOT_PUSH_KEY}}
39 | TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
40 | TG_USER_ID: ${{ secrets.TG_USER_ID }}
41 | BARK_SOUND: ${{ secrets.BARK_SOUND }}
42 | DD_BOT_TOKEN: ${{ secrets.DD_BOT_TOKEN }}
43 | DD_BOT_SECRET: ${{ secrets.DD_BOT_SECRET }}
44 | #最后推送 2021年4月09日
--------------------------------------------------------------------------------
/.github/workflows/v2ex.yaml:
--------------------------------------------------------------------------------
1 | name: V2ex签到
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "0 14 * * *"
7 | watch:
8 | types: [started]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | if: github.event.repository.owner.id == github.event.sender.id
14 | steps:
15 | - uses: actions/checkout@v1
16 | - name: Use Node.js 10.x
17 | uses: actions/setup-node@v1
18 | with:
19 | node-version: 10.x
20 | - name: npm install
21 | run: |
22 | npm install
23 | - name: "运行【V2ex自动签到】"
24 | run: |
25 | node function/v2ex/v2ex.js
26 | env:
27 | V2EXCK: ${{ secrets.V2EXCK }}
28 | SEND_KEY: ${{ secrets.SEND_KEY }}
29 | PUSH_KEY: ${{ secrets.PUSH_KEY }}
30 | BARK_PUSH: ${{ secrets.BARK_PUSH }}
31 | PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN}}
32 | PUSH_PLUS_USER: ${{ secrets.PUSH_PLUS_USER}}
33 | QYWX_KEY: ${{ secrets.QYWX_KEY}}
34 | QYWX_AM: ${{ secrets.QYWX_AM}}
35 | TG_PROXY_HOST: ${{ secrets.TG_PROXY_HOST}}
36 | TG_PROXY_PORT: ${{ secrets.TG_PROXY_PORT}}
37 | IGOT_PUSH_KEY: ${{ secrets.IGOT_PUSH_KEY}}
38 | TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
39 | TG_USER_ID: ${{ secrets.TG_USER_ID }}
40 | BARK_SOUND: ${{ secrets.BARK_SOUND }}
41 | DD_BOT_TOKEN: ${{ secrets.DD_BOT_TOKEN }}
42 | DD_BOT_SECRET: ${{ secrets.DD_BOT_SECRET }}
43 | #最后推送 2021年4月09日
44 |
--------------------------------------------------------------------------------
/.github/workflows/v_video.yaml:
--------------------------------------------------------------------------------
1 | name: 腾讯视频签到
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "30 14 * * *"
7 | watch:
8 | types: [started]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | if: github.event.repository.owner.id == github.event.sender.id
14 | steps:
15 | - uses: actions/checkout@v1
16 | - name: Use Node.js 10.x
17 | uses: actions/setup-node@v1
18 | with:
19 | node-version: 10.x
20 | - name: npm install
21 | run: |
22 | npm install
23 | - name: "运行【腾讯视频签到】"
24 | run: |
25 | node function/q_video/q_video.js
26 | env:
27 | V_REF_URL: ${{ secrets.V_REF_URL }}
28 | V_COOKIE: ${{ secrets.V_COOKIE }}
29 | SEND_KEY: ${{ secrets.SEND_KEY }}
30 | PUSH_KEY: ${{ secrets.PUSH_KEY }}
31 | BARK_PUSH: ${{ secrets.BARK_PUSH }}
32 | PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN}}
33 | PUSH_PLUS_USER: ${{ secrets.PUSH_PLUS_USER}}
34 | QYWX_KEY: ${{ secrets.QYWX_KEY}}
35 | QYWX_AM: ${{ secrets.QYWX_AM}}
36 | TG_PROXY_HOST: ${{ secrets.TG_PROXY_HOST}}
37 | TG_PROXY_PORT: ${{ secrets.TG_PROXY_PORT}}
38 | IGOT_PUSH_KEY: ${{ secrets.IGOT_PUSH_KEY}}
39 | TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
40 | TG_USER_ID: ${{ secrets.TG_USER_ID }}
41 | BARK_SOUND: ${{ secrets.BARK_SOUND }}
42 | DD_BOT_TOKEN: ${{ secrets.DD_BOT_TOKEN }}
43 | DD_BOT_SECRET: ${{ secrets.DD_BOT_SECRET }}
44 | #最后推送 2021年4月09日
45 |
--------------------------------------------------------------------------------
/.github/workflows/wps.yaml:
--------------------------------------------------------------------------------
1 | name: WPS自动邀请
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "45 0 * * *"
7 | watch:
8 | types: [started]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | if: github.event.repository.owner.id == github.event.sender.id
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v2
17 |
18 | - name: "Set up Python"
19 | uses: actions/setup-python@v1
20 | with:
21 | python-version: 3.9
22 |
23 | - name: "安装依赖包"
24 | run: pip install -r ./requirements.txt
25 |
26 | - name: "运行 WPS自动邀请"
27 | run: python3 function/wps/wps_invitation.py
28 | env:
29 | WPS_KEY: ${{ secrets.WPS_KEY }}
30 | SEND_KEY: ${{ secrets.SEND_KEY }}
31 | PUSH_KEY: ${{ secrets.PUSH_KEY }}
32 | BARK_PUSH: ${{ secrets.BARK_PUSH }}
33 | PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN}}
34 | PUSH_PLUS_USER: ${{ secrets.PUSH_PLUS_USER}}
35 | TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
36 | TG_USER_ID: ${{ secrets.TG_USER_ID }}
37 | BARK_SOUND: ${{ secrets.BARK_SOUND }}
38 | DD_BOT_TOKEN: ${{ secrets.DD_BOT_TOKEN }}
39 | DD_BOT_SECRET: ${{ secrets.DD_BOT_SECRET }}
40 | QYWX_AM: ${{ secrets.QYWX_AM}}
41 | #最后推送 2021年4月22日
42 |
--------------------------------------------------------------------------------
/.github/workflows/xiaomi.yaml:
--------------------------------------------------------------------------------
1 | name: 小米自动刷步数
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "0 10 * * *"
7 | watch:
8 | types: [started]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | if: github.event.repository.owner.id == github.event.sender.id
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v2
17 |
18 | - name: "Set up Python"
19 | uses: actions/setup-python@v1
20 | with:
21 | python-version: 3.9
22 |
23 | - name: "安装依赖包"
24 | run: pip install -r ./requirements.txt
25 |
26 | - name: "运行 小米自动刷步数"
27 | run: python3 function/xiaomi_sports/xiaomi.py
28 | env:
29 | Xiaomi_User: ${{ secrets.Xiaomi_User }}
30 | Xiaomi_Pw: ${{ secrets.Xiaomi_Pw }}
31 | Xiaomi_Bs: ${{ secrets.Xiaomi_Bs }}
32 | SEND_KEY: ${{ secrets.SEND_KEY }}
33 | PUSH_KEY: ${{ secrets.PUSH_KEY }}
34 | BARK_PUSH: ${{ secrets.BARK_PUSH }}
35 | PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN}}
36 | PUSH_PLUS_USER: ${{ secrets.PUSH_PLUS_USER}}
37 | TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
38 | TG_USER_ID: ${{ secrets.TG_USER_ID }}
39 | BARK_SOUND: ${{ secrets.BARK_SOUND }}
40 | DD_BOT_TOKEN: ${{ secrets.DD_BOT_TOKEN }}
41 | DD_BOT_SECRET: ${{ secrets.DD_BOT_SECRET }}
42 | QYWX_AM: ${{ secrets.QYWX_AM}}
43 | #最后推送 2021年4月22日
44 |
--------------------------------------------------------------------------------
/Env.js:
--------------------------------------------------------------------------------
1 | function Env(name, opts) {
2 | class Http {
3 | constructor(env) {
4 | this.env = env
5 | }
6 |
7 | send(opts, method = 'GET') {
8 | opts = typeof opts === 'string' ? { url: opts } : opts
9 | let sender = this.get
10 | if (method === 'POST') {
11 | sender = this.post
12 | }
13 | return new Promise((resolve, reject) => {
14 | sender.call(this, opts, (err, resp, body) => {
15 | if (err) reject(err)
16 | else resolve(resp)
17 | })
18 | })
19 | }
20 |
21 | get(opts) {
22 | return this.send.call(this.env, opts)
23 | }
24 |
25 | post(opts) {
26 | return this.send.call(this.env, opts, 'POST')
27 | }
28 | }
29 |
30 | return new (class {
31 | constructor(name, opts) {
32 | this.name = name
33 | this.http = new Http(this)
34 | this.data = null
35 | this.dataFile = 'box.dat'
36 | this.logs = []
37 | this.isMute = false
38 | this.isNeedRewrite = false
39 | this.logSeparator = '\n'
40 | this.startTime = new Date().getTime()
41 | Object.assign(this, opts)
42 | this.log('', `🔔${this.name}, 开始!`)
43 | }
44 |
45 | isNode() {
46 | return 'undefined' !== typeof module && !!module.exports
47 | }
48 |
49 | isQuanX() {
50 | return 'undefined' !== typeof $task
51 | }
52 |
53 | isSurge() {
54 | return 'undefined' !== typeof $httpClient && 'undefined' === typeof $loon
55 | }
56 |
57 | isLoon() {
58 | return 'undefined' !== typeof $loon
59 | }
60 |
61 | isShadowrocket() {
62 | return 'undefined' !== typeof $rocket
63 | }
64 |
65 | toObj(str, defaultValue = null) {
66 | try {
67 | return JSON.parse(str)
68 | } catch {
69 | return defaultValue
70 | }
71 | }
72 |
73 | toStr(obj, defaultValue = null) {
74 | try {
75 | return JSON.stringify(obj)
76 | } catch {
77 | return defaultValue
78 | }
79 | }
80 |
81 | getjson(key, defaultValue) {
82 | let json = defaultValue
83 | const val = this.getdata(key)
84 | if (val) {
85 | try {
86 | json = JSON.parse(this.getdata(key))
87 | } catch {}
88 | }
89 | return json
90 | }
91 |
92 | setjson(val, key) {
93 | try {
94 | return this.setdata(JSON.stringify(val), key)
95 | } catch {
96 | return false
97 | }
98 | }
99 |
100 | getScript(url) {
101 | return new Promise((resolve) => {
102 | this.get({ url }, (err, resp, body) => resolve(body))
103 | })
104 | }
105 |
106 | runScript(script, runOpts) {
107 | return new Promise((resolve) => {
108 | let httpapi = this.getdata('@chavy_boxjs_userCfgs.httpapi')
109 | httpapi = httpapi ? httpapi.replace(/\n/g, '').trim() : httpapi
110 | let httpapi_timeout = this.getdata('@chavy_boxjs_userCfgs.httpapi_timeout')
111 | httpapi_timeout = httpapi_timeout ? httpapi_timeout * 1 : 20
112 | httpapi_timeout = runOpts && runOpts.timeout ? runOpts.timeout : httpapi_timeout
113 | const [key, addr] = httpapi.split('@')
114 | const opts = {
115 | url: `http://${addr}/v1/scripting/evaluate`,
116 | body: { script_text: script, mock_type: 'cron', timeout: httpapi_timeout },
117 | headers: { 'X-Key': key, 'Accept': '*/*' }
118 | }
119 | this.post(opts, (err, resp, body) => resolve(body))
120 | }).catch((e) => this.logErr(e))
121 | }
122 |
123 | loaddata() {
124 | if (this.isNode()) {
125 | this.fs = this.fs ? this.fs : require('fs')
126 | this.path = this.path ? this.path : require('path')
127 | const curDirDataFilePath = this.path.resolve(this.dataFile)
128 | const rootDirDataFilePath = this.path.resolve(process.cwd(), this.dataFile)
129 | const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath)
130 | const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath)
131 | if (isCurDirDataFile || isRootDirDataFile) {
132 | const datPath = isCurDirDataFile ? curDirDataFilePath : rootDirDataFilePath
133 | try {
134 | return JSON.parse(this.fs.readFileSync(datPath))
135 | } catch (e) {
136 | return {}
137 | }
138 | } else return {}
139 | } else return {}
140 | }
141 |
142 | writedata() {
143 | if (this.isNode()) {
144 | this.fs = this.fs ? this.fs : require('fs')
145 | this.path = this.path ? this.path : require('path')
146 | const curDirDataFilePath = this.path.resolve(this.dataFile)
147 | const rootDirDataFilePath = this.path.resolve(process.cwd(), this.dataFile)
148 | const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath)
149 | const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath)
150 | const jsondata = JSON.stringify(this.data)
151 | if (isCurDirDataFile) {
152 | this.fs.writeFileSync(curDirDataFilePath, jsondata)
153 | } else if (isRootDirDataFile) {
154 | this.fs.writeFileSync(rootDirDataFilePath, jsondata)
155 | } else {
156 | this.fs.writeFileSync(curDirDataFilePath, jsondata)
157 | }
158 | }
159 | }
160 |
161 | lodash_get(source, path, defaultValue = undefined) {
162 | const paths = path.replace(/\[(\d+)\]/g, '.$1').split('.')
163 | let result = source
164 | for (const p of paths) {
165 | result = Object(result)[p]
166 | if (result === undefined) {
167 | return defaultValue
168 | }
169 | }
170 | return result
171 | }
172 |
173 | lodash_set(obj, path, value) {
174 | if (Object(obj) !== obj) return obj
175 | if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || []
176 | path
177 | .slice(0, -1)
178 | .reduce((a, c, i) => (Object(a[c]) === a[c] ? a[c] : (a[c] = Math.abs(path[i + 1]) >> 0 === +path[i + 1] ? [] : {})), obj)[
179 | path[path.length - 1]
180 | ] = value
181 | return obj
182 | }
183 |
184 | getdata(key) {
185 | let val = this.getval(key)
186 | // 如果以 @
187 | if (/^@/.test(key)) {
188 | const [, objkey, paths] = /^@(.*?)\.(.*?)$/.exec(key)
189 | const objval = objkey ? this.getval(objkey) : ''
190 | if (objval) {
191 | try {
192 | const objedval = JSON.parse(objval)
193 | val = objedval ? this.lodash_get(objedval, paths, '') : val
194 | } catch (e) {
195 | val = ''
196 | }
197 | }
198 | }
199 | return val
200 | }
201 |
202 | setdata(val, key) {
203 | let issuc = false
204 | if (/^@/.test(key)) {
205 | const [, objkey, paths] = /^@(.*?)\.(.*?)$/.exec(key)
206 | const objdat = this.getval(objkey)
207 | const objval = objkey ? (objdat === 'null' ? null : objdat || '{}') : '{}'
208 | try {
209 | const objedval = JSON.parse(objval)
210 | this.lodash_set(objedval, paths, val)
211 | issuc = this.setval(JSON.stringify(objedval), objkey)
212 | } catch (e) {
213 | const objedval = {}
214 | this.lodash_set(objedval, paths, val)
215 | issuc = this.setval(JSON.stringify(objedval), objkey)
216 | }
217 | } else {
218 | issuc = this.setval(val, key)
219 | }
220 | return issuc
221 | }
222 |
223 | getval(key) {
224 | if (this.isSurge() || this.isLoon()) {
225 | return $persistentStore.read(key)
226 | } else if (this.isQuanX()) {
227 | return $prefs.valueForKey(key)
228 | } else if (this.isNode()) {
229 | this.data = this.loaddata()
230 | return this.data[key]
231 | } else {
232 | return (this.data && this.data[key]) || null
233 | }
234 | }
235 |
236 | setval(val, key) {
237 | if (this.isSurge() || this.isLoon()) {
238 | return $persistentStore.write(val, key)
239 | } else if (this.isQuanX()) {
240 | return $prefs.setValueForKey(val, key)
241 | } else if (this.isNode()) {
242 | this.data = this.loaddata()
243 | this.data[key] = val
244 | this.writedata()
245 | return true
246 | } else {
247 | return (this.data && this.data[key]) || null
248 | }
249 | }
250 |
251 | initGotEnv(opts) {
252 | this.got = this.got ? this.got : require('got')
253 | this.cktough = this.cktough ? this.cktough : require('tough-cookie')
254 | this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar()
255 | if (opts) {
256 | opts.headers = opts.headers ? opts.headers : {}
257 | if (undefined === opts.headers.Cookie && undefined === opts.cookieJar) {
258 | opts.cookieJar = this.ckjar
259 | }
260 | }
261 | }
262 |
263 | get(opts, callback = () => {}) {
264 | if (opts.headers) {
265 | delete opts.headers['Content-Type']
266 | delete opts.headers['Content-Length']
267 | }
268 | if (this.isSurge() || this.isLoon()) {
269 | if (this.isSurge() && this.isNeedRewrite) {
270 | opts.headers = opts.headers || {}
271 | Object.assign(opts.headers, { 'X-Surge-Skip-Scripting': false })
272 | }
273 | $httpClient.get(opts, (err, resp, body) => {
274 | if (!err && resp) {
275 | resp.body = body
276 | resp.statusCode = resp.status
277 | }
278 | callback(err, resp, body)
279 | })
280 | } else if (this.isQuanX()) {
281 | if (this.isNeedRewrite) {
282 | opts.opts = opts.opts || {}
283 | Object.assign(opts.opts, { hints: false })
284 | }
285 | $task.fetch(opts).then(
286 | (resp) => {
287 | const { statusCode: status, statusCode, headers, body } = resp
288 | callback(null, { status, statusCode, headers, body }, body)
289 | },
290 | (err) => callback(err)
291 | )
292 | } else if (this.isNode()) {
293 | this.initGotEnv(opts)
294 | this.got(opts)
295 | .on('redirect', (resp, nextOpts) => {
296 | try {
297 | if (resp.headers['set-cookie']) {
298 | const ck = resp.headers['set-cookie'].map(this.cktough.Cookie.parse).toString()
299 | if (ck) {
300 | this.ckjar.setCookieSync(ck, null)
301 | }
302 | nextOpts.cookieJar = this.ckjar
303 | }
304 | } catch (e) {
305 | this.logErr(e)
306 | }
307 | // this.ckjar.setCookieSync(resp.headers['set-cookie'].map(Cookie.parse).toString())
308 | })
309 | .then(
310 | (resp) => {
311 | const { statusCode: status, statusCode, headers, body } = resp
312 | callback(null, { status, statusCode, headers, body }, body)
313 | },
314 | (err) => {
315 | const { message: error, response: resp } = err
316 | callback(error, resp, resp && resp.body)
317 | }
318 | )
319 | }
320 | }
321 |
322 | post(opts, callback = () => {}) {
323 | const method = opts.method ? opts.method.toLocaleLowerCase() : 'post'
324 | // 如果指定了请求体, 但没指定`Content-Type`, 则自动生成
325 | if (opts.body && opts.headers && !opts.headers['Content-Type']) {
326 | opts.headers['Content-Type'] = 'application/x-www-form-urlencoded'
327 | }
328 | if (opts.headers) delete opts.headers['Content-Length']
329 | if (this.isSurge() || this.isLoon()) {
330 | if (this.isSurge() && this.isNeedRewrite) {
331 | opts.headers = opts.headers || {}
332 | Object.assign(opts.headers, { 'X-Surge-Skip-Scripting': false })
333 | }
334 | $httpClient[method](opts, (err, resp, body) => {
335 | if (!err && resp) {
336 | resp.body = body
337 | resp.statusCode = resp.status
338 | }
339 | callback(err, resp, body)
340 | })
341 | } else if (this.isQuanX()) {
342 | opts.method = method
343 | if (this.isNeedRewrite) {
344 | opts.opts = opts.opts || {}
345 | Object.assign(opts.opts, { hints: false })
346 | }
347 | $task.fetch(opts).then(
348 | (resp) => {
349 | const { statusCode: status, statusCode, headers, body } = resp
350 | callback(null, { status, statusCode, headers, body }, body)
351 | },
352 | (err) => callback(err)
353 | )
354 | } else if (this.isNode()) {
355 | this.initGotEnv(opts)
356 | const { url, ..._opts } = opts
357 | this.got[method](url, _opts).then(
358 | (resp) => {
359 | const { statusCode: status, statusCode, headers, body } = resp
360 | callback(null, { status, statusCode, headers, body }, body)
361 | },
362 | (err) => {
363 | const { message: error, response: resp } = err
364 | callback(error, resp, resp && resp.body)
365 | }
366 | )
367 | }
368 | }
369 | /**
370 | *
371 | * 示例:$.time('yyyy-MM-dd qq HH:mm:ss.S')
372 | * :$.time('yyyyMMddHHmmssS')
373 | * y:年 M:月 d:日 q:季 H:时 m:分 s:秒 S:毫秒
374 | * 其中y可选0-4位占位符、S可选0-1位占位符,其余可选0-2位占位符
375 | * @param {string} fmt 格式化参数
376 | * @param {number} 可选: 根据指定时间戳返回格式化日期
377 | *
378 | */
379 | time(fmt, ts = null) {
380 | const date = ts ? new Date(ts) : new Date()
381 | let o = {
382 | 'M+': date.getMonth() + 1,
383 | 'd+': date.getDate(),
384 | 'H+': date.getHours(),
385 | 'm+': date.getMinutes(),
386 | 's+': date.getSeconds(),
387 | 'q+': Math.floor((date.getMonth() + 3) / 3),
388 | 'S': date.getMilliseconds()
389 | }
390 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
391 | for (let k in o)
392 | if (new RegExp('(' + k + ')').test(fmt))
393 | fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
394 | return fmt
395 | }
396 |
397 | /**
398 | * 系统通知
399 | *
400 | * > 通知参数: 同时支持 QuanX 和 Loon 两种格式, EnvJs根据运行环境自动转换, Surge 环境不支持多媒体通知
401 | *
402 | * 示例:
403 | * $.msg(title, subt, desc, 'twitter://')
404 | * $.msg(title, subt, desc, { 'open-url': 'twitter://', 'media-url': 'https://github.githubassets.com/images/modules/open_graph/github-mark.png' })
405 | * $.msg(title, subt, desc, { 'open-url': 'https://bing.com', 'media-url': 'https://github.githubassets.com/images/modules/open_graph/github-mark.png' })
406 | *
407 | * @param {*} title 标题
408 | * @param {*} subt 副标题
409 | * @param {*} desc 通知详情
410 | * @param {*} opts 通知参数
411 | *
412 | */
413 | msg(title = name, subt = '', desc = '', opts) {
414 | const toEnvOpts = (rawopts) => {
415 | if (!rawopts) return rawopts
416 | if (typeof rawopts === 'string') {
417 | if (this.isLoon()) return rawopts
418 | else if (this.isQuanX()) return { 'open-url': rawopts }
419 | else if (this.isSurge()) return { url: rawopts }
420 | else return undefined
421 | } else if (typeof rawopts === 'object') {
422 | if (this.isLoon()) {
423 | let openUrl = rawopts.openUrl || rawopts.url || rawopts['open-url']
424 | let mediaUrl = rawopts.mediaUrl || rawopts['media-url']
425 | return { openUrl, mediaUrl }
426 | } else if (this.isQuanX()) {
427 | let openUrl = rawopts['open-url'] || rawopts.url || rawopts.openUrl
428 | let mediaUrl = rawopts['media-url'] || rawopts.mediaUrl
429 | return { 'open-url': openUrl, 'media-url': mediaUrl }
430 | } else if (this.isSurge()) {
431 | let openUrl = rawopts.url || rawopts.openUrl || rawopts['open-url']
432 | return { url: openUrl }
433 | }
434 | } else {
435 | return undefined
436 | }
437 | }
438 | if (!this.isMute) {
439 | if (this.isSurge() || this.isLoon()) {
440 | $notification.post(title, subt, desc, toEnvOpts(opts))
441 | } else if (this.isQuanX()) {
442 | $notify(title, subt, desc, toEnvOpts(opts))
443 | }
444 | }
445 | if (!this.isMuteLog) {
446 | let logs = ['', '==============📣系统通知📣==============']
447 | logs.push(title)
448 | subt ? logs.push(subt) : ''
449 | desc ? logs.push(desc) : ''
450 | console.log(logs.join('\n'))
451 | this.logs = this.logs.concat(logs)
452 | }
453 | }
454 |
455 | log(...logs) {
456 | if (logs.length > 0) {
457 | this.logs = [...this.logs, ...logs]
458 | }
459 | console.log(logs.join(this.logSeparator))
460 | }
461 |
462 | logErr(err, msg) {
463 | const isPrintSack = !this.isSurge() && !this.isQuanX() && !this.isLoon()
464 | if (!isPrintSack) {
465 | this.log('', `❗️${this.name}, 错误!`, err)
466 | } else {
467 | this.log('', `❗️${this.name}, 错误!`, err.stack)
468 | }
469 | }
470 |
471 | wait(time) {
472 | return new Promise((resolve) => setTimeout(resolve, time))
473 | }
474 |
475 | done(val = {}) {
476 | const endTime = new Date().getTime()
477 | const costTime = (endTime - this.startTime) / 1000
478 | this.log('', `🔔${this.name}, 结束! 🕛 ${costTime} 秒`)
479 | this.log()
480 | if (this.isSurge() || this.isQuanX() || this.isLoon()) {
481 | $done(val)
482 | }
483 | }
484 | })(name, opts)
485 | }
--------------------------------------------------------------------------------
/Env.min.js:
--------------------------------------------------------------------------------
1 | function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),a={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(a,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:i,...r}=t;this.got[s](i,r).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${s} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)}
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2020, BlueSkyClouds
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
My-Actions
4 |

5 |

6 |

7 |

8 |

9 |
10 |
11 | 个人收集并适配Github Actions的各类签到大杂烩
12 |
13 | ### 本项目已可以实现自动同步上游更改
14 |
15 | # 使用方式
16 | 1. 右上角fork本仓库
17 | 2. 点击Settings -> Secrets -> 点击绿色按钮 (如无绿色按钮说明已激活。直接到第三步。)
18 | 3. 新增 new secret 并设置 Secrets:
19 | 4. 双击右上角自己仓库Star触发,如有不使用项目请[禁用部分项目](https://cdn.jsdelivr.net/gh/BlueskyClouds/BlueskyClouds.github.io/2020/10/19/img/2020-10-19.jpg)
20 | 6. **必须** - 请随便找个文件(例如`README.md`),加个空格提交一下,否则可能会出现无法定时执行的问题
21 | 7. 由于规则更新,可能会Fork后会默认禁用,请手动点击Actions 选择要签到的项目 `enable workflows`激活
22 | 8. [定时执行](#定时执行)
23 |
24 | # 定时执行
25 | 1. 支持手动执行,具体在Actions中选中要执行的Workflows后再在右侧可以看到Run workflow,点击即可运行此workflow。
26 |
27 | 2. 如果嫌上一步麻烦的,也可以直接点击一下star,你会发现所有的workflow都已执行。
28 |
29 | 3. 如需修改执行时间自行修改`.github\workflows\`下面的yaml内的` cron:` 执行时间为国际标准时间 [时间转换](http://www.timebie.com/cn/universalbeijing.php) 分钟在前 小时在后 尽量提前几分钟,因为下载安装部署环境需要一定时间
30 |
31 | ##### Cookie变量设置 Secrets:**
32 |
33 | | 名称 | 内容 | 说明 |
34 | | -------- | -------------| ----- |
35 | | `PAT` | 自动同步**必须设置** |利用Github Actions自动同步上游仓库或新建仓库[PAT获取教程](RepoSync.md)|
36 | | `IQIYI_COOKIE` | 爱奇艺authcookie |P00001的值 详情[文字教程](https://www.bilibili.com/read/cv7437179) [视频教程](https://www.bilibili.com/video/BV1B541157DE) 电脑版有效期三个月|
37 | | `Xiaomi_User` | 小米运动账号 |小米运动账号,多账号请用#分割 例如:13800138000#13800138001|
38 | | `Xiaomi_Pw` | 小米运动密码 |小米运动密码,多账号请用#分割 例如:abc123qwe#abcqwe2|
39 | | `Xiaomi_Bs` | 小米运动步数 |默认为1w-2w之间随机 或自定义随机范围`[18000-25000]`|
40 | | `BILI_USER` | 哔哩哔哩账号 |B站账号|
41 | | `BILI_PASS` | 哔哩哔哩密码 |B站密码|
42 | | `BILI_COOKIE` | 哔哩哔哩COOKIE`(非必填)` |哔哩哔哩COOKIE,如果账号密码无法登陆就用COOKIE,等一段时间再用账号密码即可.|
43 | | `BILI_NUM` | 哔哩哔哩每日投币数量 |每日投币数量`可不填`默认0 不投币|
44 | | `BILI_TYPE` | 哔哩哔哩每日投币方式 |投币方式`可不填`默认1,只给关注的人投币 0 则随机投币|
45 | | `BIKA_USER` | 哔咔漫画用户名 |哔咔漫画用户名|
46 | | `BIKA_PASS` | 哔咔漫画密码 |哔咔漫画密码|
47 | | `WPS_KEY` | WPS_SID |WPS `COOKIE`中的wps_sid,只要不注销,10年过期|
48 | | `V_REF_URL` | 腾讯视频Request URL |电脑端搜索auth_refresh复制整段Request url[图片教程](https://cdn.jsdelivr.net/gh/BlueskyClouds/BlueskyClouds.github.io/2020/11/1/img/v_1.jpg)|
49 | | `V_COOKIE` | 腾讯视频Cookie |电脑端搜索auth_refresh复制Cookie[图片教程](https://cdn.jsdelivr.net/gh/BlueskyClouds/BlueskyClouds.github.io/2020/11/1/img/v_2.jpg)|
50 | | `TELECOM_MOBILE` | 中国电信手机号 |只需要手机号 单账号 `多账号将会暴露手机号` 自行考虑,多账号使用`,`分割 部分地区或手机号暂无法签到,自行测试使用|
51 | | `V2EXCK` | V2EX的Cookie |V2EX的Cookie|
52 | | `BDUSS` | 百度BDUSS |BDUSS值切勿使用双击复制 (结尾有一个`符号`双击复制可能无法复制完整)|
53 | ##### 推送通知环境变量(目前提供`微信server酱`、`pushplus(推送加)`、`iOS Bark APP`、`telegram机器人`、`钉钉机器人`、`企业微信机器人`、`iGot`等通知方式)
54 |
55 | | Name | 归属 | 属性 | 说明 |
56 | | :---------------------: | :----------: | --------- | ------------------------------------------------------------ |
57 | | `SEND_KEY` | 推送开关 | 非必须 | 仅在Cookie失效时发送推送,值随意|
58 | | `PUSH_KEY` | 微信server酱推送 | 非必须 | server酱的微信通知[更新公告](https://sc.ftqq.com/9.version) |
59 | | `BARK_PUSH` | [BARK推送](https://apps.apple.com/us/app/bark-customed-notifications/id1403753865) | 非必须 | IOS用户下载BARK这个APP,填写内容是app提供的`设备码`,例如:https://api.day.app/123 ,那么此处的设备码就是`123`,再不懂看 [这个图](https://github.com/BlueskyClouds/My-Actions/blob/master/icon/bark.jpg)(注:支持自建填完整链接即可) |
60 | | `BARK_SOUND` | [BARK推送](https://apps.apple.com/us/app/bark-customed-notifications/id1403753865) | 非必须 | bark推送声音设置,例如`choo`,具体值请在`bark`-`推送铃声`-`查看所有铃声` |
61 | | `TG_BOT_TOKEN` | telegram推送 | 非必须 | tg推送(需设备可连接外网),`TG_BOT_TOKEN`和`TG_USER_ID`两者必需,填写自己申请[@BotFather](https://t.me/BotFather)的Token,如`10xxx4:AAFcqxxxxgER5uw` , [具体教程](https://github.com/BlueskyClouds/My-Actions/blob/master/backUp/TG_PUSH.md) |
62 | | `TG_USER_ID` | telegram推送 | 非必须 | tg推送(需设备可连接外网),`TG_BOT_TOKEN`和`TG_USER_ID`两者必需,填写[@getuseridbot](https://t.me/getuseridbot)中获取到的纯数字ID, [具体教程](https://github.com/BlueskyClouds/My-Actions/blob/master/backUp/TG_PUSH.md) |
63 | | `DD_BOT_TOKEN` | 钉钉推送 | 非必须 | 钉钉推送(`DD_BOT_TOKEN`和`DD_BOT_SECRET`两者必需)[官方文档](https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq) ,只需`https://oapi.dingtalk.com/robot/send?access_token=XXX` 等于`=`符号后面的XXX即可 |
64 | | `DD_BOT_SECRET` | 钉钉推送 | 非必须 | (`DD_BOT_TOKEN`和`DD_BOT_SECRET`两者必需) ,密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的`SECXXXXXXXXXX`等字符 , 注:钉钉机器人安全设置只需勾选`加签`即可,其他选项不要勾选,再不懂看 [这个图](https://github.com/BlueskyClouds/My-Actions/blob/master/icon/DD_bot.png) |
65 | | `QYWX_KEY` | 企业微信机器人推送 | 非必须 | 密钥,企业微信推送 webhook 后面的 key [详见官方说明文档](https://work.weixin.qq.com/api/doc/90000/90136/91770) |
66 | | `QYWX_AM` | 企业微信应用推送 | 非必须 | 依次填入 企业id,secret,@all(或者成员id),AgentID,图片id [详见官方说明文档](https://work.weixin.qq.com/api/doc/90000/90135/90236) [详见获取教程文档](https://note.youdao.com/ynoteshare1/index.html?id=351e08a72378206f9dd64d2281e9b83b) |
67 | | `IGOT_PUSH_KEY` | iGot推送 | 非必须 | iGot聚合推送,支持多方式推送,确保消息可达。 [参考文档](https://wahao.github.io/Bark-MP-helper ) |
68 | | `PUSH_PLUS_TOKEN` | pushplus推送 | 非必须 | 微信扫码登录后一对一推送或一对多推送下面的token(您的Token) [官方网站](https://www.pushplus.plus/) |
69 | | `PUSH_PLUS_USER` | pushplus推送 | 非必须 | 一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码)注:(1、需订阅者扫描二维码 2、如果您是创建群组所属人,也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送),只填`PUSH_PLUS_TOKEN`默认为一对一推送 |
70 | | `TG_PROXY_HOST` | Telegram 代理的 IP | 非必须 | 代理类型为 http。例子:http代理 http://127.0.0.1:1080 则填写 127.0.0.1 |
71 | | `TG_PROXY_PORT` | Telegram 代理的端口 | 非必须 | 例子:http代理 http://127.0.0.1:1080 则填写 1080 |
72 |
73 | ### 同步Fork后的代码
74 |
75 | #### 手动同步
76 |
77 | [手动同步 https://blog.blueskyclouds.com/jsfx/58.html](https://blog.blueskyclouds.com/jsfx/58.html)
78 |
79 | #### 自动同步
80 |
81 | ##### 方案A - 强制远程分支覆盖自己的分支
82 | 1. 参考[这里](https://github.com/BlueskyClouds/My-Actions/blob/master/backUp/gitSync.md),安装[pull插件](https://github.com/apps/pull),并确认此项目已在pull插件的作用下(参考文中1-d)。
83 | 2. 确保.github/pull.yml文件正常存在,yml内上游作者填写正确(此项目已填好,无需更改)。
84 | 3. 确保pull.yml里面是`mergeMethod: hardreset`(默认就是hardreset)。
85 | 4. ENJOY!上游更改三小时左右就会自动发起同步。
86 |
87 | ##### 方案B - 保留自己分支的修改
88 |
89 | > 上游变动后pull插件会自动发起pr,但如果有冲突需要自行**手动**确认。
90 | > 如果上游更新涉及workflow里的文件内容改动,需要自行**手动**确认。
91 |
92 | 1. 参考[这里](https://github.com/BlueskyClouds/My-Actions/blob/master/backUp/gitSync.md),安装[pull插件](https://github.com/apps/pull),并确认此项目已在pull插件的作用下(参考文中1-d)。
93 | 2. 确保.github/pull.yml文件正常存在,yml内上游作者填写正确(此项目已填好,无需更改)。
94 | 3. 将pull.yml里面的`mergeMethod: hardreset`修改为`mergeMethod: merge`保存。
95 | 4. ENJOY!上游更改三小时左右就会自动发起同步。
96 |
97 | ### 鸣谢
98 |
99 | 特别感谢 [JetBrains](https://www.jetbrains.com/?from=My-Actions) 为开源项目提供免费的 [WebStrom](https://www.jetbrains.com/?from=My-Actions) 等 IDE 的授权
100 | [
](https://www.jetbrains.com/?from=My-Actions)
101 |
102 | ### 历史 Star 数
103 | 
104 | ### 访问量
105 |
106 | 
107 |
--------------------------------------------------------------------------------
/RepoSync.md:
--------------------------------------------------------------------------------
1 | # 通过reposync方式进行代码同步
2 |
3 | ## Why
4 |
5 | 如果不想fork,通过下面的方法重新创建分支,同步代码
6 |
7 | 此方式亲测可行,请放心食用
8 |
9 | 当然别忘了对源仓库进行*Star*
10 |
11 | ## How
12 |
13 | ### 创建新仓库
14 |
15 | [点击创建自己的仓库](https://github.com/new)
16 |
17 | 填入`Repository name`后点击最下方的`Create repository`即可完成创建
18 |
19 | 如默认分支非`master`请自行修改`repo_sync.yml`的`destination_branch`或新建master分支并设置为默认分支
20 | *Settings* -> *Branch* -> 重命名分支为`master`即可
21 |
22 | ### 自己创建工作流
23 |
24 | 在创建完成页面点击`Actions`再点击`set up a workflow yourself`
25 |
26 |
27 |
28 | 复制https://github.com/BlueskyClouds/My-Actions/blob/master/.github/workflows/repo_sync.yml 里面的代码
29 |
30 | 复制完毕后直接点击右上角的`Start commit`后直接`Commit new file`即可
31 |
32 |
33 |
34 | ### 申请PAT
35 |
36 | 点击 GitHub [用户设置页面](https://github.com/settings) 最下方的`Developer setting` ,然后选择 [`Personal access tokens`(点击快捷到达指定页面)](https://github.com/settings/tokens/new) 来生成一个 token,把 `repo`和`workflow` 两部分勾上即可。
37 |
38 | 
39 |
40 | 点击最下面的创建按钮后,图示部分即为你的PAT(图示的已经删除了,仅为演示),复制下来马上就要使用了
41 |
42 | 
43 |
44 |
45 |
46 | ### 填写PAT到Secrets
47 |
48 | 申请完毕后,在分支中点击`Settings`-`Secrets`-`New secret`
49 |
50 |
51 |
52 | `name`填`PAT`,`Value`填入上方申请到的PAT,保存即可
53 |
54 | 
55 |
56 |
57 |
58 | ### 手动触发一次代码同步
59 |
60 | 点击`Actions`,找到指定的脚本,按图示运行一次
61 |
62 | 
63 |
64 | 等待两分钟左右,能够发现代码全部同步过来了
65 |
66 | 
67 |
68 | ## Enjoy
69 |
70 | 操作到这一步,表示您已经全部完成了
71 |
72 | 剩下的去配置cookie等secrets就好啦
--------------------------------------------------------------------------------
/backUp/TG_PUSH.md:
--------------------------------------------------------------------------------
1 | **TG_PUSH教程**
2 |
3 | 利用Telegram机器人推送通知,需要在环境变量填入正确的```TG_BOT_TOKEN```以及```TG_USER_ID```,以下教程简明阐述如何获取token以及UserID
4 |
5 | Ⅰ.首先在Telegram上搜索[BotFather](https://t.me/BotFather)机器人
6 |
7 | 
8 |
9 | Ⅱ.利用[BotFather](https://t.me/BotFather)创建一个属于自己的通知机器人,按照下图中的1、2、3步骤拿到token,格式形如```10xxx4:AAFcqxxxxgER5uw```。填入```TG_BOT_TOKEN```
10 |
11 | 
12 |
13 | **新创建的机器人需要跟它发一条消息来开启对话,否则可能会遇到secret填对了但是收不到消息的情况**
14 |
15 | Ⅲ.再次在Telegram上搜索[getuserIDbot](https://t.me/getuserIDbot)机器人,获取UserID。填入```TG_USER_ID```
16 |
17 | 
18 |
19 | 至此,获取**TG_BOT_TOKEN**以及**TG_USER_ID**的教程结束
20 |
--------------------------------------------------------------------------------
/backUp/gitSync.md:
--------------------------------------------------------------------------------
1 | ## 保持自己github的forks自动和上游仓库同步的教程
2 | - 信息来源于 [https://github.com/wei/pull](https://github.com/wei/pull)
3 | - 以下教程仅是出于个人爱好,不保证本教程的完全正确性,最终请以作者 [https://github.com/wei/pull](https://github.com/wei/pull) 的描述为准。
4 | - 注:此教程由telegram用户@wukongdada提供
5 | ### 1、只同步默认分支的教程
6 |
7 | > 当上游的仓库仅有一个默认分支。或者上游仓库有两个分支,我们仅需要同步他的默认分支,其他分支对内容对我们来说无关紧要。
8 |
9 |
10 | 
11 |
12 |
13 |
14 | a) 登录自己的github账号,另开网页打开 [https://github.com/wei/pull](https://github.com/wei/pull)
15 |
16 |
17 |
18 | b) 点击Pull app进行安装。
19 |
20 | 
21 |
22 |
23 |
24 | c) 安装过程中会让你选择要选择那一种方式,All repositories(就是同步已经frok的仓库以及未来fork的仓库),Only select repositories(仅选择要自己需要同步的仓库,其他fork的仓库不会被同步),根据自己需求选择,实在不知道怎么选择,就选All repositories;点击install,完成安装。
25 |
26 | 
27 |
28 |
29 |
30 | d) 后续,如果要调整1.c中的选项,打开 [https://github.com/apps/pull](https://github.com/apps/pull) ,点击Configure,输入github密码进入pull的相关设置。
31 |
32 | 
33 |
34 |
35 |
36 | e) 进入后,找到Repository access,根据自己的需求,重新选择:All repositories(就是同步已经frok的仓库以及未来fork的仓库),Only select repositories(仅选择要自己需要同步的仓库,其他fork的仓库不会被同步),Save后保存生效。
37 |
38 | 
39 |
40 |
41 |
42 | f) Pull app作者虽然在项目中写道keeps your forks up-to-date with upstream via automated pull requests,但当上游仓库有更改时,自己的仓库会在3个小时内完成与上游的同步,3个小时是Pull app作者说的最长时间。当然也可以通过手动触发同步上游仓库,手动触发方式:`https://pull.git.ci/process/你的GitHub名字/你的仓库名字` (例如:`https://pull.git.ci/process/xxxxx/test` ),手动触发可能会进行人机验证,验证通过后会显示Success。
43 |
44 | 
45 |
46 | 
47 |
48 | ### 2、同步其他分支的教程
49 |
50 | 
51 |
52 |
53 |
54 | a) 假设你fork了上游仓库后,你fork后的地址为 `https://github.com/你的仓库名字/test` ,首先设置完成第1部分内容,注意在1.c步骤没有设置全部同步的,要回到1.e步,确认是否设置同步了 `你的仓库名字/test`,如果没有,请添加上。
55 |
56 | 
57 |
58 |
59 |
60 | b) 在默认分支下添加一个文件。
61 |
62 | 
63 |
64 |
65 |
66 | c) 复制 ``.github/pull.yml`` 粘贴后看到以下页面,注意github前面的那个.别漏掉了。
67 |
68 | 
69 |
70 |
71 |
72 | d) 请在https://github.com/wei/pull#most-common 页复制代码,
73 |
74 | 注意:upstream处要修改为上游仓库作者名字。
75 |
76 | 
77 |
78 | 
79 |
80 |
81 |
82 | e) 最终的示例如下,假设上游作者是zhangsan,所有的注意点都用红线圈出来了,保存后生效。
83 |
84 | 
85 |
86 |
87 |
88 | f) Pull app作者虽然在项目中写道keeps your forks up-to-date with upstream via automated pull requests,但当上游仓库有更改时,自己的仓库会在3个小时内完成与上游的同步,3个小时是Pull app作者说的最长时间。当然也可以通过手动触发同步上游仓库,手动触发方式:`https://pull.git.ci/process/你的GitHub名字/你的仓库名字` (例如:`https://pull.git.ci/process/xxxxx/test`),手动触发可能会进行人机验证,验证通过后会显示Success。具体见1.f提供的图片。
89 |
90 |
91 |
92 | g) 本人仅测试过forks一个仓库只有2个分支的项目,如果有多个分支,不能保证是否可行,请自行测试,或者是使用本教程第3部分高级玩法。
93 |
94 | ### 高级玩法
95 |
96 | >当然,作者还有其他更好的项目用于同步所有分支,例如使用 GitHub actions 进行同步。请参考原作者的项目
97 | - [https://github.com/wei/git-sync](https://github.com/wei/git-sync)
98 | - [https://github.com/repo-sync/github-sync](https://github.com/repo-sync/github-sync)
--------------------------------------------------------------------------------
/function/10000/10000.js:
--------------------------------------------------------------------------------
1 | // version v0.0.1
2 | // create by BlueSkyClouds
3 | // detail url: https://github.com/BlueskyClouds/My-Actions
4 |
5 | const exec = require('child_process').execSync
6 | const fs = require('fs')
7 | const download = require('download')
8 |
9 | const $ = new Env('中国电信签到');
10 | const notify = $.isNode() ? require('../sendNotify') : '';
11 | // 公共变量
12 | const KEY = process.env.TELECOM_MOBILE
13 | const SEND_KEY = process.env.SEND_KEY
14 | const UTC8 = new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000;
15 |
16 | async function downFile () {
17 | const url = 'https://raw.githubusercontent.com/chavyleung/scripts/master/10000/10000.js'
18 | await download(url, './')
19 | }
20 |
21 | async function changeFiele () {
22 | let content = await fs.readFileSync('./10000.js', 'utf8')
23 | //替换各种无用信息.
24 | content = content.replace("\"\\n\"", "\"\"")
25 | content = content.replace("中国电信", ``)
26 | content = content.replace(/==============\\ud83d\\udce3\\u7cfb\\u7edf\\u901a\\u77e5\\ud83d\\udce3==============/, ``)
27 | content = content.replace("\\ud83d\\udd14${this.name}, \\u5f00\\u59cb!", ``)
28 | content = content.replace("\\ud83d\\udd14${this.name}, \\u7ed3\\u675f! \\ud83d\\udd5b ${e} \\u79d2", ``)
29 |
30 | content = content.replace("const phonedat = $.getdata($.KEY_mobile)", `const phonedat = '${KEY}'`)
31 | await fs.writeFileSync( './10000.js', content, 'utf8')
32 | }
33 |
34 | async function deleteFile(path) {
35 | // 查看文件result.txt是 否存在,如果存在,先删除
36 | const fileExists = await fs.existsSync(path);
37 | // console.log('fileExists', fileExists);
38 | if (fileExists) {
39 | const unlinkRes = await fs.unlinkSync(path);
40 | // console.log('unlinkRes', unlinkRes)
41 | }
42 | }
43 |
44 | async function start() {
45 | if (!KEY) {
46 | console.log('请填写电信号码后再继续')
47 | return
48 | }
49 | // 下载最新代码
50 | await downFile();
51 | console.log('下载代码完毕')
52 | // 替换变量
53 | await changeFiele();
54 | console.log('替换变量完毕')
55 | // 执行
56 | await exec("node 10000.js >> result.txt");
57 | console.log('执行完毕')
58 | const path = "./result.txt";
59 | let content = "";
60 | if (fs.existsSync(path)) {
61 | content = fs.readFileSync(path, "utf8");
62 | }
63 |
64 | if (content.includes("签到成功") | content.includes("已签到")) {
65 | console.log("电信签到-" + content)
66 | }else{
67 | await notify.sendNotify("中国电信签到-" + timeFormat(UTC8), content);
68 | console.log("中国电信签到-" + content)
69 | }
70 |
71 | //运行完成后,删除下载的文件
72 | console.log('运行完成后,删除下载的文件\n')
73 | await deleteFile(path);
74 |
75 | }
76 |
77 | start()
78 |
79 | function timeFormat(time) {
80 | let date;
81 | if (time) {
82 | date = new Date(time)
83 | } else {
84 | date = new Date();
85 | }
86 | return date.getFullYear() + '年' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '月' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()) + '日';
87 | }
88 | // prettier-ignore
89 | function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),a={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(a,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:i,...r}=t;this.got[s](i,r).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${s} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)}
90 |
--------------------------------------------------------------------------------
/function/bika/bika.py:
--------------------------------------------------------------------------------
1 | import random
2 | import string
3 | import sys
4 |
5 | sys.path.append("My-Actions/function/bika/")
6 | from sendNotify import *
7 | from http import client
8 |
9 | sendNotify = sendNotify()
10 |
11 | SEND_KEY = os.environ['SEND_KEY']
12 |
13 | msg = ''
14 |
15 | # noinspection SpellCheckingInspection
16 | pica_api_host = "picaapi.picacomic.com"
17 | pica_api_base_url = "https://%s/" % pica_api_host
18 | sign_in_path = "auth/sign-in"
19 | punch_in_path = "users/punch-in"
20 | POST = "POST"
21 |
22 | # noinspection SpellCheckingInspection
23 | api_key = "C69BAF41DA5ABD1FFEDC6D2FEA56B"
24 | api_secret = "~d}$Q7$eIni=V)9\\RK/P.RM4;9[7|@/CA}b~OW!3?EV`:<>M7pddUBL5n|0/*Cn"
25 | # noinspection SpellCheckingInspection
26 | static_headers = {
27 | "api-key": api_key,
28 | "accept": "application/vnd.picacomic.com.v1+json",
29 | "app-channel": "2",
30 | "app-version": "2.2.1.2.3.3",
31 | "app-uuid": "defaultUuid",
32 | "app-platform": "android",
33 | "app-build-version": "44",
34 | "User-Agent": "okhttp/3.8.1",
35 | "image-quality": "original",
36 | }
37 |
38 |
39 | def send_request(path: string, method: string, body: string = None, token: string = None) -> dict:
40 | current_time = str(int(time.time()))
41 | nonce = "".join(random.choices(string.ascii_lowercase + string.digits, k=32))
42 | raw = path + current_time + nonce + method + api_key
43 | raw = raw.lower()
44 | h = hmac.new(api_secret.encode(), digestmod=hashlib.sha256)
45 | h.update(raw.encode())
46 | signature = h.hexdigest()
47 | headers = static_headers.copy()
48 | headers["time"] = current_time
49 | headers["nonce"] = nonce
50 | headers["signature"] = signature
51 | if body is not None:
52 | headers["Content-Type"] = "application/json; charset=UTF-8"
53 | if token is not None:
54 | headers["authorization"] = token
55 | connection = client.HTTPSConnection(pica_api_host)
56 | connection.request(method, '/' + path, body, headers)
57 | response = connection.getresponse().read().decode("utf-8")
58 | json_object = json.loads(response)
59 | if json_object["code"] != 200:
60 | if SEND_KEY != '':
61 | sendNotify.send(title=u"哔咔漫画自动打哔咔", msg="登录失败 账号或密码错误")
62 | print(json_object["message"])
63 | exit(0)
64 | raise RuntimeError(json_object["message"])
65 | return json_object
66 |
67 |
68 | def sign_in(email: string, password: string) -> string:
69 | body = {
70 | "email": email,
71 | "password": password
72 | }
73 | return send_request(sign_in_path, POST, json.dumps(body))["data"]["token"]
74 |
75 |
76 | def punch_in(token: string):
77 | return send_request(punch_in_path, POST, token=token)
78 |
79 |
80 | if __name__ == '__main__':
81 | if os.environ['BIKA_USER'] == "" or os.environ['BIKA_PASS'] == "":
82 | print("未填写哔咔账号密码 取消运行")
83 | exit(0)
84 | current_token = sign_in(os.environ['BIKA_USER'], os.environ['BIKA_PASS'])
85 | punch_in_response = punch_in(current_token)
86 | result = punch_in_response["data"]["res"]
87 | if result["status"] == "ok":
88 | msg = "打卡成功, 最后一次打卡: %s" % result["punchInLastDay"]
89 | print(msg)
90 | else:
91 | msg = '重复签到 - Already punch-in'
92 | print(msg)
93 |
94 | if SEND_KEY == '':
95 | sendNotify.send(title=u"哔咔漫画自动打哔咔", msg="【哔咔漫画自动签到】\n" + msg)
96 |
--------------------------------------------------------------------------------
/function/bika/sendNotify.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import time
3 | import hmac
4 | import hashlib
5 | import base64
6 | import json
7 | import os
8 | import urllib.parse
9 |
10 |
11 | class sendNotify:
12 | # =======================================微信server酱通知设置区域===========================================
13 | # 此处填你申请的SCKEY.
14 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入PUSH_KEY)
15 | SCKEY = ''
16 |
17 | # =======================================Bark App通知设置区域===========================================
18 | # 此处填你BarkAPP的信息(IP/设备码,例如:https://api.day.app/XXXXXXXX)
19 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_PUSH)
20 | BARK_PUSH = ''
21 | # BARK app推送铃声,铃声列表去APP查看复制填写
22 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_SOUND , Value输入app提供的铃声名称,例如:birdsong)
23 | BARK_SOUND = ''
24 |
25 | # =======================================telegram机器人通知设置区域===========================================
26 | # 此处填你telegram bot 的Token,例如:1077xxx4424:AAFjv0FlexboxEMGfi22B4yh15R5uw
27 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_BOT_TOKEN)
28 | TG_BOT_TOKEN = ''
29 | # 此处填你接收通知消息的telegram用户的id,例如:129xxx206
30 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_USER_ID)
31 | TG_USER_ID = ''
32 |
33 | # =======================================钉钉机器人通知设置区域===========================================
34 | # 此处填你钉钉 bot 的webhook,例如:5a544165465465645d0f31dca676e7bd07415assayed
35 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入DD_BOT_TOKEN)
36 | DD_BOT_TOKEN = ''
37 | # 密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串
38 | DD_BOT_SECRET = ''
39 |
40 | # =======================================企业微信机器人通知设置区域=========================================== 此处填你企业微信机器人的
41 | # webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
42 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QYWX_KEY)
43 | # QYWX_KEY = ''
44 |
45 | # =======================================企业微信应用消息通知设置区域=========================================== 此处填你企业微信应用消息的
46 | # 第一个值是企业id,第二个值是secret,第三个值@all(或者成员id),第四个值是AgentID 中间以逗号隔开
47 | # 详情查看https://note.youdao.com/ynoteshare1/index.html?id=351e08a72378206f9dd64d2281e9b83b&type=note#/
48 | # B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat
49 | QYWX_AM = ''
50 |
51 | # =======================================QQ酷推通知设置区域===========================================
52 | # 此处填你申请的SKEY(具体详见文档 https://cp.xuthus.cc/)
53 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QQ_SKEY)
54 | # QQ_SKEY = ''
55 | # #此处填写私聊或群组推送,默认私聊(send或group或者wx)
56 | # QQ_MODE = 'send'
57 |
58 | # =======================================push+设置区域=======================================
59 | # 官方文档:https://www.pushplus.plus/
60 | # PUSH_PLUS_TOKEN:微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送
61 | PUSH_PLUS_TOKEN = ''
62 | # PUSH_PLUS_USER: 一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)
63 | PUSH_PLUS_USER = ''
64 |
65 | # Server酱
66 | if os.environ['PUSH_KEY'] != "":
67 | SCKEY = os.environ['PUSH_KEY']
68 |
69 | # Bark App
70 | if os.environ['BARK_PUSH'] != "":
71 | if os.environ['BARK_PUSH'].find("https") != -1 or os.environ['BARK_PUSH'].find("http") != -1:
72 | BARK_PUSH = os.environ['PUSH_KEY']
73 | else:
74 | BARK_PUSH = "https://api.day.app/" + os.environ['BARK_PUSH']
75 | elif os.environ['BARK_SOUND'] != "":
76 | BARK_SOUND = os.environ['BARK_SOUND']
77 | elif BARK_PUSH != "" or BARK_PUSH.find("https") != -1 or BARK_PUSH.find("http") != -1:
78 | BARK_PUSH = "https://api.day.app/" + BARK_PUSH
79 |
80 | # telegram
81 | if os.environ['TG_BOT_TOKEN'] != "":
82 | TG_BOT_TOKEN = os.environ['TG_BOT_TOKEN']
83 | if os.environ['TG_USER_ID'] != "":
84 | TG_USER_ID = os.environ['TG_USER_ID']
85 |
86 | # 钉钉机器人
87 | if os.environ['DD_BOT_TOKEN'] != "":
88 | DD_BOT_TOKEN = os.environ['DD_BOT_TOKEN']
89 | if os.environ['DD_BOT_SECRET'] != "":
90 | DD_BOT_SECRET = os.environ['DD_BOT_SECRET']
91 |
92 | # QQ酷推
93 | # if os.environ['QQ_SKEY'] != "":
94 | # QQ_SKEY = os.environ['QQ_SKEY']
95 | # if os.environ['QQ_MODE'] != "":
96 | # QQ_MODE = os.environ['QQ_MODE']
97 |
98 | # 企业微信
99 | # if os.environ['QYWX_KEY'] != "":
100 | # QQ_SKEY = os.environ['QYWX_KEY']
101 | if os.environ['QYWX_AM'] != "":
102 | QYWX_AM = os.environ['QYWX_AM']
103 |
104 | # push+
105 | if os.environ['PUSH_PLUS_TOKEN'] != "":
106 | PUSH_PLUS_TOKEN = os.environ['PUSH_PLUS_TOKEN']
107 | if os.environ['PUSH_PLUS_USER'] != "":
108 | PUSH_PLUS_USER = os.environ['PUSH_PLUS_USER']
109 |
110 | def serverNotify(self, text, desp):
111 | if sendNotify.SCKEY != '':
112 | url = 'https://sctapi.ftqq.com/' + sendNotify.SCKEY + '.send'
113 | if "\n" in desp:
114 | desp = desp.replace("\n", "\n\n")
115 | data = {
116 | 'text': text,
117 | 'desp': desp
118 | }
119 | response = json.dumps(requests.post(url, data).json(), ensure_ascii=False)
120 | datas = json.loads(response)
121 | # print(datas)
122 | if datas['code'] == 0:
123 | print('\nserver酱发送通知消息成功\n')
124 | elif datas['code'] == 40001:
125 | print('\nPUSH_KEY 错误\n')
126 | else:
127 | print('\n发送通知调用API失败!!\n')
128 | else:
129 | print('\n您未提供server酱的SCKEY,取消微信推送消息通知\n')
130 | pass
131 |
132 | def BarkNotify(self, text, desp):
133 | if sendNotify.BARK_PUSH != '':
134 | url = sendNotify.BARK_PUSH + '/' + urllib.parse.quote(text) + '/' + urllib.parse.quote(
135 | desp) + '?sound=' + sendNotify.BARK_SOUND
136 | headers = {'Content-type': "application/x-www-form-urlencoded"}
137 | response = json.dumps(requests.get(url, headers=headers).json(), ensure_ascii=False)
138 | data = json.loads(response)
139 | # print(data)
140 | if data['code'] == 400:
141 | print('\n找不到 Key 对应的 DeviceToken\n')
142 | elif data['code'] == 200:
143 | print('\nBark APP发送通知消息成功\n')
144 | else:
145 | print('\nBark APP发送通知调用API失败!!\n')
146 | print(data)
147 | else:
148 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
149 | pass
150 |
151 | def tgBotNotify(self, text, desp):
152 | if sendNotify.TG_BOT_TOKEN != '' or sendNotify.TG_USER_ID != '':
153 |
154 | url = 'https://api.telegram.org/bot' + sendNotify.TG_BOT_TOKEN + '/sendMessage'
155 | headers = {'Content-type': "application/x-www-form-urlencoded"}
156 | body = 'chat_id=' + sendNotify.TG_USER_ID + '&text=' + urllib.parse.quote(
157 | text) + '\n\n' + urllib.parse.quote(desp) + '&disable_web_page_preview=true'
158 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
159 |
160 | data = json.loads(response)
161 | if data['ok']:
162 | print('\nTelegram发送通知消息完成\n')
163 | elif data['error_code'] == 400:
164 | print('\n请主动给bot发送一条消息并检查接收用户ID是否正确。\n')
165 | elif data['error_code'] == 401:
166 | print('\nTelegram bot token 填写错误。\n')
167 | else:
168 | print('\nTelegram bot发送通知调用API失败!!\n')
169 | print(data)
170 | else:
171 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
172 | pass
173 |
174 | def dingNotify(self, text, desp):
175 | if sendNotify.DD_BOT_TOKEN != '':
176 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN
177 | data = {
178 | "msgtype": "text",
179 | "text": {
180 | 'content': text + desp
181 | }
182 | }
183 | headers = {
184 | 'Content-Type': 'application/json;charset=utf-8'
185 | }
186 | if sendNotify.DD_BOT_SECRET != '':
187 | timestamp = str(round(time.time() * 1000))
188 | secret = sendNotify.DD_BOT_SECRET
189 | secret_enc = secret.encode('utf-8')
190 | string_to_sign = '{}\n{}'.format(timestamp, secret)
191 | string_to_sign_enc = string_to_sign.encode('utf-8')
192 | hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
193 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
194 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN + '×tamp=' + timestamp + '&sign=' + sign
195 |
196 | response = requests.post(url=url, data=json.dumps(data), headers=headers).text
197 | if json.loads(response)['errcode'] == 0:
198 | print('\n钉钉发送通知消息成功\n')
199 | else:
200 | print('\n钉钉发送通知失败!!\n')
201 | else:
202 | print('\n您未提供钉钉的有关数据,取消钉钉推送消息通知\n')
203 | pass
204 |
205 | # def coolpush(self, text, desp):
206 | # if sendNotify.QQ_SKEY != '':
207 | # url = "https://push.xuthus.cc/" + sendNotify.QQ_MODE + "/" + sendNotify.QQ_SKEY
208 | # params = {"c": desp, "t": text}
209 | # headers = {'content-type': 'charset=utf8'}
210 | # response = json.dumps(requests.post(url=url, params=params, headers=headers).json(),ensure_ascii=False)
211 | # datas = json.loads(response)
212 | #
213 | # if datas['code'] == 200:
214 | # print('\nQQ推送发送通知消息成功\n')
215 | # elif datas['code'] == 500:
216 | # print('\nQQ推送QQ_SKEY错误\n')
217 | # else:
218 | # print('\n发送通知调用API失败!!\n')
219 | #
220 | # else:
221 | # print('\n您未提供酷推的SKEY,取消QQ推送消息通知\n')
222 | # pass
223 | def pushNotify(self, text, desp):
224 | if sendNotify.PUSH_PLUS_TOKEN != '':
225 | url = 'http://www.pushplus.plus/send'
226 | data = {
227 | "token": sendNotify.PUSH_PLUS_TOKEN,
228 | "title": text,
229 | "content": desp
230 | }
231 | if sendNotify.PUSH_PLUS_USER != '':
232 | data = {
233 | "token": sendNotify.PUSH_PLUS_TOKEN,
234 | "title": text,
235 | "content": desp,
236 | "topic": sendNotify.PUSH_PLUS_USER,
237 | "template": "html"
238 | }
239 | body = json.dumps(data).encode(encoding='utf-8')
240 | headers = {'Content-Type': 'application/json'}
241 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
242 | datas = json.loads(response)
243 | if datas['code'] == 200:
244 | print('\npush+发送通知消息成功\n')
245 | if datas['code'] == 600:
246 | print('\nPUSH_PLUS_TOKEN 错误\n')
247 | else:
248 | print('\npush+发送通知调用API失败!!\n')
249 | else:
250 | print('\n您未提供push+的PUSH_PLUS_TOKEN,取消push+推送消息通知\n')
251 | pass
252 |
253 | # 企业微信推送
254 | def sendWechat(self, desp):
255 | if sendNotify.QYWX_AM != '':
256 | # 获得access_token
257 | url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
258 | token_param = '?corpid=' + sendNotify.QYWX_AM.split(',')[0] + '&corpsecret=' + sendNotify.QYWX_AM.split(',')[1]
259 | token_data = requests.get(url + token_param)
260 | token_data.encoding = 'utf-8'
261 | token_data = token_data.json()
262 | access_token = token_data['access_token']
263 | #发送内容
264 | content = desp
265 | #创建要发送的消息
266 | data = {
267 | "touser": sendNotify.QYWX_AM.split(',')[2],
268 | "msgtype": "text",
269 | "agentid": sendNotify.QYWX_AM.split(',')[3],
270 | "text": {"content": content}
271 | }
272 | send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + access_token
273 | message = requests.post(send_url, json=data)
274 | message.encoding = 'utf-8'
275 | res = message.json()
276 | print('企业微信推送 : ' + res['errmsg'])
277 | else:
278 | print('\n您未提供企业微信的QYWX_AM,取消企业微信推送消息通知\n')
279 | pass
280 |
281 | def send(self, **kwargs):
282 | send = sendNotify()
283 | title = kwargs.get("title", "")
284 | msg = kwargs.get("msg", "")
285 | send.serverNotify(title, msg)
286 | send.BarkNotify(title, msg)
287 | send.tgBotNotify(title, msg)
288 | send.dingNotify(title, msg)
289 | send.pushNotify(title, msg)
290 | send.sendWechat(msg)
291 | # send.coolpush(title,msg)
292 |
293 | # if __name__ == "__main__":
294 | # send(title = '这是标题',msg = '这是内容')
295 |
--------------------------------------------------------------------------------
/function/bilibili/bilibili.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import sys
3 | sys.path.append("My-Actions/function/bilibili/")
4 | from bilibiliapi import *
5 | from sendNotify import *
6 |
7 | sendNotify = sendNotify()
8 | SEND_KEY = os.environ['SEND_KEY']
9 | BILI_COOKIE = os.environ['BILI_COOKIE'].replace(" ", "")
10 |
11 | class BiliBiliCheckIn(object):
12 | # 待测试,需要大会员账号测试领取福利
13 | def __init__(self, bilibili_cookie_list):
14 | self.bilibili_cookie_list = bilibili_cookie_list
15 |
16 | @staticmethod
17 | def get_nav(session):
18 | url = "https://api.bilibili.com/x/web-interface/nav"
19 | ret = session.get(url=url).json()
20 | # print(ret) #取消本段输出
21 | uname = ret.get("data", {}).get("uname")
22 | uid = ret.get("data", {}).get("mid")
23 | is_login = ret.get("data", {}).get("isLogin")
24 | coin = ret.get("data", {}).get("money")
25 | vip_type = ret.get("data", {}).get("vipType")
26 | current_exp = ret.get("data", {}).get("level_info", {}).get("current_exp")
27 | return uname, uid, is_login, coin, vip_type, current_exp
28 |
29 | @staticmethod
30 | def reward(session) -> dict:
31 | """取B站经验信息"""
32 | url = "https://account.bilibili.com/home/reward"
33 | ret = session.get(url=url).json()
34 | return ret
35 |
36 | @staticmethod
37 | def live_sign(session) -> dict:
38 | """B站直播签到"""
39 | try:
40 | url = "https://api.live.bilibili.com/xlive/web-ucenter/v1/sign/DoSign"
41 | ret = session.get(url=url).json()
42 | if ret["code"] == 0:
43 | msg = f'签到成功,{ret["data"]["text"]},特别信息:{ret["data"]["specialText"]},本月已签到{ret["data"]["hadSignDays"]}天'
44 | elif ret["code"] == 1011040:
45 | msg = "今日已签到过,无法重复签到"
46 | else:
47 | msg = f'签到失败,信息为: {ret["message"]}'
48 | except Exception as e:
49 | msg = f"签到异常,原因为{str(e)}"
50 | return msg
51 |
52 | @staticmethod
53 | def manga_sign(session, platform="android") -> dict:
54 | """
55 | 模拟B站漫画客户端签到
56 | """
57 | try:
58 | url = "https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn"
59 | post_data = {"platform": platform}
60 | ret = session.post(url=url, data=post_data).json()
61 | if ret["code"] == 0:
62 | msg = "签到成功"
63 | elif ret["msg"] == "clockin clockin is duplicate":
64 | msg = "今天已经签到过了"
65 | else:
66 | msg = f'签到失败,信息为({ret["msg"]})'
67 | except Exception as e:
68 | msg = f"签到异常,原因为: {str(e)}"
69 | return msg
70 |
71 | @staticmethod
72 | def vip_privilege_receive(session, bili_jct, receive_type: int = 1) -> dict:
73 | """
74 | 领取B站大会员权益
75 | receive_type int 权益类型,1为B币劵,2为优惠券
76 | """
77 | url = "https://api.bilibili.com/x/vip/privilege/receive"
78 | post_data = {"type": receive_type, "csrf": bili_jct}
79 | ret = session.post(url=url, data=post_data).json()
80 | return ret
81 |
82 | @staticmethod
83 | def vip_manga_reward(session) -> dict:
84 | """获取漫画大会员福利"""
85 | url = "https://manga.bilibili.com/twirp/user.v1.User/GetVipReward"
86 | ret = session.post(url=url, json={"reason_id": 1}).json()
87 | return ret
88 |
89 | @staticmethod
90 | def report_task(session, bili_jct, aid: int, cid: int, progres: int = 300) -> dict:
91 | """
92 | B站上报视频观看进度
93 | aid int 视频av号
94 | cid int 视频cid号
95 | progres int 观看秒数
96 | """
97 | url = "http://api.bilibili.com/x/v2/history/report"
98 | post_data = {"aid": aid, "cid": cid, "progres": progres, "csrf": bili_jct}
99 | ret = session.post(url=url, data=post_data).json()
100 | return ret
101 |
102 | @staticmethod
103 | def share_task(session, bili_jct, aid) -> dict:
104 | """
105 | 分享指定av号视频
106 | aid int 视频av号
107 | """
108 | url = "https://api.bilibili.com/x/web-interface/share/add"
109 | post_data = {"aid": aid, "csrf": bili_jct}
110 | ret = session.post(url=url, data=post_data).json()
111 | return ret
112 |
113 | @staticmethod
114 | def get_followings(
115 | session, uid: int, pn: int = 1, ps: int = 50, order: str = "desc", order_type: str = "attention"
116 | ) -> dict:
117 | """
118 | 获取指定用户关注的up主
119 | uid int 账户uid,默认为本账户,非登录账户只能获取20个*5页
120 | pn int 页码,默认第一页
121 | ps int 每页数量,默认50
122 | order str 排序方式,默认desc
123 | order_type 排序类型,默认attention
124 | """
125 | params = {
126 | "vmid": uid,
127 | "pn": pn,
128 | "ps": ps,
129 | "order": order,
130 | "order_type": order_type,
131 | }
132 | url = f"https://api.bilibili.com/x/relation/followings"
133 | ret = session.get(url=url, params=params).json()
134 | return ret
135 |
136 | @staticmethod
137 | def space_arc_search(
138 | session, uid: int, pn: int = 1, ps: int = 100, tid: int = 0, order: str = "pubdate", keyword: str = ""
139 | ) -> dict:
140 | """
141 | 获取指定up主空间视频投稿信息
142 | uid int 账户uid,默认为本账户
143 | pn int 页码,默认第一页
144 | ps int 每页数量,默认50
145 | tid int 分区 默认为0(所有分区)
146 | order str 排序方式,默认pubdate
147 | keyword str 关键字,默认为空
148 | """
149 | params = {
150 | "mid": uid,
151 | "pn": pn,
152 | "ps": ps,
153 | "tid": tid,
154 | "order": order,
155 | "keyword": keyword,
156 | }
157 | url = f"https://api.bilibili.com/x/space/arc/search"
158 | ret = session.get(url=url, params=params).json()
159 | data_list = [
160 | {"aid": one.get("aid"), "cid": 0, "title": one.get("title"), "owner": one.get("author")}
161 | for one in ret.get("data", {}).get("list", {}).get("vlist", [])
162 | ]
163 | return data_list
164 |
165 | @staticmethod
166 | def elec_pay(session, bili_jct, uid: int, num: int = 50) -> dict:
167 | """
168 | 用B币给up主充电
169 | uid int up主uid
170 | num int 充电电池数量
171 | """
172 | url = "https://api.bilibili.com/x/ugcpay/trade/elec/pay/quick"
173 | post_data = {"elec_num": num, "up_mid": uid, "otype": "up", "oid": uid, "csrf": bili_jct}
174 | ret = session.post(url=url, data=post_data).json()
175 | return ret
176 |
177 | @staticmethod
178 | def coin_add(session, bili_jct, aid: int, num: int = 1, select_like: int = 1) -> dict:
179 | """
180 | 给指定 av 号视频投币
181 | aid int 视频av号
182 | num int 投币数量
183 | select_like int 是否点赞
184 | """
185 | url = "https://api.bilibili.com/x/web-interface/coin/add"
186 | post_data = {
187 | "aid": aid,
188 | "multiply": num,
189 | "select_like": select_like,
190 | "cross_domain": "true",
191 | "csrf": bili_jct,
192 | }
193 | ret = session.post(url=url, data=post_data).json()
194 |
195 | return ret
196 |
197 | @staticmethod
198 | def live_status(session) -> dict:
199 | """B站直播获取金银瓜子状态"""
200 | url = "https://api.live.bilibili.com/pay/v1/Exchange/getStatus"
201 | ret = session.get(url=url).json()
202 | data = ret.get("data")
203 | silver = data.get("silver", 0)
204 | gold = data.get("gold", 0)
205 | coin = data.get("coin", 0)
206 | msg = f"银瓜子数量: {silver}\n金瓜子数量: {gold}\n硬币数量: {coin}"
207 | return msg
208 |
209 | @staticmethod
210 | def silver2coin(session, bili_jct) -> dict:
211 | """银瓜子兑换硬币"""
212 | url = "https://api.live.bilibili.com/pay/v1/Exchange/silver2coin"
213 | post_data = {"csrf_token": bili_jct}
214 | ret = session.post(url=url, data=post_data).json()
215 | return ret
216 |
217 | @staticmethod
218 | def get_region(session, rid=1, num=6) -> dict:
219 | """
220 | 获取 B站分区视频信息
221 | rid int 分区号
222 | num int 获取视频数量
223 | """
224 | url = "https://api.bilibili.com/x/web-interface/dynamic/region?ps=" + str(num) + "&rid=" + str(rid)
225 | ret = session.get(url=url).json()
226 | data_list = [
227 | {
228 | "aid": one.get("aid"),
229 | "cid": one.get("cid"),
230 | "title": one.get("title"),
231 | "owner": one.get("owner", {}).get("name"),
232 | }
233 | for one in ret.get("data", {}).get("archives", [])
234 | ]
235 | return data_list
236 |
237 | def main(self):
238 | msg_list = []
239 | bilibili_cookie = self.bilibili_cookie_list
240 | bili_jct = bilibili_cookie.get("bili_jct")
241 |
242 | if os.environ['BILI_NUM'] == "":
243 | coin_num = 0 # 投币数量
244 | else:
245 | coin_num = int(os.environ['BILI_NUM'])
246 |
247 | if os.environ['BILI_TYPE'] == "":
248 | coin_type = 1 # 投币方式 默认为 1 ;1: 为关注用户列表视频投币 0: 为随机投币。如果关注用户发布的视频不足配置的投币数,则剩余部分使用随机投币
249 | else:
250 | coin_type = int(os.environ['BILI_TYPE'])
251 |
252 | silver2coin = True #是否开启银瓜子换硬币,默认为 True 开启
253 | session = requests.session()
254 | requests.utils.add_dict_to_cookiejar(session.cookies, bilibili_cookie)
255 | session.headers.update(
256 | {
257 | "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/63.0.3239.108",
258 | "Referer": "https://www.bilibili.com/",
259 | "Connection": "keep-alive",
260 | }
261 | )
262 | success_count = 0
263 | uname, uid, is_login, coin, vip_type, current_exp = self.get_nav(session=session)
264 | # print(uname, uid, is_login, coin, vip_type, current_exp)
265 | if is_login:
266 | manhua_msg = self.manga_sign(session=session)
267 | print(manhua_msg)
268 | live_msg = self.live_sign(session=session)
269 | print(live_msg)
270 | aid_list = self.get_region(session=session)
271 | reward_ret = self.reward(session=session)
272 | # print(reward_ret) # 取消本段输出
273 | coins_av_count = reward_ret.get("data", {}).get("coins_av") // 10
274 | coin_num = coin_num - coins_av_count
275 | coin_num = coin_num if coin_num < coin else coin
276 | print(coin_num)
277 | if coin_type == 1 and coin_num:
278 | following_list = self.get_followings(session=session, uid=uid)
279 | for following in following_list.get("data", {}).get("list"):
280 | mid = following.get("mid")
281 | if mid:
282 | aid_list += self.space_arc_search(session=session, uid=mid)
283 | if coin_num > 0:
284 | for aid in aid_list[::-1]:
285 | # print(f'成功给{aid.get("title")}投一个币')
286 | # coin_num -= 1
287 | # success_count += 1
288 | ret = self.coin_add(session=session, aid=aid.get("aid"), bili_jct=bili_jct)
289 | if ret["code"] == 0:
290 | coin_num -= 1
291 | print(f'成功给{aid.get("title")}投一个币')
292 | success_count += 1
293 | elif ret["code"] == 34005:
294 | print(f'投币{aid.get("title")}失败,原因为{ret["message"]}')
295 | continue
296 | # -104 硬币不够了 -111 csrf 失败 34005 投币达到上限
297 | else:
298 | print(f'投币{aid.get("title")}失败,原因为{ret["message"]},跳过投币')
299 | break
300 | if coin_num <= 0:
301 | break
302 | coin_msg = f"今日成功投币{success_count + coins_av_count}/{coin_num}个"
303 | print(coin_msg)
304 | else:
305 | coin_msg = f"今日成功投币{coins_av_count}/{coin_type}个"
306 | print(coin_msg)
307 | aid = aid_list[0].get("aid")
308 | cid = aid_list[0].get("cid")
309 | title = aid_list[0].get("title")
310 | report_ret = self.report_task(session=session, bili_jct=bili_jct, aid=aid, cid=cid)
311 | if report_ret.get("code") == 0:
312 | report_msg = f"观看《{title}》300秒"
313 | else:
314 | report_msg = f"任务失败"
315 | print(report_msg)
316 | share_ret = self.share_task(session=session, bili_jct=bili_jct, aid=aid)
317 | if share_ret.get("code") == 0:
318 | share_msg = f"分享《{title}》成功"
319 | else:
320 | share_msg = f"分享失败"
321 | print(share_msg)
322 | if silver2coin:
323 | silver2coin_ret = self.silver2coin(session=session, bili_jct=bili_jct)
324 | if silver2coin_ret["code"] == 0:
325 | silver2coin_msg = f"成功将银瓜子兑换为1个硬币"
326 | else:
327 | silver2coin_msg = silver2coin_ret["msg"]
328 | print(silver2coin_msg)
329 | else:
330 | silver2coin_msg = f"未开启银瓜子兑换硬币功能"
331 | live_stats = self.live_status(session=session)
332 | uname, uid, is_login, new_coin, vip_type, new_current_exp = self.get_nav(session=session)
333 | # print(uname, uid, is_login, new_coin, vip_type, new_current_exp)
334 | reward_ret = self.reward(session=session)
335 | login = reward_ret.get("data", {}).get("login")
336 | watch_av = reward_ret.get("data", {}).get("watch_av")
337 | coins_av = reward_ret.get("data", {}).get("coins_av", 0)
338 | share_av = reward_ret.get("data", {}).get("share_av")
339 | today_exp = len([one for one in [login, watch_av, share_av] if one]) * 5
340 | today_exp += coins_av
341 | update_data = (28800 - new_current_exp) // (today_exp if today_exp else 1)
342 | msg = (
343 | f"【Bilibili签到】\n帐号信息: {uname}\n漫画签到: {manhua_msg}\n直播签到: {live_msg}\n"
344 | f"登陆任务: 今日已登陆\n观看视频: {report_msg}\n分享任务: {share_msg}\n投币任务: {coin_msg}\n"
345 | f"银瓜子兑换硬币: {silver2coin_msg}\n今日获得经验: {today_exp}\n当前经验: {new_current_exp}\n"
346 | f"按当前速度升级还需: {update_data}天\n{live_stats}"
347 | )
348 | print(msg)
349 | if SEND_KEY == '':
350 | sendNotify.send(title = u"哔哩哔哩签到",msg = msg)
351 | msg_list.append(msg)
352 | return msg_list
353 |
354 |
355 | if __name__ == "__main__":
356 | # 未填写参数取消运行
357 | if os.environ['BILI_USER'] == "" or os.environ['BILI_PASS'] == "":
358 | if os.environ['BILI_COOKIE'] == "":
359 | print("未填写哔哩哔哩账号密码或COOKIE取消运行")
360 | exit(0)
361 |
362 | if BILI_COOKIE == "":
363 | b = Bilibili()
364 | login = b.login(username=os.environ['BILI_USER'], password=os.environ['BILI_PASS'])
365 | if login == False:
366 | sendNotify.send(title = u"哔哩哔哩签到", msg = "登录失败 账号或密码错误,详情前往Github查看")
367 | exit(0)
368 | _bilibili_cookie_list = b.get_cookies()
369 | else:
370 | _bilibili_cookie_list = {cookie.split('=')[0]:cookie.split('=')[-1] for cookie in BILI_COOKIE.split(';')}
371 |
372 | BiliBiliCheckIn(bilibili_cookie_list=_bilibili_cookie_list).main()
--------------------------------------------------------------------------------
/function/bilibili/sendNotify.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import time
3 | import hmac
4 | import hashlib
5 | import base64
6 | import json
7 | import os
8 | import urllib.parse
9 |
10 |
11 | class sendNotify:
12 | # =======================================微信server酱通知设置区域===========================================
13 | # 此处填你申请的SCKEY.
14 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入PUSH_KEY)
15 | SCKEY = ''
16 |
17 | # =======================================Bark App通知设置区域===========================================
18 | # 此处填你BarkAPP的信息(IP/设备码,例如:https://api.day.app/XXXXXXXX)
19 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_PUSH)
20 | BARK_PUSH = ''
21 | # BARK app推送铃声,铃声列表去APP查看复制填写
22 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_SOUND , Value输入app提供的铃声名称,例如:birdsong)
23 | BARK_SOUND = ''
24 |
25 | # =======================================telegram机器人通知设置区域===========================================
26 | # 此处填你telegram bot 的Token,例如:1077xxx4424:AAFjv0FlexboxEMGfi22B4yh15R5uw
27 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_BOT_TOKEN)
28 | TG_BOT_TOKEN = ''
29 | # 此处填你接收通知消息的telegram用户的id,例如:129xxx206
30 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_USER_ID)
31 | TG_USER_ID = ''
32 |
33 | # =======================================钉钉机器人通知设置区域===========================================
34 | # 此处填你钉钉 bot 的webhook,例如:5a544165465465645d0f31dca676e7bd07415assayed
35 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入DD_BOT_TOKEN)
36 | DD_BOT_TOKEN = ''
37 | # 密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串
38 | DD_BOT_SECRET = ''
39 |
40 | # =======================================企业微信机器人通知设置区域=========================================== 此处填你企业微信机器人的
41 | # webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
42 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QYWX_KEY)
43 | # QYWX_KEY = ''
44 |
45 | # =======================================企业微信应用消息通知设置区域=========================================== 此处填你企业微信应用消息的
46 | # 第一个值是企业id,第二个值是secret,第三个值@all(或者成员id),第四个值是AgentID 中间以逗号隔开
47 | # 详情查看https://note.youdao.com/ynoteshare1/index.html?id=351e08a72378206f9dd64d2281e9b83b&type=note#/
48 | # B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat
49 | QYWX_AM = ''
50 |
51 | # =======================================QQ酷推通知设置区域===========================================
52 | # 此处填你申请的SKEY(具体详见文档 https://cp.xuthus.cc/)
53 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QQ_SKEY)
54 | # QQ_SKEY = ''
55 | # #此处填写私聊或群组推送,默认私聊(send或group或者wx)
56 | # QQ_MODE = 'send'
57 |
58 | # =======================================push+设置区域=======================================
59 | # 官方文档:https://www.pushplus.plus/
60 | # PUSH_PLUS_TOKEN:微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送
61 | PUSH_PLUS_TOKEN = ''
62 | # PUSH_PLUS_USER: 一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)
63 | PUSH_PLUS_USER = ''
64 |
65 | # Server酱
66 | if os.environ['PUSH_KEY'] != "":
67 | SCKEY = os.environ['PUSH_KEY']
68 |
69 | # Bark App
70 | if os.environ['BARK_PUSH'] != "":
71 | if os.environ['BARK_PUSH'].find("https") != -1 or os.environ['BARK_PUSH'].find("http") != -1:
72 | BARK_PUSH = os.environ['PUSH_KEY']
73 | else:
74 | BARK_PUSH = "https://api.day.app/" + os.environ['BARK_PUSH']
75 | elif os.environ['BARK_SOUND'] != "":
76 | BARK_SOUND = os.environ['BARK_SOUND']
77 | elif BARK_PUSH != "" or BARK_PUSH.find("https") != -1 or BARK_PUSH.find("http") != -1:
78 | BARK_PUSH = "https://api.day.app/" + BARK_PUSH
79 |
80 | # telegram
81 | if os.environ['TG_BOT_TOKEN'] != "":
82 | TG_BOT_TOKEN = os.environ['TG_BOT_TOKEN']
83 | if os.environ['TG_USER_ID'] != "":
84 | TG_USER_ID = os.environ['TG_USER_ID']
85 |
86 | # 钉钉机器人
87 | if os.environ['DD_BOT_TOKEN'] != "":
88 | DD_BOT_TOKEN = os.environ['DD_BOT_TOKEN']
89 | if os.environ['DD_BOT_SECRET'] != "":
90 | DD_BOT_SECRET = os.environ['DD_BOT_SECRET']
91 |
92 | # QQ酷推
93 | # if os.environ['QQ_SKEY'] != "":
94 | # QQ_SKEY = os.environ['QQ_SKEY']
95 | # if os.environ['QQ_MODE'] != "":
96 | # QQ_MODE = os.environ['QQ_MODE']
97 |
98 | # 企业微信
99 | # if os.environ['QYWX_KEY'] != "":
100 | # QQ_SKEY = os.environ['QYWX_KEY']
101 | if os.environ['QYWX_AM'] != "":
102 | QYWX_AM = os.environ['QYWX_AM']
103 |
104 | # push+
105 | if os.environ['PUSH_PLUS_TOKEN'] != "":
106 | PUSH_PLUS_TOKEN = os.environ['PUSH_PLUS_TOKEN']
107 | if os.environ['PUSH_PLUS_USER'] != "":
108 | PUSH_PLUS_USER = os.environ['PUSH_PLUS_USER']
109 |
110 | def serverNotify(self, text, desp):
111 | if sendNotify.SCKEY != '':
112 | url = 'https://sctapi.ftqq.com/' + sendNotify.SCKEY + '.send'
113 | if "\n" in desp:
114 | desp = desp.replace("\n", "\n\n")
115 | data = {
116 | 'text': text,
117 | 'desp': desp
118 | }
119 | response = json.dumps(requests.post(url, data).json(), ensure_ascii=False)
120 | datas = json.loads(response)
121 | # print(datas)
122 | if datas['code'] == 0:
123 | print('\nserver酱发送通知消息成功\n')
124 | elif datas['code'] == 40001:
125 | print('\nPUSH_KEY 错误\n')
126 | else:
127 | print('\n发送通知调用API失败!!\n')
128 | else:
129 | print('\n您未提供server酱的SCKEY,取消微信推送消息通知\n')
130 | pass
131 |
132 | def BarkNotify(self, text, desp):
133 | if sendNotify.BARK_PUSH != '':
134 | url = sendNotify.BARK_PUSH + '/' + urllib.parse.quote(text) + '/' + urllib.parse.quote(
135 | desp) + '?sound=' + sendNotify.BARK_SOUND
136 | headers = {'Content-type': "application/x-www-form-urlencoded"}
137 | response = json.dumps(requests.get(url, headers=headers).json(), ensure_ascii=False)
138 | data = json.loads(response)
139 | # print(data)
140 | if data['code'] == 400:
141 | print('\n找不到 Key 对应的 DeviceToken\n')
142 | elif data['code'] == 200:
143 | print('\nBark APP发送通知消息成功\n')
144 | else:
145 | print('\nBark APP发送通知调用API失败!!\n')
146 | print(data)
147 | else:
148 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
149 | pass
150 |
151 | def tgBotNotify(self, text, desp):
152 | if sendNotify.TG_BOT_TOKEN != '' or sendNotify.TG_USER_ID != '':
153 |
154 | url = 'https://api.telegram.org/bot' + sendNotify.TG_BOT_TOKEN + '/sendMessage'
155 | headers = {'Content-type': "application/x-www-form-urlencoded"}
156 | body = 'chat_id=' + sendNotify.TG_USER_ID + '&text=' + urllib.parse.quote(
157 | text) + '\n\n' + urllib.parse.quote(desp) + '&disable_web_page_preview=true'
158 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
159 |
160 | data = json.loads(response)
161 | if data['ok']:
162 | print('\nTelegram发送通知消息完成\n')
163 | elif data['error_code'] == 400:
164 | print('\n请主动给bot发送一条消息并检查接收用户ID是否正确。\n')
165 | elif data['error_code'] == 401:
166 | print('\nTelegram bot token 填写错误。\n')
167 | else:
168 | print('\nTelegram bot发送通知调用API失败!!\n')
169 | print(data)
170 | else:
171 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
172 | pass
173 |
174 | def dingNotify(self, text, desp):
175 | if sendNotify.DD_BOT_TOKEN != '':
176 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN
177 | data = {
178 | "msgtype": "text",
179 | "text": {
180 | 'content': text + desp
181 | }
182 | }
183 | headers = {
184 | 'Content-Type': 'application/json;charset=utf-8'
185 | }
186 | if sendNotify.DD_BOT_SECRET != '':
187 | timestamp = str(round(time.time() * 1000))
188 | secret = sendNotify.DD_BOT_SECRET
189 | secret_enc = secret.encode('utf-8')
190 | string_to_sign = '{}\n{}'.format(timestamp, secret)
191 | string_to_sign_enc = string_to_sign.encode('utf-8')
192 | hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
193 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
194 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN + '×tamp=' + timestamp + '&sign=' + sign
195 |
196 | response = requests.post(url=url, data=json.dumps(data), headers=headers).text
197 | if json.loads(response)['errcode'] == 0:
198 | print('\n钉钉发送通知消息成功\n')
199 | else:
200 | print('\n钉钉发送通知失败!!\n')
201 | else:
202 | print('\n您未提供钉钉的有关数据,取消钉钉推送消息通知\n')
203 | pass
204 |
205 | # def coolpush(self, text, desp):
206 | # if sendNotify.QQ_SKEY != '':
207 | # url = "https://push.xuthus.cc/" + sendNotify.QQ_MODE + "/" + sendNotify.QQ_SKEY
208 | # params = {"c": desp, "t": text}
209 | # headers = {'content-type': 'charset=utf8'}
210 | # response = json.dumps(requests.post(url=url, params=params, headers=headers).json(),ensure_ascii=False)
211 | # datas = json.loads(response)
212 | #
213 | # if datas['code'] == 200:
214 | # print('\nQQ推送发送通知消息成功\n')
215 | # elif datas['code'] == 500:
216 | # print('\nQQ推送QQ_SKEY错误\n')
217 | # else:
218 | # print('\n发送通知调用API失败!!\n')
219 | #
220 | # else:
221 | # print('\n您未提供酷推的SKEY,取消QQ推送消息通知\n')
222 | # pass
223 | def pushNotify(self, text, desp):
224 | if sendNotify.PUSH_PLUS_TOKEN != '':
225 | url = 'http://www.pushplus.plus/send'
226 | data = {
227 | "token": sendNotify.PUSH_PLUS_TOKEN,
228 | "title": text,
229 | "content": desp
230 | }
231 | if sendNotify.PUSH_PLUS_USER != '':
232 | data = {
233 | "token": sendNotify.PUSH_PLUS_TOKEN,
234 | "title": text,
235 | "content": desp,
236 | "topic": sendNotify.PUSH_PLUS_USER,
237 | "template": "html"
238 | }
239 | body = json.dumps(data).encode(encoding='utf-8')
240 | headers = {'Content-Type': 'application/json'}
241 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
242 | datas = json.loads(response)
243 | if datas['code'] == 200:
244 | print('\npush+发送通知消息成功\n')
245 | if datas['code'] == 600:
246 | print('\nPUSH_PLUS_TOKEN 错误\n')
247 | else:
248 | print('\npush+发送通知调用API失败!!\n')
249 | else:
250 | print('\n您未提供push+的PUSH_PLUS_TOKEN,取消push+推送消息通知\n')
251 | pass
252 |
253 | # 企业微信推送
254 | def sendWechat(self, desp):
255 | if sendNotify.QYWX_AM != '':
256 | # 获得access_token
257 | url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
258 | token_param = '?corpid=' + sendNotify.QYWX_AM.split(',')[0] + '&corpsecret=' + sendNotify.QYWX_AM.split(',')[1]
259 | token_data = requests.get(url + token_param)
260 | token_data.encoding = 'utf-8'
261 | token_data = token_data.json()
262 | access_token = token_data['access_token']
263 | #发送内容
264 | content = desp
265 | #创建要发送的消息
266 | data = {
267 | "touser": sendNotify.QYWX_AM.split(',')[2],
268 | "msgtype": "text",
269 | "agentid": sendNotify.QYWX_AM.split(',')[3],
270 | "text": {"content": content}
271 | }
272 | send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + access_token
273 | message = requests.post(send_url, json=data)
274 | message.encoding = 'utf-8'
275 | res = message.json()
276 | print('企业微信推送 : ' + res['errmsg'])
277 | else:
278 | print('\n您未提供企业微信的QYWX_AM,取消企业微信推送消息通知\n')
279 | pass
280 |
281 | def send(self, **kwargs):
282 | send = sendNotify()
283 | title = kwargs.get("title", "")
284 | msg = kwargs.get("msg", "")
285 | send.serverNotify(title, msg)
286 | send.BarkNotify(title, msg)
287 | send.tgBotNotify(title, msg)
288 | send.dingNotify(title, msg)
289 | send.pushNotify(title, msg)
290 | send.sendWechat(msg)
291 | # send.coolpush(title,msg)
292 |
293 | # if __name__ == "__main__":
294 | # send(title = '这是标题',msg = '这是内容')
295 |
--------------------------------------------------------------------------------
/function/iQIYI-DailyBonus/iQIYI-bak.js:
--------------------------------------------------------------------------------
1 | /*
2 | 爱奇艺会员签到脚本
3 |
4 | 更新时间: 2020.9.6
5 | 脚本兼容: QuantumultX, Surge4, Loon, JsBox, Node.js
6 | 电报频道: @NobyDa
7 | 问题反馈: @NobyDa_bot
8 |
9 | 获取Cookie说明:
10 | 打开爱奇艺App后(AppStore中国区),点击"我的", 如通知成功获取cookie, 则可以使用此签到脚本.
11 | 获取Cookie后, 请将Cookie脚本禁用并移除主机名,以免产生不必要的MITM.
12 | 脚本将在每天上午9:00执行, 您可以修改执行时间。
13 |
14 | 如果使用Node.js, 需自行安装'request'模块. 例: npm install request -g
15 |
16 | JsBox, Node.js用户抓取Cookie说明:
17 | 开启抓包, 打开爱奇艺App后(AppStore中国区),点击"我的" 返回抓包App 搜索请求头关键字 psp_cki= 或 P00001= 或 authcookie=
18 | 提取字母数字混合字段, 到&结束, 填入以下单引号内即可.
19 | */
20 |
21 | var cookie = ''
22 |
23 | /*********************
24 | QuantumultX 远程脚本配置:
25 | **********************
26 | [task_local]
27 | # 爱奇艺会员签到
28 | 0 9 * * * https://raw.githubusercontent.com/NobyDa/Script/master/iQIYI-DailyBonus/iQIYI.js
29 |
30 | [rewrite_local]
31 | # 获取Cookie
32 | ^https?:\/\/iface(\d)?\.iqiyi\.com\/ url script-request-header https://raw.githubusercontent.com/NobyDa/Script/master/iQIYI-DailyBonus/iQIYI.js
33 |
34 | [mitm]
35 | hostname= ifac*.iqiyi.com
36 |
37 | **********************
38 | Surge 4.2.0+ 脚本配置:
39 | **********************
40 | [Script]
41 | 爱奇艺签到 = type=cron,cronexp=0 9 * * *,script-path=https://raw.githubusercontent.com/NobyDa/Script/master/iQIYI-DailyBonus/iQIYI.js
42 |
43 | 爱奇艺获取Cookie = type=http-request,pattern=^https?:\/\/iface(\d)?\.iqiyi\.com\/,script-path=https://raw.githubusercontent.com/NobyDa/Script/master/iQIYI-DailyBonus/iQIYI.js
44 |
45 | [MITM]
46 | hostname= ifac*.iqiyi.com
47 |
48 | ************************
49 | Loon 2.1.0+ 脚本配置:
50 | ************************
51 |
52 | [Script]
53 | # 爱奇艺签到
54 | cron "0 9 * * *" script-path=https://raw.githubusercontent.com/NobyDa/Script/master/iQIYI-DailyBonus/iQIYI.js
55 |
56 | # 获取Cookie
57 | http-request ^https?:\/\/iface(\d)?\.iqiyi\.com\/ script-path=https://raw.githubusercontent.com/NobyDa/Script/master/iQIYI-DailyBonus/iQIYI.js
58 |
59 | [Mitm]
60 | hostname= ifac*.iqiyi.com
61 |
62 | */
63 |
64 | var LogDetails = false; // 响应日志
65 |
66 | var out = 10000; // 超时 (毫秒) 如填写, 则不少于3000
67 |
68 | var $nobyda = nobyda();
69 |
70 | (async () => {
71 | out = $nobyda.read("iQIYI_TimeOut") || out
72 | cookie = cookie || $nobyda.read("CookieQY")
73 | LogDetails = $nobyda.read("iQIYI_LogDetails") === "true" ? true : LogDetails
74 | if ($nobyda.isRequest) {
75 | GetCookie()
76 | } else if (cookie) {
77 | await login();
78 | await Checkin();
79 | await Lottery(500);
80 | await $nobyda.time();
81 | } else {
82 | $nobyda.notify("爱奇艺会员", "", "签到终止, 未获取Cookie");
83 | }
84 | })().finally(() => {
85 | $nobyda.done();
86 | })
87 |
88 | function login() {
89 | return new Promise(resolve => {
90 | var URL = {
91 | url: 'https://cards.iqiyi.com/views_category/3.0/vip_home?secure_p=iPhone&scrn_scale=0&dev_os=0&ouid=0&layout_v=6&psp_cki=' + cookie + '&page_st=suggest&app_k=8e48946f144759d86a50075555fd5862&dev_ua=iPhone8%2C2&net_sts=1&cupid_uid=0&xas=1&init_type=6&app_v=11.4.5&idfa=0&app_t=0&platform_id=0&layout_name=0&req_sn=0&api_v=0&psp_status=0&psp_uid=451953037415627&qyid=0&secure_v=0&req_times=0',
92 | headers: {
93 | sign: '7fd8aadd90f4cfc99a858a4b087bcc3a',
94 | t: '479112291'
95 | }
96 | }
97 | $nobyda.get(URL, function(error, response, data) {
98 | const Details = LogDetails ? data ? `response:\n${data}` : '' : ''
99 | if (!error && data.match(/\"text\":\"\d.+?\u5230\u671f\"/)) {
100 | $nobyda.expire = data.match(/\"text\":\"(\d.+?\u5230\u671f)\"/)[1]
101 | console.log(`爱奇艺-查询成功: ${$nobyda.expire} ${Details}`)
102 | } else {
103 | console.log(`爱奇艺-查询失败${error || ': 无到期数据 ⚠️'} ${Details}`)
104 | }
105 | resolve()
106 | })
107 | if (out) setTimeout(resolve, out)
108 | })
109 | }
110 |
111 | function Checkin() {
112 | return new Promise(resolve => {
113 | var URL = {
114 | url: 'https://tc.vip.iqiyi.com/taskCenter/task/queryUserTask?autoSign=yes&P00001=' + cookie
115 | }
116 | $nobyda.get(URL, function(error, response, data) {
117 | if (error) {
118 | $nobyda.data = "签到失败: 接口请求出错 ‼️"
119 | console.log(`爱奇艺-${$nobyda.data} ${error}`)
120 | } else {
121 | if(!isJSON_test(data)){
122 | return false;
123 | }
124 | const obj = JSON.parse(data)
125 | const Details = LogDetails ? `response:\n${data}` : ''
126 | if (obj.msg === "成功") {
127 | if (obj.data.signInfo.code === "A00000") {
128 | var AwardName = obj.data.signInfo.data.rewards[0].name;
129 | var quantity = obj.data.signInfo.data.rewards[0].value;
130 | var continued = obj.data.signInfo.data.continueSignDaysSum;
131 | $nobyda.data = "签到成功: " + AwardName + quantity + ", 已连签" + continued + "天 🎉"
132 | console.log(`爱奇艺-${$nobyda.data} ${Details}`)
133 | } else {
134 | $nobyda.data = "签到失败: " + obj.data.signInfo.msg + " ⚠️"
135 | console.log(`爱奇艺-${$nobyda.data} ${Details}`)
136 | }
137 | } else {
138 | $nobyda.data = "签到失败: Cookie无效 ⚠️"
139 | console.log(`爱奇艺-${$nobyda.data} ${Details}`)
140 | }
141 | }
142 | resolve()
143 | })
144 | if (out) setTimeout(resolve, out)
145 | })
146 | }
147 |
148 | function Lottery(s) {
149 | return new Promise(resolve => {
150 | $nobyda.times++
151 | const URL = {
152 | url: 'https://iface2.iqiyi.com/aggregate/3.0/lottery_activity?app_k=0&app_v=0&platform_id=0&dev_os=0&dev_ua=0&net_sts=0&qyid=0&psp_uid=0&psp_cki=' + cookie + '&psp_status=0&secure_p=0&secure_v=0&req_sn=0'
153 | }
154 | setTimeout(() => {
155 | $nobyda.get(URL, async function(error, response, data) {
156 | if (error) {
157 | $nobyda.data += "\n抽奖失败: 接口请求出错 ‼️"
158 | console.log(`爱奇艺-抽奖失败: 接口请求出错 ‼️ ${error} (${$nobyda.times})`)
159 | //$nobyda.notify("爱奇艺", "", $nobyda.data)
160 | } else {
161 | const obj = JSON.parse(data);
162 | const Details = LogDetails ? `response:\n${data}` : ''
163 | $nobyda.last = data.match(/(机会|已经)用完/) ? true : false
164 | if (obj.awardName && obj.code === 0) {
165 | $nobyda.data += !$nobyda.last ? `\n抽奖成功: ${obj.awardName.replace(/《.+》/, "未中奖")} 🎉` : `\n抽奖失败: 今日已抽奖 ⚠️`
166 | console.log(`爱奇艺-抽奖明细: ${obj.awardName.replace(/《.+》/, "未中奖")} 🎉 (${$nobyda.times}) ${Details}`)
167 | } else if (data.match(/\"errorReason\"/)) {
168 | msg = data.match(/msg=.+?\)/) ? data.match(/msg=(.+?)\)/)[1].replace(/用户(未登录|不存在)/, "Cookie无效") : ""
169 | $nobyda.data += `\n抽奖失败: ${msg || `未知错误`} ⚠️`
170 | console.log(`爱奇艺-抽奖失败: ${msg || `未知错误`} ⚠️ (${$nobyda.times}) ${msg ? Details : `response:\n${data}`}`)
171 | console.log(data)
172 | s = s + 500;
173 | if(s <= 4500){
174 | await Lottery(s)
175 | }
176 | } else {
177 | $nobyda.data += "\n抽奖错误: 已输出日志 ⚠️"
178 | console.log(`爱奇艺-抽奖失败: \n${data} (${$nobyda.times})`)
179 | }
180 | }
181 | if (!$nobyda.last && $nobyda.times < 3) {
182 | await Lottery(s)
183 | } else {
184 | const expires = $nobyda.expire ? $nobyda.expire.replace(/\u5230\u671f/, "") : "获取失败 ⚠️"
185 | if (!$nobyda.isNode) $nobyda.notify("爱奇艺", "到期时间: " + expires, $nobyda.data)
186 | }
187 | resolve()
188 | })
189 | }, s)
190 | if (out) setTimeout(resolve, out + s)
191 | })
192 | }
193 |
194 | function GetCookie() {
195 | var CKA = $request.url.match(/(psp_cki=|P00001=|authcookie=)([A-Za-z0-9]+)/)
196 | var CKB = JSON.stringify($request.headers).match(/(psp_cki=|P00001=|authcookie=)([A-Za-z0-9]+)/)
197 | var iQIYI = CKA || CKB || null
198 | var RA = $nobyda.read("CookieQY")
199 | if (iQIYI) {
200 | if (RA !== iQIYI[2]) {
201 | var OldTime = $nobyda.read("CookieQYTime")
202 | if (!$nobyda.write(iQIYI[2], "CookieQY")) {
203 | $nobyda.notify(`${RA?`更新`:`首次写入`}爱奇艺签到Cookie失败‼️`, "", "")
204 | } else {
205 | if (!OldTime || OldTime && (Date.now() - OldTime) / 1000 >= 21600) {
206 | $nobyda.write(JSON.stringify(Date.now()), "CookieQYTime")
207 | $nobyda.notify(`${RA?`更新`:`首次写入`}爱奇艺签到Cookie成功 🎉`, "", "")
208 | } else {
209 | console.log(`\n更新爱奇艺Cookie成功! 🎉\n检测到频繁通知, 已转为输出日志`)
210 | }
211 | }
212 | } else {
213 | console.log("\n爱奇艺-与本机储存Cookie相同, 跳过写入 ⚠️")
214 | }
215 | } else {
216 | console.log("\n爱奇艺-请求不含Cookie, 跳过写入 ‼️")
217 | }
218 | }
219 |
220 | function nobyda() {
221 | const times = 0
222 | const start = Date.now()
223 | const isRequest = typeof $request != "undefined"
224 | const isSurge = typeof $httpClient != "undefined"
225 | const isQuanX = typeof $task != "undefined"
226 | const isLoon = typeof $loon != "undefined"
227 | const isJSBox = typeof $app != "undefined" && typeof $http != "undefined"
228 | const isNode = typeof require == "function" && !isJSBox;
229 | const node = (() => {
230 | if (isNode) {
231 | const request = require('request');
232 | return ({
233 | request
234 | })
235 | } else {
236 | return (null)
237 | }
238 | })()
239 | const notify = (title, subtitle, message) => {
240 | if (isQuanX) $notify(title, subtitle, message)
241 | if (isSurge) $notification.post(title, subtitle, message)
242 | if (isNode) log('\n' + title + '\n' + subtitle + '\n' + message)
243 | if (isJSBox) $push.schedule({
244 | title: title,
245 | body: subtitle ? subtitle + "\n" + message : message
246 | })
247 | }
248 | const write = (value, key) => {
249 | if (isQuanX) return $prefs.setValueForKey(value, key)
250 | if (isSurge) return $persistentStore.write(value, key)
251 | }
252 | const read = (key) => {
253 | if (isQuanX) return $prefs.valueForKey(key)
254 | if (isSurge) return $persistentStore.read(key)
255 | }
256 | const adapterStatus = (response) => {
257 | if (response) {
258 | if (response.status) {
259 | response["statusCode"] = response.status
260 | } else if (response.statusCode) {
261 | response["status"] = response.statusCode
262 | }
263 | }
264 | return response
265 | }
266 | const get = (options, callback) => {
267 | if (isQuanX) {
268 | if (typeof options == "string") options = {
269 | url: options
270 | }
271 | options["method"] = "GET"
272 | $task.fetch(options).then(response => {
273 | callback(null, adapterStatus(response), response.body)
274 | }, reason => callback(reason.error, null, null))
275 | }
276 | if (isSurge) $httpClient.get(options, (error, response, body) => {
277 | callback(error, adapterStatus(response), body)
278 | })
279 | if (isNode) {
280 | node.request(options, (error, response, body) => {
281 | callback(error, adapterStatus(response), body)
282 | })
283 | }
284 | if (isJSBox) {
285 | if (typeof options == "string") options = {
286 | url: options
287 | }
288 | options["header"] = options["headers"]
289 | options["handler"] = function(resp) {
290 | let error = resp.error;
291 | if (error) error = JSON.stringify(resp.error)
292 | let body = resp.data;
293 | if (typeof body == "object") body = JSON.stringify(resp.data);
294 | callback(error, adapterStatus(resp.response), body)
295 | };
296 | $http.get(options);
297 | }
298 | }
299 |
300 | const log = (message) => console.log(message)
301 | const time = () => {
302 | const end = ((Date.now() - start) / 1000).toFixed(2)
303 | return console.log('\n签到用时: ' + end + ' 秒')
304 | }
305 | const done = (value = {}) => {
306 | if (isQuanX) return $done(value)
307 | if (isSurge) isRequest ? $done(value) : $done()
308 | }
309 | return {
310 | isRequest,
311 | isNode,
312 | notify,
313 | write,
314 | read,
315 | get,
316 | log,
317 | time,
318 | times,
319 | done
320 | }
321 | };
322 |
323 | function isJSON_test(str) {
324 | if (typeof str == 'string') {
325 | try {
326 | var obj=JSON.parse(str);
327 | //console.log('转换成功:'+obj);
328 | return true;
329 | } catch(e) {
330 | console.log('no json');
331 | console.log('error:'+str+'!!!'+e);
332 | return false;
333 | }
334 | }
335 | //console.log('It is not a string!')
336 | }
--------------------------------------------------------------------------------
/function/iQIYI-DailyBonus/iqiyi.js:
--------------------------------------------------------------------------------
1 | // version v0.0.1
2 | // create by BlueSkyClouds
3 | // detail url: https://github.com/BlueskyClouds/My-Actions
4 | const exec = require('child_process').execSync
5 | const fs = require('fs')
6 | const download = require('download')
7 |
8 | const $ = new Env('爱奇艺会员签到');
9 | const notify = $.isNode() ? require('../sendNotify') : '';
10 | // 公共变量
11 | const KEY = process.env.iQIYI_COOKIE
12 | const SEND_KEY = process.env.SEND_KEY
13 | const UTC8 = new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000;
14 |
15 | async function downFile () {
16 | const url = 'https://raw.githubusercontent.com/BlueSkyClouds/My-Actions/master/function/iQIYI-DailyBonus/iQIYI-bak.js'
17 | await download(url, './')
18 | }
19 |
20 | async function changeFiele () {
21 | let content = await fs.readFileSync('./iQIYI-bak.js', 'utf8')
22 | content = content.replace(/var cookie = ''/, `var cookie = '${KEY}'`)
23 | await fs.writeFileSync( './iQIYI-bak.js', content, 'utf8')
24 | }
25 |
26 | async function deleteFile(path) {
27 | // 查看文件result.txt是 否存在,如果存在,先删除
28 | const fileExists = await fs.existsSync(path);
29 | // console.log('fileExists', fileExists);
30 | if (fileExists) {
31 | const unlinkRes = await fs.unlinkSync(path);
32 | // console.log('unlinkRes', unlinkRes)
33 | }
34 | }
35 |
36 | async function start() {
37 | if (!KEY) {
38 | console.log('请填写 key 后在继续')
39 | return
40 | }
41 | // 下载最新代码
42 | await downFile();
43 | console.log('下载代码完毕')
44 | // 替换变量
45 | await changeFiele();
46 | console.log('替换变量完毕')
47 | // 执行
48 | await exec("node iQIYI-bak.js >> result.txt");
49 | console.log('执行完毕')
50 | const path = "./result.txt";
51 | let content = "";
52 | if (fs.existsSync(path)) {
53 | content = fs.readFileSync(path, "utf8");
54 | }
55 | if (content.includes("今日已签到")) {
56 | //重复签到,不推送仅输出,因为每天会签到两次防止抽奖失败.
57 | console.log("爱奇艺签到-" + content + '\n重复签到,取消推送')
58 | }else if(SEND_KEY) {
59 | if (content.includes("Cookie")) {
60 | await notify.sendNotify("爱奇艺签到-" + timeFormat(UTC8), content);
61 | console.log("爱奇艺签到-" + content)
62 | }else{
63 | console.log("爱奇艺签到-" + content)
64 | }
65 | }else{
66 | await notify.sendNotify("爱奇艺签到-" + timeFormat(UTC8), content);
67 | console.log("爱奇艺签到-" + content)
68 | }
69 |
70 | //运行完成后,删除下载的文件
71 | console.log('运行完成后,删除下载的文件\n')
72 | await deleteFile(path);
73 | }
74 |
75 | start()
76 |
77 | function timeFormat(time) {
78 | let date;
79 | if (time) {
80 | date = new Date(time)
81 | } else {
82 | date = new Date();
83 | }
84 | return date.getFullYear() + '年' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '月' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()) + '日';
85 | }
86 | // prettier-ignore
87 | function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),a={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(a,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:i,...r}=t;this.got[s](i,r).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${s} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)}
88 |
--------------------------------------------------------------------------------
/function/sendNotify.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import time
3 | import hmac
4 | import hashlib
5 | import base64
6 | import json
7 | import os
8 | import urllib.parse
9 |
10 |
11 | class sendNotify:
12 | # =======================================微信server酱通知设置区域===========================================
13 | # 此处填你申请的SCKEY.
14 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入PUSH_KEY)
15 | SCKEY = ''
16 |
17 | # =======================================Bark App通知设置区域===========================================
18 | # 此处填你BarkAPP的信息(IP/设备码,例如:https://api.day.app/XXXXXXXX)
19 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_PUSH)
20 | BARK_PUSH = ''
21 | # BARK app推送铃声,铃声列表去APP查看复制填写
22 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_SOUND , Value输入app提供的铃声名称,例如:birdsong)
23 | BARK_SOUND = ''
24 |
25 | # =======================================telegram机器人通知设置区域===========================================
26 | # 此处填你telegram bot 的Token,例如:1077xxx4424:AAFjv0FlexboxEMGfi22B4yh15R5uw
27 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_BOT_TOKEN)
28 | TG_BOT_TOKEN = ''
29 | # 此处填你接收通知消息的telegram用户的id,例如:129xxx206
30 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_USER_ID)
31 | TG_USER_ID = ''
32 |
33 | # =======================================钉钉机器人通知设置区域===========================================
34 | # 此处填你钉钉 bot 的webhook,例如:5a544165465465645d0f31dca676e7bd07415assayed
35 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入DD_BOT_TOKEN)
36 | DD_BOT_TOKEN = ''
37 | # 密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串
38 | DD_BOT_SECRET = ''
39 |
40 | # =======================================企业微信机器人通知设置区域=========================================== 此处填你企业微信机器人的
41 | # webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
42 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QYWX_KEY)
43 | # QYWX_KEY = ''
44 |
45 | # =======================================企业微信应用消息通知设置区域=========================================== 此处填你企业微信应用消息的
46 | # 第一个值是企业id,第二个值是secret,第三个值@all(或者成员id),第四个值是AgentID 中间以逗号隔开
47 | # 详情查看https://note.youdao.com/ynoteshare1/index.html?id=351e08a72378206f9dd64d2281e9b83b&type=note#/
48 | # B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat
49 | QYWX_AM = ''
50 |
51 | # =======================================QQ酷推通知设置区域===========================================
52 | # 此处填你申请的SKEY(具体详见文档 https://cp.xuthus.cc/)
53 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QQ_SKEY)
54 | # QQ_SKEY = ''
55 | # #此处填写私聊或群组推送,默认私聊(send或group或者wx)
56 | # QQ_MODE = 'send'
57 |
58 | # =======================================push+设置区域=======================================
59 | # 官方文档:https://www.pushplus.plus/
60 | # PUSH_PLUS_TOKEN:微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送
61 | PUSH_PLUS_TOKEN = ''
62 | # PUSH_PLUS_USER: 一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)
63 | PUSH_PLUS_USER = ''
64 |
65 | # Server酱
66 | if os.environ['PUSH_KEY'] != "":
67 | SCKEY = os.environ['PUSH_KEY']
68 |
69 | # Bark App
70 | if os.environ['BARK_PUSH'] != "":
71 | if os.environ['BARK_PUSH'].find("https") != -1 or os.environ['BARK_PUSH'].find("http") != -1:
72 | BARK_PUSH = os.environ['PUSH_KEY']
73 | else:
74 | BARK_PUSH = "https://api.day.app/" + os.environ['BARK_PUSH']
75 | elif os.environ['BARK_SOUND'] != "":
76 | BARK_SOUND = os.environ['BARK_SOUND']
77 | elif BARK_PUSH != "" or BARK_PUSH.find("https") != -1 or BARK_PUSH.find("http") != -1:
78 | BARK_PUSH = "https://api.day.app/" + BARK_PUSH
79 |
80 | # telegram
81 | if os.environ['TG_BOT_TOKEN'] != "":
82 | TG_BOT_TOKEN = os.environ['TG_BOT_TOKEN']
83 | if os.environ['TG_USER_ID'] != "":
84 | TG_USER_ID = os.environ['TG_USER_ID']
85 |
86 | # 钉钉机器人
87 | if os.environ['DD_BOT_TOKEN'] != "":
88 | DD_BOT_TOKEN = os.environ['DD_BOT_TOKEN']
89 | if os.environ['DD_BOT_SECRET'] != "":
90 | DD_BOT_SECRET = os.environ['DD_BOT_SECRET']
91 |
92 | # QQ酷推
93 | # if os.environ['QQ_SKEY'] != "":
94 | # QQ_SKEY = os.environ['QQ_SKEY']
95 | # if os.environ['QQ_MODE'] != "":
96 | # QQ_MODE = os.environ['QQ_MODE']
97 |
98 | # 企业微信
99 | # if os.environ['QYWX_KEY'] != "":
100 | # QQ_SKEY = os.environ['QYWX_KEY']
101 | if os.environ['QYWX_AM'] != "":
102 | QYWX_AM = os.environ['QYWX_AM']
103 |
104 | # push+
105 | if os.environ['PUSH_PLUS_TOKEN'] != "":
106 | PUSH_PLUS_TOKEN = os.environ['PUSH_PLUS_TOKEN']
107 | if os.environ['PUSH_PLUS_USER'] != "":
108 | PUSH_PLUS_USER = os.environ['PUSH_PLUS_USER']
109 |
110 | def serverNotify(self, text, desp):
111 | if sendNotify.SCKEY != '':
112 | url = 'https://sctapi.ftqq.com/' + sendNotify.SCKEY + '.send'
113 | if "\n" in desp:
114 | desp = desp.replace("\n", "\n\n")
115 | data = {
116 | 'text': text,
117 | 'desp': desp
118 | }
119 | response = json.dumps(requests.post(url, data).json(), ensure_ascii=False)
120 | datas = json.loads(response)
121 | # print(datas)
122 | if datas['code'] == 0:
123 | print('\nserver酱发送通知消息成功\n')
124 | elif datas['code'] == 40001:
125 | print('\nPUSH_KEY 错误\n')
126 | else:
127 | print('\n发送通知调用API失败!!\n')
128 | else:
129 | print('\n您未提供server酱的SCKEY,取消微信推送消息通知\n')
130 | pass
131 |
132 | def BarkNotify(self, text, desp):
133 | if sendNotify.BARK_PUSH != '':
134 | url = sendNotify.BARK_PUSH + '/' + urllib.parse.quote(text) + '/' + urllib.parse.quote(
135 | desp) + '?sound=' + sendNotify.BARK_SOUND
136 | headers = {'Content-type': "application/x-www-form-urlencoded"}
137 | response = json.dumps(requests.get(url, headers=headers).json(), ensure_ascii=False)
138 | data = json.loads(response)
139 | # print(data)
140 | if data['code'] == 400:
141 | print('\n找不到 Key 对应的 DeviceToken\n')
142 | elif data['code'] == 200:
143 | print('\nBark APP发送通知消息成功\n')
144 | else:
145 | print('\nBark APP发送通知调用API失败!!\n')
146 | print(data)
147 | else:
148 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
149 | pass
150 |
151 | def tgBotNotify(self, text, desp):
152 | if sendNotify.TG_BOT_TOKEN != '' or sendNotify.TG_USER_ID != '':
153 |
154 | url = 'https://api.telegram.org/bot' + sendNotify.TG_BOT_TOKEN + '/sendMessage'
155 | headers = {'Content-type': "application/x-www-form-urlencoded"}
156 | body = 'chat_id=' + sendNotify.TG_USER_ID + '&text=' + urllib.parse.quote(
157 | text) + '\n\n' + urllib.parse.quote(desp) + '&disable_web_page_preview=true'
158 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
159 |
160 | data = json.loads(response)
161 | if data['ok']:
162 | print('\nTelegram发送通知消息完成\n')
163 | elif data['error_code'] == 400:
164 | print('\n请主动给bot发送一条消息并检查接收用户ID是否正确。\n')
165 | elif data['error_code'] == 401:
166 | print('\nTelegram bot token 填写错误。\n')
167 | else:
168 | print('\nTelegram bot发送通知调用API失败!!\n')
169 | print(data)
170 | else:
171 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
172 | pass
173 |
174 | def dingNotify(self, text, desp):
175 | if sendNotify.DD_BOT_TOKEN != '':
176 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN
177 | data = {
178 | "msgtype": "text",
179 | "text": {
180 | 'content': text + desp
181 | }
182 | }
183 | headers = {
184 | 'Content-Type': 'application/json;charset=utf-8'
185 | }
186 | if sendNotify.DD_BOT_SECRET != '':
187 | timestamp = str(round(time.time() * 1000))
188 | secret = sendNotify.DD_BOT_SECRET
189 | secret_enc = secret.encode('utf-8')
190 | string_to_sign = '{}\n{}'.format(timestamp, secret)
191 | string_to_sign_enc = string_to_sign.encode('utf-8')
192 | hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
193 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
194 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN + '×tamp=' + timestamp + '&sign=' + sign
195 |
196 | response = requests.post(url=url, data=json.dumps(data), headers=headers).text
197 | if json.loads(response)['errcode'] == 0:
198 | print('\n钉钉发送通知消息成功\n')
199 | else:
200 | print('\n钉钉发送通知失败!!\n')
201 | else:
202 | print('\n您未提供钉钉的有关数据,取消钉钉推送消息通知\n')
203 | pass
204 |
205 | # def coolpush(self, text, desp):
206 | # if sendNotify.QQ_SKEY != '':
207 | # url = "https://push.xuthus.cc/" + sendNotify.QQ_MODE + "/" + sendNotify.QQ_SKEY
208 | # params = {"c": desp, "t": text}
209 | # headers = {'content-type': 'charset=utf8'}
210 | # response = json.dumps(requests.post(url=url, params=params, headers=headers).json(),ensure_ascii=False)
211 | # datas = json.loads(response)
212 | #
213 | # if datas['code'] == 200:
214 | # print('\nQQ推送发送通知消息成功\n')
215 | # elif datas['code'] == 500:
216 | # print('\nQQ推送QQ_SKEY错误\n')
217 | # else:
218 | # print('\n发送通知调用API失败!!\n')
219 | #
220 | # else:
221 | # print('\n您未提供酷推的SKEY,取消QQ推送消息通知\n')
222 | # pass
223 | def pushNotify(self, text, desp):
224 | if sendNotify.PUSH_PLUS_TOKEN != '':
225 | url = 'http://www.pushplus.plus/send'
226 | data = {
227 | "token": sendNotify.PUSH_PLUS_TOKEN,
228 | "title": text,
229 | "content": desp
230 | }
231 | if sendNotify.PUSH_PLUS_USER != '':
232 | data = {
233 | "token": sendNotify.PUSH_PLUS_TOKEN,
234 | "title": text,
235 | "content": desp,
236 | "topic": sendNotify.PUSH_PLUS_USER,
237 | "template": "html"
238 | }
239 | body = json.dumps(data).encode(encoding='utf-8')
240 | headers = {'Content-Type': 'application/json'}
241 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
242 | datas = json.loads(response)
243 | if datas['code'] == 200:
244 | print('\npush+发送通知消息成功\n')
245 | if datas['code'] == 600:
246 | print('\nPUSH_PLUS_TOKEN 错误\n')
247 | else:
248 | print('\npush+发送通知调用API失败!!\n')
249 | else:
250 | print('\n您未提供push+的PUSH_PLUS_TOKEN,取消push+推送消息通知\n')
251 | pass
252 |
253 | # 企业微信推送
254 | def sendWechat(self, desp):
255 | if sendNotify.QYWX_AM != '':
256 | # 获得access_token
257 | url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
258 | token_param = '?corpid=' + sendNotify.QYWX_AM.split(',')[0] + '&corpsecret=' + sendNotify.QYWX_AM.split(',')[1]
259 | token_data = requests.get(url + token_param)
260 | token_data.encoding = 'utf-8'
261 | token_data = token_data.json()
262 | access_token = token_data['access_token']
263 | #发送内容
264 | content = desp
265 | #创建要发送的消息
266 | data = {
267 | "touser": sendNotify.QYWX_AM.split(',')[2],
268 | "msgtype": "text",
269 | "agentid": sendNotify.QYWX_AM.split(',')[3],
270 | "text": {"content": content}
271 | }
272 | send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + access_token
273 | message = requests.post(send_url, json=data)
274 | message.encoding = 'utf-8'
275 | res = message.json()
276 | print('企业微信推送 : ' + res['errmsg'])
277 | else:
278 | print('\n您未提供企业微信的QYWX_AM,取消企业微信推送消息通知\n')
279 | pass
280 |
281 | def send(self, **kwargs):
282 | send = sendNotify()
283 | title = kwargs.get("title", "")
284 | msg = kwargs.get("msg", "")
285 | send.serverNotify(title, msg)
286 | send.BarkNotify(title, msg)
287 | send.tgBotNotify(title, msg)
288 | send.dingNotify(title, msg)
289 | send.pushNotify(title, msg)
290 | send.sendWechat(msg)
291 | # send.coolpush(title,msg)
292 |
293 | # if __name__ == "__main__":
294 | # send(title = '这是标题',msg = '这是内容')
295 |
--------------------------------------------------------------------------------
/function/v2ex/v2ex.js:
--------------------------------------------------------------------------------
1 | //V2ex-Auto-Sign
2 | const $ = new Env('V2ex自动签到');
3 | const notify = $.isNode() ? require('../sendNotify') : '';
4 | const cookie = process.env.V2EXCK
5 | const SEND_KEY = process.env.SEND_KEY
6 | const axios = require("axios")
7 | const UTC8 = new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000;
8 |
9 | once = null;
10 | ckstatus = 1;
11 | signstatus = 0;
12 | notice = timeFormat(UTC8) + "\n";
13 |
14 | const header = {
15 | headers: {
16 | Referer: "https://www.v2ex.com/mission",
17 | Host: "www.v2ex.com",
18 | "user-agent": "Mozilla/5.0 (Linux; Android 10; Redmi K30) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36",
19 | cookie: `'${cookie}'`,
20 | },
21 | };
22 |
23 | //获取once检查是否已签到
24 | function check() {
25 | return new Promise(async (resolve) => {
26 | try {
27 | let url = "https://www.v2ex.com/mission/daily";
28 | let res = await axios.get(url, header);
29 | reg1 = /需要先登录/;
30 | if (reg1.test(res.data)) {
31 | console.log("cookie失效");
32 | ckstatus = 0;
33 | notice += "cookie失效";
34 | if(SEND_KEY){
35 | notify.sendNotify("V2ex自动签到", notice);
36 | return;
37 | }
38 | } else {
39 | reg = /每日登录奖励已领取/;
40 | if (reg.test(res.data)) {
41 | notice += "今天已经签到过啦\n";
42 | signstatus = 1;
43 | } else {
44 | reg = /redeem\?once=(.*?)'/;
45 | once = res.data.match(reg)[1];
46 | console.log(`获取成功 once:${once}`);
47 | }
48 | }
49 | } catch (err) {
50 | console.log(err);
51 | }
52 | resolve();
53 | });
54 | }
55 |
56 | //每日签到
57 | function daily() {
58 | return new Promise(async (resolve) => {
59 | try {
60 | let url = `https://www.v2ex.com/mission/daily/redeem?once=${once}`;
61 | let res = await axios.get(url, header);
62 | reg = /已成功领取每日登录奖励/;
63 | if (reg.test(res.data)) {
64 | notice += "签到成功\n";
65 | signstatus = 1;
66 | } else {
67 | notice += "签到失败Cookie疑似失效\n";
68 | if(SEND_KEY){
69 | notify.sendNotify("V2ex自动签到", notice);
70 | return;
71 | }
72 | }
73 | } catch (err) {
74 | console.log(err);
75 | }
76 | resolve();
77 | });
78 | }
79 |
80 | //查询余额
81 | function balance() {
82 | return new Promise(async (resolve) => {
83 | try {
84 | let url = "https://www.v2ex.com/balance";
85 | let res = await axios.get(url, header);
86 | reg = /\d+?\s的每日登录奖励\s\d+\s铜币/;
87 | console.log(res.data.match(reg)[0]);
88 | notice += res.data.match(reg)[0];
89 | } catch (err) {
90 | console.log(err);
91 | }
92 | resolve();
93 | });
94 | }
95 |
96 | function sign() {
97 | return new Promise(async (resolve) => {
98 | try {
99 |
100 | if (!cookie) {
101 | console.log("你的cookie呢!!!");
102 | return;
103 | }
104 | await check();
105 | if (once && signstatus === 0) {
106 | await daily();
107 | await balance();
108 | if (signstatus === 0) {
109 | console.log("签到失败Cookie疑似失效")
110 | }
111 | }
112 | console.log(notice);
113 | notify.sendNotify("V2ex自动签到", notice);
114 | } catch (err) {
115 | console.log(err);
116 | }
117 | resolve();
118 | });
119 | }
120 |
121 | sign();
122 |
123 | function timeFormat(time) {
124 | let date;
125 | if (time) {
126 | date = new Date(time)
127 | } else {
128 | date = new Date();
129 | }
130 | return date.getFullYear() + '年' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '月' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()) + '日';
131 | }
132 | // prettier-ignore
133 | function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),a={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(a,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:i,...r}=t;this.got[s](i,r).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${s} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)}
134 |
--------------------------------------------------------------------------------
/function/wps/sendNotify.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import time
3 | import hmac
4 | import hashlib
5 | import base64
6 | import json
7 | import os
8 | import urllib.parse
9 |
10 |
11 | class sendNotify:
12 | # =======================================微信server酱通知设置区域===========================================
13 | # 此处填你申请的SCKEY.
14 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入PUSH_KEY)
15 | SCKEY = ''
16 |
17 | # =======================================Bark App通知设置区域===========================================
18 | # 此处填你BarkAPP的信息(IP/设备码,例如:https://api.day.app/XXXXXXXX)
19 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_PUSH)
20 | BARK_PUSH = ''
21 | # BARK app推送铃声,铃声列表去APP查看复制填写
22 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_SOUND , Value输入app提供的铃声名称,例如:birdsong)
23 | BARK_SOUND = ''
24 |
25 | # =======================================telegram机器人通知设置区域===========================================
26 | # 此处填你telegram bot 的Token,例如:1077xxx4424:AAFjv0FlexboxEMGfi22B4yh15R5uw
27 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_BOT_TOKEN)
28 | TG_BOT_TOKEN = ''
29 | # 此处填你接收通知消息的telegram用户的id,例如:129xxx206
30 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_USER_ID)
31 | TG_USER_ID = ''
32 |
33 | # =======================================钉钉机器人通知设置区域===========================================
34 | # 此处填你钉钉 bot 的webhook,例如:5a544165465465645d0f31dca676e7bd07415assayed
35 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入DD_BOT_TOKEN)
36 | DD_BOT_TOKEN = ''
37 | # 密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串
38 | DD_BOT_SECRET = ''
39 |
40 | # =======================================企业微信机器人通知设置区域=========================================== 此处填你企业微信机器人的
41 | # webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
42 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QYWX_KEY)
43 | # QYWX_KEY = ''
44 |
45 | # =======================================企业微信应用消息通知设置区域=========================================== 此处填你企业微信应用消息的
46 | # 第一个值是企业id,第二个值是secret,第三个值@all(或者成员id),第四个值是AgentID 中间以逗号隔开
47 | # 详情查看https://note.youdao.com/ynoteshare1/index.html?id=351e08a72378206f9dd64d2281e9b83b&type=note#/
48 | # B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat
49 | QYWX_AM = ''
50 |
51 | # =======================================QQ酷推通知设置区域===========================================
52 | # 此处填你申请的SKEY(具体详见文档 https://cp.xuthus.cc/)
53 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QQ_SKEY)
54 | # QQ_SKEY = ''
55 | # #此处填写私聊或群组推送,默认私聊(send或group或者wx)
56 | # QQ_MODE = 'send'
57 |
58 | # =======================================push+设置区域=======================================
59 | # 官方文档:https://www.pushplus.plus/
60 | # PUSH_PLUS_TOKEN:微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送
61 | PUSH_PLUS_TOKEN = ''
62 | # PUSH_PLUS_USER: 一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)
63 | PUSH_PLUS_USER = ''
64 |
65 | # Server酱
66 | if os.environ['PUSH_KEY'] != "":
67 | SCKEY = os.environ['PUSH_KEY']
68 |
69 | # Bark App
70 | if os.environ['BARK_PUSH'] != "":
71 | if os.environ['BARK_PUSH'].find("https") != -1 or os.environ['BARK_PUSH'].find("http") != -1:
72 | BARK_PUSH = os.environ['PUSH_KEY']
73 | else:
74 | BARK_PUSH = "https://api.day.app/" + os.environ['BARK_PUSH']
75 | elif os.environ['BARK_SOUND'] != "":
76 | BARK_SOUND = os.environ['BARK_SOUND']
77 | elif BARK_PUSH != "" or BARK_PUSH.find("https") != -1 or BARK_PUSH.find("http") != -1:
78 | BARK_PUSH = "https://api.day.app/" + BARK_PUSH
79 |
80 | # telegram
81 | if os.environ['TG_BOT_TOKEN'] != "":
82 | TG_BOT_TOKEN = os.environ['TG_BOT_TOKEN']
83 | if os.environ['TG_USER_ID'] != "":
84 | TG_USER_ID = os.environ['TG_USER_ID']
85 |
86 | # 钉钉机器人
87 | if os.environ['DD_BOT_TOKEN'] != "":
88 | DD_BOT_TOKEN = os.environ['DD_BOT_TOKEN']
89 | if os.environ['DD_BOT_SECRET'] != "":
90 | DD_BOT_SECRET = os.environ['DD_BOT_SECRET']
91 |
92 | # QQ酷推
93 | # if os.environ['QQ_SKEY'] != "":
94 | # QQ_SKEY = os.environ['QQ_SKEY']
95 | # if os.environ['QQ_MODE'] != "":
96 | # QQ_MODE = os.environ['QQ_MODE']
97 |
98 | # 企业微信
99 | # if os.environ['QYWX_KEY'] != "":
100 | # QQ_SKEY = os.environ['QYWX_KEY']
101 | if os.environ['QYWX_AM'] != "":
102 | QYWX_AM = os.environ['QYWX_AM']
103 |
104 | # push+
105 | if os.environ['PUSH_PLUS_TOKEN'] != "":
106 | PUSH_PLUS_TOKEN = os.environ['PUSH_PLUS_TOKEN']
107 | if os.environ['PUSH_PLUS_USER'] != "":
108 | PUSH_PLUS_USER = os.environ['PUSH_PLUS_USER']
109 |
110 | def serverNotify(self, text, desp):
111 | if sendNotify.SCKEY != '':
112 | url = 'https://sctapi.ftqq.com/' + sendNotify.SCKEY + '.send'
113 | if "\n" in desp:
114 | desp = desp.replace("\n", "\n\n")
115 | data = {
116 | 'text': text,
117 | 'desp': desp
118 | }
119 | response = json.dumps(requests.post(url, data).json(), ensure_ascii=False)
120 | datas = json.loads(response)
121 | # print(datas)
122 | if datas['code'] == 0:
123 | print('\nserver酱发送通知消息成功\n')
124 | elif datas['code'] == 40001:
125 | print('\nPUSH_KEY 错误\n')
126 | else:
127 | print('\n发送通知调用API失败!!\n')
128 | else:
129 | print('\n您未提供server酱的SCKEY,取消微信推送消息通知\n')
130 | pass
131 |
132 | def BarkNotify(self, text, desp):
133 | if sendNotify.BARK_PUSH != '':
134 | url = sendNotify.BARK_PUSH + '/' + urllib.parse.quote(text) + '/' + urllib.parse.quote(
135 | desp) + '?sound=' + sendNotify.BARK_SOUND
136 | headers = {'Content-type': "application/x-www-form-urlencoded"}
137 | response = json.dumps(requests.get(url, headers=headers).json(), ensure_ascii=False)
138 | data = json.loads(response)
139 | # print(data)
140 | if data['code'] == 400:
141 | print('\n找不到 Key 对应的 DeviceToken\n')
142 | elif data['code'] == 200:
143 | print('\nBark APP发送通知消息成功\n')
144 | else:
145 | print('\nBark APP发送通知调用API失败!!\n')
146 | print(data)
147 | else:
148 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
149 | pass
150 |
151 | def tgBotNotify(self, text, desp):
152 | if sendNotify.TG_BOT_TOKEN != '' or sendNotify.TG_USER_ID != '':
153 |
154 | url = 'https://api.telegram.org/bot' + sendNotify.TG_BOT_TOKEN + '/sendMessage'
155 | headers = {'Content-type': "application/x-www-form-urlencoded"}
156 | body = 'chat_id=' + sendNotify.TG_USER_ID + '&text=' + urllib.parse.quote(
157 | text) + '\n\n' + urllib.parse.quote(desp) + '&disable_web_page_preview=true'
158 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
159 |
160 | data = json.loads(response)
161 | if data['ok']:
162 | print('\nTelegram发送通知消息完成\n')
163 | elif data['error_code'] == 400:
164 | print('\n请主动给bot发送一条消息并检查接收用户ID是否正确。\n')
165 | elif data['error_code'] == 401:
166 | print('\nTelegram bot token 填写错误。\n')
167 | else:
168 | print('\nTelegram bot发送通知调用API失败!!\n')
169 | print(data)
170 | else:
171 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
172 | pass
173 |
174 | def dingNotify(self, text, desp):
175 | if sendNotify.DD_BOT_TOKEN != '':
176 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN
177 | data = {
178 | "msgtype": "text",
179 | "text": {
180 | 'content': text + desp
181 | }
182 | }
183 | headers = {
184 | 'Content-Type': 'application/json;charset=utf-8'
185 | }
186 | if sendNotify.DD_BOT_SECRET != '':
187 | timestamp = str(round(time.time() * 1000))
188 | secret = sendNotify.DD_BOT_SECRET
189 | secret_enc = secret.encode('utf-8')
190 | string_to_sign = '{}\n{}'.format(timestamp, secret)
191 | string_to_sign_enc = string_to_sign.encode('utf-8')
192 | hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
193 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
194 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN + '×tamp=' + timestamp + '&sign=' + sign
195 |
196 | response = requests.post(url=url, data=json.dumps(data), headers=headers).text
197 | if json.loads(response)['errcode'] == 0:
198 | print('\n钉钉发送通知消息成功\n')
199 | else:
200 | print('\n钉钉发送通知失败!!\n')
201 | else:
202 | print('\n您未提供钉钉的有关数据,取消钉钉推送消息通知\n')
203 | pass
204 |
205 | # def coolpush(self, text, desp):
206 | # if sendNotify.QQ_SKEY != '':
207 | # url = "https://push.xuthus.cc/" + sendNotify.QQ_MODE + "/" + sendNotify.QQ_SKEY
208 | # params = {"c": desp, "t": text}
209 | # headers = {'content-type': 'charset=utf8'}
210 | # response = json.dumps(requests.post(url=url, params=params, headers=headers).json(),ensure_ascii=False)
211 | # datas = json.loads(response)
212 | #
213 | # if datas['code'] == 200:
214 | # print('\nQQ推送发送通知消息成功\n')
215 | # elif datas['code'] == 500:
216 | # print('\nQQ推送QQ_SKEY错误\n')
217 | # else:
218 | # print('\n发送通知调用API失败!!\n')
219 | #
220 | # else:
221 | # print('\n您未提供酷推的SKEY,取消QQ推送消息通知\n')
222 | # pass
223 | def pushNotify(self, text, desp):
224 | if sendNotify.PUSH_PLUS_TOKEN != '':
225 | url = 'http://www.pushplus.plus/send'
226 | data = {
227 | "token": sendNotify.PUSH_PLUS_TOKEN,
228 | "title": text,
229 | "content": desp
230 | }
231 | if sendNotify.PUSH_PLUS_USER != '':
232 | data = {
233 | "token": sendNotify.PUSH_PLUS_TOKEN,
234 | "title": text,
235 | "content": desp,
236 | "topic": sendNotify.PUSH_PLUS_USER,
237 | "template": "html"
238 | }
239 | body = json.dumps(data).encode(encoding='utf-8')
240 | headers = {'Content-Type': 'application/json'}
241 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
242 | datas = json.loads(response)
243 | if datas['code'] == 200:
244 | print('\npush+发送通知消息成功\n')
245 | if datas['code'] == 600:
246 | print('\nPUSH_PLUS_TOKEN 错误\n')
247 | else:
248 | print('\npush+发送通知调用API失败!!\n')
249 | else:
250 | print('\n您未提供push+的PUSH_PLUS_TOKEN,取消push+推送消息通知\n')
251 | pass
252 |
253 | # 企业微信推送
254 | def sendWechat(self, desp):
255 | if sendNotify.QYWX_AM != '':
256 | # 获得access_token
257 | url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
258 | token_param = '?corpid=' + sendNotify.QYWX_AM.split(',')[0] + '&corpsecret=' + sendNotify.QYWX_AM.split(',')[1]
259 | token_data = requests.get(url + token_param)
260 | token_data.encoding = 'utf-8'
261 | token_data = token_data.json()
262 | access_token = token_data['access_token']
263 | #发送内容
264 | content = desp
265 | #创建要发送的消息
266 | data = {
267 | "touser": sendNotify.QYWX_AM.split(',')[2],
268 | "msgtype": "text",
269 | "agentid": sendNotify.QYWX_AM.split(',')[3],
270 | "text": {"content": content}
271 | }
272 | send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + access_token
273 | message = requests.post(send_url, json=data)
274 | message.encoding = 'utf-8'
275 | res = message.json()
276 | print('企业微信推送 : ' + res['errmsg'])
277 | else:
278 | print('\n您未提供企业微信的QYWX_AM,取消企业微信推送消息通知\n')
279 | pass
280 |
281 | def send(self, **kwargs):
282 | send = sendNotify()
283 | title = kwargs.get("title", "")
284 | msg = kwargs.get("msg", "")
285 | send.serverNotify(title, msg)
286 | send.BarkNotify(title, msg)
287 | send.tgBotNotify(title, msg)
288 | send.dingNotify(title, msg)
289 | send.pushNotify(title, msg)
290 | send.sendWechat(msg)
291 | # send.coolpush(title,msg)
292 |
293 | # if __name__ == "__main__":
294 | # send(title = '这是标题',msg = '这是内容')
295 |
--------------------------------------------------------------------------------
/function/xiaomi_sports/sendNotify.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import time
3 | import hmac
4 | import hashlib
5 | import base64
6 | import json
7 | import os
8 | import urllib.parse
9 |
10 |
11 | class sendNotify:
12 | # =======================================微信server酱通知设置区域===========================================
13 | # 此处填你申请的SCKEY.
14 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入PUSH_KEY)
15 | SCKEY = ''
16 |
17 | # =======================================Bark App通知设置区域===========================================
18 | # 此处填你BarkAPP的信息(IP/设备码,例如:https://api.day.app/XXXXXXXX)
19 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_PUSH)
20 | BARK_PUSH = ''
21 | # BARK app推送铃声,铃声列表去APP查看复制填写
22 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入BARK_SOUND , Value输入app提供的铃声名称,例如:birdsong)
23 | BARK_SOUND = ''
24 |
25 | # =======================================telegram机器人通知设置区域===========================================
26 | # 此处填你telegram bot 的Token,例如:1077xxx4424:AAFjv0FlexboxEMGfi22B4yh15R5uw
27 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_BOT_TOKEN)
28 | TG_BOT_TOKEN = ''
29 | # 此处填你接收通知消息的telegram用户的id,例如:129xxx206
30 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入TG_USER_ID)
31 | TG_USER_ID = ''
32 |
33 | # =======================================钉钉机器人通知设置区域===========================================
34 | # 此处填你钉钉 bot 的webhook,例如:5a544165465465645d0f31dca676e7bd07415assayed
35 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入DD_BOT_TOKEN)
36 | DD_BOT_TOKEN = ''
37 | # 密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串
38 | DD_BOT_SECRET = ''
39 |
40 | # =======================================企业微信机器人通知设置区域=========================================== 此处填你企业微信机器人的
41 | # webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
42 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QYWX_KEY)
43 | # QYWX_KEY = ''
44 |
45 | # =======================================企业微信应用消息通知设置区域=========================================== 此处填你企业微信应用消息的
46 | # 第一个值是企业id,第二个值是secret,第三个值@all(或者成员id),第四个值是AgentID 中间以逗号隔开
47 | # 详情查看https://note.youdao.com/ynoteshare1/index.html?id=351e08a72378206f9dd64d2281e9b83b&type=note#/
48 | # B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat
49 | QYWX_AM = ''
50 |
51 | # =======================================QQ酷推通知设置区域===========================================
52 | # 此处填你申请的SKEY(具体详见文档 https://cp.xuthus.cc/)
53 | # 注:此处设置github action用户填写到Settings-Secrets里面(Name输入QQ_SKEY)
54 | # QQ_SKEY = ''
55 | # #此处填写私聊或群组推送,默认私聊(send或group或者wx)
56 | # QQ_MODE = 'send'
57 |
58 | # =======================================push+设置区域=======================================
59 | # 官方文档:https://www.pushplus.plus/
60 | # PUSH_PLUS_TOKEN:微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送
61 | PUSH_PLUS_TOKEN = ''
62 | # PUSH_PLUS_USER: 一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)
63 | PUSH_PLUS_USER = ''
64 |
65 | # Server酱
66 | if os.environ['PUSH_KEY'] != "":
67 | SCKEY = os.environ['PUSH_KEY']
68 |
69 | # Bark App
70 | if os.environ['BARK_PUSH'] != "":
71 | if os.environ['BARK_PUSH'].find("https") != -1 or os.environ['BARK_PUSH'].find("http") != -1:
72 | BARK_PUSH = os.environ['PUSH_KEY']
73 | else:
74 | BARK_PUSH = "https://api.day.app/" + os.environ['BARK_PUSH']
75 | elif os.environ['BARK_SOUND'] != "":
76 | BARK_SOUND = os.environ['BARK_SOUND']
77 | elif BARK_PUSH != "" or BARK_PUSH.find("https") != -1 or BARK_PUSH.find("http") != -1:
78 | BARK_PUSH = "https://api.day.app/" + BARK_PUSH
79 |
80 | # telegram
81 | if os.environ['TG_BOT_TOKEN'] != "":
82 | TG_BOT_TOKEN = os.environ['TG_BOT_TOKEN']
83 | if os.environ['TG_USER_ID'] != "":
84 | TG_USER_ID = os.environ['TG_USER_ID']
85 |
86 | # 钉钉机器人
87 | if os.environ['DD_BOT_TOKEN'] != "":
88 | DD_BOT_TOKEN = os.environ['DD_BOT_TOKEN']
89 | if os.environ['DD_BOT_SECRET'] != "":
90 | DD_BOT_SECRET = os.environ['DD_BOT_SECRET']
91 |
92 | # QQ酷推
93 | # if os.environ['QQ_SKEY'] != "":
94 | # QQ_SKEY = os.environ['QQ_SKEY']
95 | # if os.environ['QQ_MODE'] != "":
96 | # QQ_MODE = os.environ['QQ_MODE']
97 |
98 | # 企业微信
99 | # if os.environ['QYWX_KEY'] != "":
100 | # QQ_SKEY = os.environ['QYWX_KEY']
101 | if os.environ['QYWX_AM'] != "":
102 | QYWX_AM = os.environ['QYWX_AM']
103 |
104 | # push+
105 | if os.environ['PUSH_PLUS_TOKEN'] != "":
106 | PUSH_PLUS_TOKEN = os.environ['PUSH_PLUS_TOKEN']
107 | if os.environ['PUSH_PLUS_USER'] != "":
108 | PUSH_PLUS_USER = os.environ['PUSH_PLUS_USER']
109 |
110 | def serverNotify(self, text, desp):
111 | if sendNotify.SCKEY != '':
112 | url = 'https://sctapi.ftqq.com/' + sendNotify.SCKEY + '.send'
113 | if "\n" in desp:
114 | desp = desp.replace("\n", "\n\n")
115 | data = {
116 | 'text': text,
117 | 'desp': desp
118 | }
119 | response = json.dumps(requests.post(url, data).json(), ensure_ascii=False)
120 | datas = json.loads(response)
121 | # print(datas)
122 | if datas['code'] == 0:
123 | print('\nserver酱发送通知消息成功\n')
124 | elif datas['code'] == 40001:
125 | print('\nPUSH_KEY 错误\n')
126 | else:
127 | print('\n发送通知调用API失败!!\n')
128 | else:
129 | print('\n您未提供server酱的SCKEY,取消微信推送消息通知\n')
130 | pass
131 |
132 | def BarkNotify(self, text, desp):
133 | if sendNotify.BARK_PUSH != '':
134 | url = sendNotify.BARK_PUSH + '/' + urllib.parse.quote(text) + '/' + urllib.parse.quote(
135 | desp) + '?sound=' + sendNotify.BARK_SOUND
136 | headers = {'Content-type': "application/x-www-form-urlencoded"}
137 | response = json.dumps(requests.get(url, headers=headers).json(), ensure_ascii=False)
138 | data = json.loads(response)
139 | # print(data)
140 | if data['code'] == 400:
141 | print('\n找不到 Key 对应的 DeviceToken\n')
142 | elif data['code'] == 200:
143 | print('\nBark APP发送通知消息成功\n')
144 | else:
145 | print('\nBark APP发送通知调用API失败!!\n')
146 | print(data)
147 | else:
148 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
149 | pass
150 |
151 | def tgBotNotify(self, text, desp):
152 | if sendNotify.TG_BOT_TOKEN != '' or sendNotify.TG_USER_ID != '':
153 |
154 | url = 'https://api.telegram.org/bot' + sendNotify.TG_BOT_TOKEN + '/sendMessage'
155 | headers = {'Content-type': "application/x-www-form-urlencoded"}
156 | body = 'chat_id=' + sendNotify.TG_USER_ID + '&text=' + urllib.parse.quote(
157 | text) + '\n\n' + urllib.parse.quote(desp) + '&disable_web_page_preview=true'
158 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
159 |
160 | data = json.loads(response)
161 | if data['ok']:
162 | print('\nTelegram发送通知消息完成\n')
163 | elif data['error_code'] == 400:
164 | print('\n请主动给bot发送一条消息并检查接收用户ID是否正确。\n')
165 | elif data['error_code'] == 401:
166 | print('\nTelegram bot token 填写错误。\n')
167 | else:
168 | print('\nTelegram bot发送通知调用API失败!!\n')
169 | print(data)
170 | else:
171 | print('\n您未提供Bark的APP推送BARK_PUSH,取消Bark推送消息通知\n')
172 | pass
173 |
174 | def dingNotify(self, text, desp):
175 | if sendNotify.DD_BOT_TOKEN != '':
176 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN
177 | data = {
178 | "msgtype": "text",
179 | "text": {
180 | 'content': text + desp
181 | }
182 | }
183 | headers = {
184 | 'Content-Type': 'application/json;charset=utf-8'
185 | }
186 | if sendNotify.DD_BOT_SECRET != '':
187 | timestamp = str(round(time.time() * 1000))
188 | secret = sendNotify.DD_BOT_SECRET
189 | secret_enc = secret.encode('utf-8')
190 | string_to_sign = '{}\n{}'.format(timestamp, secret)
191 | string_to_sign_enc = string_to_sign.encode('utf-8')
192 | hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
193 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
194 | url = 'https://oapi.dingtalk.com/robot/send?access_token=' + sendNotify.DD_BOT_TOKEN + '×tamp=' + timestamp + '&sign=' + sign
195 |
196 | response = requests.post(url=url, data=json.dumps(data), headers=headers).text
197 | if json.loads(response)['errcode'] == 0:
198 | print('\n钉钉发送通知消息成功\n')
199 | else:
200 | print('\n钉钉发送通知失败!!\n')
201 | else:
202 | print('\n您未提供钉钉的有关数据,取消钉钉推送消息通知\n')
203 | pass
204 |
205 | # def coolpush(self, text, desp):
206 | # if sendNotify.QQ_SKEY != '':
207 | # url = "https://push.xuthus.cc/" + sendNotify.QQ_MODE + "/" + sendNotify.QQ_SKEY
208 | # params = {"c": desp, "t": text}
209 | # headers = {'content-type': 'charset=utf8'}
210 | # response = json.dumps(requests.post(url=url, params=params, headers=headers).json(),ensure_ascii=False)
211 | # datas = json.loads(response)
212 | #
213 | # if datas['code'] == 200:
214 | # print('\nQQ推送发送通知消息成功\n')
215 | # elif datas['code'] == 500:
216 | # print('\nQQ推送QQ_SKEY错误\n')
217 | # else:
218 | # print('\n发送通知调用API失败!!\n')
219 | #
220 | # else:
221 | # print('\n您未提供酷推的SKEY,取消QQ推送消息通知\n')
222 | # pass
223 | def pushNotify(self, text, desp):
224 | if sendNotify.PUSH_PLUS_TOKEN != '':
225 | url = 'http://www.pushplus.plus/send'
226 | data = {
227 | "token": sendNotify.PUSH_PLUS_TOKEN,
228 | "title": text,
229 | "content": desp
230 | }
231 | if sendNotify.PUSH_PLUS_USER != '':
232 | data = {
233 | "token": sendNotify.PUSH_PLUS_TOKEN,
234 | "title": text,
235 | "content": desp,
236 | "topic": sendNotify.PUSH_PLUS_USER,
237 | "template": "html"
238 | }
239 | body = json.dumps(data).encode(encoding='utf-8')
240 | headers = {'Content-Type': 'application/json'}
241 | response = json.dumps(requests.post(url, data=body, headers=headers).json(), ensure_ascii=False)
242 | datas = json.loads(response)
243 | if datas['code'] == 200:
244 | print('\npush+发送通知消息成功\n')
245 | if datas['code'] == 600:
246 | print('\nPUSH_PLUS_TOKEN 错误\n')
247 | else:
248 | print('\npush+发送通知调用API失败!!\n')
249 | else:
250 | print('\n您未提供push+的PUSH_PLUS_TOKEN,取消push+推送消息通知\n')
251 | pass
252 |
253 | # 企业微信推送
254 | def sendWechat(self, desp):
255 | if sendNotify.QYWX_AM != '':
256 | # 获得access_token
257 | url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
258 | token_param = '?corpid=' + sendNotify.QYWX_AM.split(',')[0] + '&corpsecret=' + sendNotify.QYWX_AM.split(',')[1]
259 | token_data = requests.get(url + token_param)
260 | token_data.encoding = 'utf-8'
261 | token_data = token_data.json()
262 | access_token = token_data['access_token']
263 | #发送内容
264 | content = desp
265 | #创建要发送的消息
266 | data = {
267 | "touser": sendNotify.QYWX_AM.split(',')[2],
268 | "msgtype": "text",
269 | "agentid": sendNotify.QYWX_AM.split(',')[3],
270 | "text": {"content": content}
271 | }
272 | send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + access_token
273 | message = requests.post(send_url, json=data)
274 | message.encoding = 'utf-8'
275 | res = message.json()
276 | print('企业微信推送 : ' + res['errmsg'])
277 | else:
278 | print('\n您未提供企业微信的QYWX_AM,取消企业微信推送消息通知\n')
279 | pass
280 |
281 | def send(self, **kwargs):
282 | send = sendNotify()
283 | title = kwargs.get("title", "")
284 | msg = kwargs.get("msg", "")
285 | send.serverNotify(title, msg)
286 | send.BarkNotify(title, msg)
287 | send.tgBotNotify(title, msg)
288 | send.dingNotify(title, msg)
289 | send.pushNotify(title, msg)
290 | send.sendWechat(msg)
291 | # send.coolpush(title,msg)
292 |
293 | # if __name__ == "__main__":
294 | # send(title = '这是标题',msg = '这是内容')
295 |
--------------------------------------------------------------------------------
/function/xiaomi_sports/xiaomi.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf8 -*-
2 | # python >=3.8
3 |
4 | import random
5 | import re
6 | import sys
7 |
8 | sys.path.append("My-Actions/function/wps")
9 | from sendNotify import *
10 |
11 | sendNotify = sendNotify()
12 | now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
13 | headers = {
14 | 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 9; MI 6 MIUI/20.6.18)'
15 | }
16 |
17 |
18 | # 获取登录code
19 | def get_code(location):
20 | code_pattern = re.compile("(?<=access=).*?(?=&)")
21 | code = code_pattern.findall(location)[0]
22 | return code
23 |
24 |
25 | # 登录
26 | def login(user, password):
27 | url1 = "https://api-user.huami.com/registrations/+86" + user + "/tokens"
28 | headers = {
29 | "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
30 | "User-Agent": "MiFit/4.6.0 (iPhone; iOS 14.0.1; Scale/2.00)"
31 | }
32 | data1 = {
33 | "client_id": "HuaMi",
34 | "password": f"{password}",
35 | "redirect_uri": "https://s3-us-west-2.amazonaws.com/hm-registration/successsignin.html",
36 | "token": "access"
37 | }
38 | r1 = requests.post(url1, data=data1, headers=headers, allow_redirects=False)
39 | location = r1.headers["Location"]
40 | try:
41 | code = get_code(location)
42 | except:
43 | return 0, 0
44 | # print("access_code获取成功!")
45 | # print(code)
46 |
47 | url2 = "https://account.huami.com/v2/client/login"
48 | data2 = {
49 | "app_name": "com.xiaomi.hm.health",
50 | "app_version": "4.6.0",
51 | "code": f"{code}",
52 | "country_code": "CN",
53 | "device_id": "2C8B4939-0CCD-4E94-8CBA-CB8EA6E613A1",
54 | "device_model": "phone",
55 | "grant_type": "access_token",
56 | "third_name": "huami_phone",
57 | }
58 | r2 = requests.post(url2, data=data2, headers=headers).json()
59 | login_token = r2["token_info"]["login_token"]
60 | # print("login_token获取成功!")
61 | # print(login_token)
62 | userid = r2["token_info"]["user_id"]
63 | # print("userid获取成功!")
64 | # print(userid)
65 |
66 | return login_token, userid
67 |
68 |
69 | # 主函数
70 | def main(user, passwd, step):
71 | user = str(user)
72 | password = str(passwd)
73 | step = str(step)
74 | if user == '' or password == '':
75 | print("未填写小米运动用户名或密码,取消运行")
76 | exit(0)
77 | # return "用户名或密码填写有误!"
78 | if step == '':
79 | print("已设置为随机步数(10000-19999)")
80 | step = str(random.randint(10000, 19999))
81 | login_token = 0
82 | login_token, userid = login(user, password)
83 | if login_token == 0:
84 | print("登陆失败!")
85 | if SEND_KEY != '':
86 | sendNotify.send(title="小米运动自动刷步数", msg="【小米运动自动刷步数】\n登陆失败!")
87 | return "login fail!"
88 |
89 | t = get_time()
90 |
91 | app_token = get_app_token(login_token)
92 |
93 | today = time.strftime("%F")
94 |
95 | data_json = '%5B%7B%22data_hr%22%3A%22%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FVv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0v%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0n%5C%2Fa%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1FK%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9PTFFpaf9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0j%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9K%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzf%5C%2F%5C%2F%5C%2F86%5C%2Fzr%5C%2FOv88%5C%2Fzf%5C%2FPf%5C%2F%5C%2F%5C%2F0v%5C%2FS%5C%2F8%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FSf%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fz3%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0r%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F9L%5C%2Fzb%5C%2FSf9K%5C%2F0v%5C%2FRf9H%5C%2Fzj%5C%2FSf9K%5C%2F0%5C%2F%5C%2FN%5C%2F%5C%2F%5C%2F%5C%2F0D%5C%2FSf83%5C%2Fzr%5C%2FPf9M%5C%2F0v%5C%2FOv9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzv%5C%2F%5C%2Fz7%5C%2FO%5C%2F83%5C%2Fzv%5C%2FN%5C%2F83%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fz%5C%2F%5C%2FNv83%5C%2Fzn%5C%2FXv84%5C%2Fzr%5C%2FPP84%5C%2Fzj%5C%2FN%5C%2F9e%5C%2Fzr%5C%2FN%5C%2F89%5C%2F03%5C%2FP%5C%2F89%5C%2Fz3%5C%2FQ%5C%2F9N%5C%2F0v%5C%2FTv9C%5C%2F0H%5C%2FOf9D%5C%2Fzz%5C%2FOf88%5C%2Fz%5C%2F%5C%2FPP9A%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fzz%5C%2FNv87%5C%2F0D%5C%2FOv84%5C%2F0v%5C%2FO%5C%2F84%5C%2Fzf%5C%2FMP83%5C%2FzH%5C%2FNv83%5C%2Fzf%5C%2FN%5C%2F84%5C%2Fzf%5C%2FOf82%5C%2Fzf%5C%2FOP83%5C%2Fzb%5C%2FMv81%5C%2FzX%5C%2FR%5C%2F9L%5C%2F0v%5C%2FO%5C%2F9I%5C%2F0T%5C%2FS%5C%2F9A%5C%2Fzn%5C%2FPf89%5C%2Fzn%5C%2FNf9K%5C%2F07%5C%2FN%5C%2F83%5C%2Fzn%5C%2FNv83%5C%2Fzv%5C%2FO%5C%2F9A%5C%2F0H%5C%2FOf8%5C%2F%5C%2Fzj%5C%2FPP83%5C%2Fzj%5C%2FS%5C%2F87%5C%2Fzj%5C%2FNv84%5C%2Fzf%5C%2FOf83%5C%2Fzf%5C%2FOf83%5C%2Fzb%5C%2FNv9L%5C%2Fzj%5C%2FNv82%5C%2Fzb%5C%2FN%5C%2F85%5C%2Fzf%5C%2FN%5C%2F9J%5C%2Fzf%5C%2FNv83%5C%2Fzj%5C%2FNv84%5C%2F0r%5C%2FSv83%5C%2Fzf%5C%2FMP%5C%2F%5C%2F%5C%2Fzb%5C%2FMv82%5C%2Fzb%5C%2FOf85%5C%2Fz7%5C%2FNv8%5C%2F%5C%2F0r%5C%2FS%5C%2F85%5C%2F0H%5C%2FQP9B%5C%2F0D%5C%2FNf89%5C%2Fzj%5C%2FOv83%5C%2Fzv%5C%2FNv8%5C%2F%5C%2F0f%5C%2FSv9O%5C%2F0ZeXv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1X%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9B%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FTP%5C%2F%5C%2F%5C%2F1b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9N%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%22%2C%22date%22%3A%222020-08-14%22%2C%22data%22%3A%5B%7B%22start%22%3A0%2C%22stop%22%3A1439%2C%22value%22%3A%22UA8AUBQAUAwAUBoAUAEAYCcAUBkAUB4AUBgAUCAAUAEAUBkAUAwAYAsAYB8AYB0AYBgAYCoAYBgAYB4AUCcAUBsAUB8AUBwAUBIAYBkAYB8AUBoAUBMAUCEAUCIAYBYAUBwAUCAAUBgAUCAAUBcAYBsAYCUAATIPYD0KECQAYDMAYB0AYAsAYCAAYDwAYCIAYB0AYBcAYCQAYB0AYBAAYCMAYAoAYCIAYCEAYCYAYBsAYBUAYAYAYCIAYCMAUB0AUCAAUBYAUCoAUBEAUC8AUB0AUBYAUDMAUDoAUBkAUC0AUBQAUBwAUA0AUBsAUAoAUCEAUBYAUAwAUB4AUAwAUCcAUCYAUCwKYDUAAUUlEC8IYEMAYEgAYDoAYBAAUAMAUBkAWgAAWgAAWgAAWgAAWgAAUAgAWgAAUBAAUAQAUA4AUA8AUAkAUAIAUAYAUAcAUAIAWgAAUAQAUAkAUAEAUBkAUCUAWgAAUAYAUBEAWgAAUBYAWgAAUAYAWgAAWgAAWgAAWgAAUBcAUAcAWgAAUBUAUAoAUAIAWgAAUAQAUAYAUCgAWgAAUAgAWgAAWgAAUAwAWwAAXCMAUBQAWwAAUAIAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWREAWQIAUAMAWSEAUDoAUDIAUB8AUCEAUC4AXB4AUA4AWgAAUBIAUA8AUBAAUCUAUCIAUAMAUAEAUAsAUAMAUCwAUBYAWgAAWgAAWgAAWgAAWgAAWgAAUAYAWgAAWgAAWgAAUAYAWwAAWgAAUAYAXAQAUAMAUBsAUBcAUCAAWwAAWgAAWgAAWgAAWgAAUBgAUB4AWgAAUAcAUAwAWQIAWQkAUAEAUAIAWgAAUAoAWgAAUAYAUB0AWgAAWgAAUAkAWgAAWSwAUBIAWgAAUC4AWSYAWgAAUAYAUAoAUAkAUAIAUAcAWgAAUAEAUBEAUBgAUBcAWRYAUA0AWSgAUB4AUDQAUBoAXA4AUA8AUBwAUA8AUA4AUA4AWgAAUAIAUCMAWgAAUCwAUBgAUAYAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAWwAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAeSEAeQ8AcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBcAcAAAcAAAcCYOcBUAUAAAUAAAUAAAUAAAUAUAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCgAeQAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcBgAeQAAcAAAcAAAegAAegAAcAAAcAcAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCkAeQAAcAcAcAAAcAAAcAwAcAAAcAAAcAIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCIAeQAAcAAAcAAAcAAAcAAAcAAAeRwAeQAAWgAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcBoAeScAeQAAegAAcBkAeQAAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAegAAegAAcAAAcAAAcBgAeQAAcAAAcAAAcAAAcAAAcAAAcAkAegAAegAAcAcAcAAAcAcAcAAAcAAAcAAAcAAAcA8AeQAAcAAAcAAAeRQAcAwAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcBEAcA0AcAAAWQsAUAAAUAAAUAAAUAAAUAAAcAAAcAoAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBYAegAAcAAAcAAAegAAcAcAcAAAcAAAcAAAcAAAcAAAeRkAegAAegAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAEAcAAAcAAAcAAAcAUAcAQAcAAAcBIAeQAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBsAcAAAcAAAcBcAeQAAUAAAUAAAUAAAUAAAUAAAUBQAcBYAUAAAUAAAUAoAWRYAWTQAWQAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAMAcAAAcAQAcAAAcAAAcAAAcDMAeSIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBQAeQwAcAAAcAAAcAAAcAMAcAAAeSoAcA8AcDMAcAYAeQoAcAwAcFQAcEMAeVIAaTYAbBcNYAsAYBIAYAIAYAIAYBUAYCwAYBMAYDYAYCkAYDcAUCoAUCcAUAUAUBAAWgAAYBoAYBcAYCgAUAMAUAYAUBYAUA4AUBgAUAgAUAgAUAsAUAsAUA4AUAMAUAYAUAQAUBIAASsSUDAAUDAAUBAAYAYAUBAAUAUAUCAAUBoAUCAAUBAAUAoAYAIAUAQAUAgAUCcAUAsAUCIAUCUAUAoAUA4AUB8AUBkAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAA%22%2C%22tz%22%3A32%2C%22did%22%3A%22DA932FFFFE8816E7%22%2C%22src%22%3A24%7D%5D%2C%22summary%22%3A%22%7B%5C%22v%5C%22%3A6%2C%5C%22slp%5C%22%3A%7B%5C%22st%5C%22%3A1597349880%2C%5C%22ed%5C%22%3A1597369860%2C%5C%22dp%5C%22%3A39%2C%5C%22lt%5C%22%3A294%2C%5C%22wk%5C%22%3A0%2C%5C%22usrSt%5C%22%3A-1440%2C%5C%22usrEd%5C%22%3A-1440%2C%5C%22wc%5C%22%3A0%2C%5C%22is%5C%22%3A169%2C%5C%22lb%5C%22%3A10%2C%5C%22to%5C%22%3A23%2C%5C%22dt%5C%22%3A0%2C%5C%22rhr%5C%22%3A58%2C%5C%22ss%5C%22%3A69%2C%5C%22stage%5C%22%3A%5B%7B%5C%22start%5C%22%3A1698%2C%5C%22stop%5C%22%3A1711%2C%5C%22mode%5C%22%3A4%7D%2C%7B%5C%22start%5C%22%3A1712%2C%5C%22stop%5C%22%3A1728%2C%5C%22mode%5C%22%3A5%7D%2C%7B%5C%22start%5C%22%3A1729%2C%5C%22stop%5C%22%3A1818%2C%5C%22mode%5C%22%3A4%7D%2C%7B%5C%22start%5C%22%3A1819%2C%5C%22stop%5C%22%3A1832%2C%5C%22mode%5C%22%3A5%7D%2C%7B%5C%22start%5C%22%3A1833%2C%5C%22stop%5C%22%3A1920%2C%5C%22mode%5C%22%3A4%7D%2C%7B%5C%22start%5C%22%3A1921%2C%5C%22stop%5C%22%3A1928%2C%5C%22mode%5C%22%3A5%7D%2C%7B%5C%22start%5C%22%3A1929%2C%5C%22stop%5C%22%3A2030%2C%5C%22mode%5C%22%3A4%7D%5D%7D%2C%5C%22stp%5C%22%3A%7B%5C%22ttl%5C%22%3A125%2C%5C%22dis%5C%22%3A82%2C%5C%22cal%5C%22%3A5%2C%5C%22wk%5C%22%3A7%2C%5C%22rn%5C%22%3A0%2C%5C%22runDist%5C%22%3A23%2C%5C%22runCal%5C%22%3A3%7D%2C%5C%22goal%5C%22%3A8000%2C%5C%22tz%5C%22%3A%5C%2228800%5C%22%2C%5C%22sn%5C%22%3A%5C%22e716882f93da%5C%22%7D%22%2C%22source%22%3A24%2C%22type%22%3A0%7D%5D'
96 |
97 | finddate = re.compile(r'.*?date%22%3A%22(.*?)%22%2C%22data.*?')
98 | findstep = re.compile(r'.*?ttl%5C%22%3A(.*?)%2C%5C%22dis.*?')
99 | data_json = re.sub(finddate.findall(data_json)[0], today, str(data_json))
100 | data_json = re.sub(findstep.findall(data_json)[0], step, str(data_json))
101 |
102 | url = f'https://api-mifit-cn.huami.com/v1/data/band_data.json?&t={t}'
103 | head = {
104 | "apptoken": app_token,
105 | "Content-Type": "application/x-www-form-urlencoded"
106 | }
107 |
108 | data = f'userid={userid}&last_sync_data_time=1597306380&device_type=0&last_deviceid=DA932FFFFE8816E7&data_json={data_json}'
109 |
110 | response = requests.post(url, data=data, headers=head).json()
111 | # print(response)
112 | result = f"{user[:4]}****{user[-4:]}: [{now}] 修改步数({step})" + response['message']
113 | print(result)
114 | return result
115 |
116 |
117 | # 获取时间戳
118 | def get_time():
119 | url = 'http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp'
120 | response = requests.get(url, headers=headers).json()
121 | t = response['data']['t']
122 | return t
123 |
124 |
125 | # 获取app_token
126 | def get_app_token(login_token):
127 | url = f"https://account-cn.huami.com/v1/client/app_tokens?app_name=com.xiaomi.hm.health&dn=api-user.huami.com%2Capi-mifit.huami.com%2Capp-analytics.huami.com&login_token={login_token}"
128 | response = requests.get(url, headers=headers).json()
129 | app_token = response['token_info']['app_token']
130 | # print("app_token获取成功!")
131 | # print(app_token)
132 | return app_token
133 |
134 |
135 | if __name__ == "__main__":
136 | # Push Mode
137 | SEND_KEY = os.environ['SEND_KEY']
138 | # 用户名(格式为 13800138000)
139 | user = os.environ['Xiaomi_User']
140 | # 登录密码
141 | passwd = os.environ['Xiaomi_Pw']
142 | # 要修改的步数,直接输入想要修改的步数值,留空为随机步数
143 | step = os.environ['Xiaomi_Bs'].replace('[', '').replace(']', '')
144 |
145 | user_list = user.split('#')
146 | passwd_list = passwd.split('#')
147 | setp_array = step.split('-')
148 |
149 | if len(user_list) == len(passwd_list):
150 | push = ''
151 | for line in range(0, len(user_list)):
152 | if len(setp_array) == 2:
153 | step = str(random.randint(int(setp_array[0]), int(setp_array[1])))
154 | elif str(step) == '0':
155 | step = ''
156 | push += main(user_list[line], passwd_list[line], step) + '\n'
157 | if SEND_KEY == '':
158 | sendNotify.send(title="小米运动自动刷步数", msg="【小米运动自动刷步数】\n" + push)
159 | else:
160 | print('用户名和密码数量不对')
161 |
--------------------------------------------------------------------------------
/icon/DD_bot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/DD_bot.png
--------------------------------------------------------------------------------
/icon/TG_PUSH1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/TG_PUSH1.png
--------------------------------------------------------------------------------
/icon/TG_PUSH2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/TG_PUSH2.png
--------------------------------------------------------------------------------
/icon/TG_PUSH3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/TG_PUSH3.png
--------------------------------------------------------------------------------
/icon/bark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/bark.jpg
--------------------------------------------------------------------------------
/icon/create_new_sync_yaml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/create_new_sync_yaml.png
--------------------------------------------------------------------------------
/icon/git1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git1.jpg
--------------------------------------------------------------------------------
/icon/git10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git10.jpg
--------------------------------------------------------------------------------
/icon/git11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git11.jpg
--------------------------------------------------------------------------------
/icon/git12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git12.jpg
--------------------------------------------------------------------------------
/icon/git13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git13.jpg
--------------------------------------------------------------------------------
/icon/git14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git14.jpg
--------------------------------------------------------------------------------
/icon/git2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git2.jpg
--------------------------------------------------------------------------------
/icon/git3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git3.jpg
--------------------------------------------------------------------------------
/icon/git4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git4.jpg
--------------------------------------------------------------------------------
/icon/git5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git5.jpg
--------------------------------------------------------------------------------
/icon/git6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git6.jpg
--------------------------------------------------------------------------------
/icon/git7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git7.png
--------------------------------------------------------------------------------
/icon/git8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git8.jpg
--------------------------------------------------------------------------------
/icon/git9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/git9.jpg
--------------------------------------------------------------------------------
/icon/new_access_token.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/new_access_token.png
--------------------------------------------------------------------------------
/icon/new_repository_secret.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/new_repository_secret.png
--------------------------------------------------------------------------------
/icon/open_actions_permissions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/open_actions_permissions.png
--------------------------------------------------------------------------------
/icon/reposync_result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/reposync_result.png
--------------------------------------------------------------------------------
/icon/run_reposync_actions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/run_reposync_actions.png
--------------------------------------------------------------------------------
/icon/set_sectet_pat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/set_sectet_pat.png
--------------------------------------------------------------------------------
/icon/set_up_workflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/set_up_workflow.png
--------------------------------------------------------------------------------
/icon/your_new_token.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qq332374857/BlueSkyClouds-My-Actions/f6b9de78c26b8667e556acccfd5fa295b682fefb/icon/your_new_token.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "My-Actions",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "Manga.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/BlueskyClouds/My-Actions.git"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "bugs": {
17 | "url": "https://github.com/BlueskyClouds/My-Actions/issues"
18 | },
19 | "homepage": "https://github.com/BlueskyClouds/My-Actions#readme",
20 | "dependencies": {
21 | "download": "^8.0.0",
22 | "request": "^2.88.2",
23 | "axios": "^0.21.1",
24 | "crypto-js": "^4.0.0",
25 | "request-promise": "^4.2.5",
26 | "got": "^11.7.0",
27 | "tunnel": "0.0.6",
28 | "tough-cookie": "^4.0.0"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | requests
2 | rsa
3 | pytz
4 | python-dateutil
--------------------------------------------------------------------------------