This commit is contained in:
Hex
2023-02-25 18:49:43 +08:00
parent c0363e5412
commit 20eeed7727
14 changed files with 15 additions and 381 deletions

View File

@@ -1,11 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"

View File

@@ -1,61 +0,0 @@
name: Build image
on:
workflow_dispatch:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: true
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Lower case
id: string
uses: ASzc/change-string-case-action@v5
with:
string: ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: app
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/386
push: true
tags: ${{ steps.string.outputs.lowercase }}:latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
- name: Sync README.md
uses: ms-jpq/sync-dockerhub-readme@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}
readme: "./README.md"
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

View File

@@ -1,31 +0,0 @@
name: Check in
on:
workflow_dispatch:
workflow_run:
workflows: ["Build image"]
types:
- completed
# UTC时间对应Beijing时间 830
schedule:
- cron: "30 0 * * *"
jobs:
run:
runs-on: ubuntu-latest
container:
image: enwaiax/smzdm_bot
env:
ANDROID_COOKIE: ${{ secrets.ANDROID_COOKIE }}
TOKEN: ${{ secrets.TOKEN }}
SK: ${{ secrets.SK }}
USER_AGENT: ${{ secrets.USER_AGENT }}
PUSH_PLUS_TOKEN: ${{ secrets.PUSH_PLUS_TOKEN }}
SC_KEY: ${{ secrets.SC_KEY }}
TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
TG_USER_ID: ${{ secrets.TG_USER_ID }}
steps:
- name: Working
run: |
python /smzdm_bot/main.py

14
.vscode/launch.json vendored
View File

@@ -1,14 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": true,
"envFile": "${workspaceFolder}/.env"
}
]
}

View File

@@ -1,100 +1,5 @@
# 什么值得买每日签到脚本 # 什么值得买每日签到脚本 for 青龙面板
<p>
<img src="https://img.shields.io/github/actions/workflow/status/Chasing66/smzdm_bot/checkin.yml?label=CheckIn">
<img src="https://img.shields.io/github/actions/workflow/status/Chasing66/smzdm_bot/build.yml?label=Build">
<img src="https://img.shields.io/github/license/Chasing66/smzdm_bot">
<img src="https://img.shields.io/docker/pulls/enwaiax/smzdm_bot">
</p>
## 1. 实现功能
- `什么值得买`每日签到
- Github Action 定时执行, **务必自行更改为随机时间**
- 本地 Docker 定时运行
- 通过`pushplus`推送运行结果到微信(不推荐)
- 通过`server酱`推送运行结果到微信
- 通过`telegram bot`推送
- 自定义反代`Telegram Bot API`, [搭建教程](https://anerg.com/2022/07/25/reverse-proxy-telegram-bot-api-using-cloudflare-worker.html)
## 2. 使用方法
### 2.1 Git Action 运行
**务必自行更改为随机时间** **务必自行更改为随机时间**
1. Fork[此仓库项目](https://github.com/Chasing66/smzdm_bot)>, 欢迎`star`~ 按照 config/config_example.toml 例子配置文件生成自己的配置文件 config.toml
2. 修改 `.github/workflows/checkin.yml`里的下面部分, 取消`schedule`两行的注释,自行设定时间
```yaml
# UTC时间对应Beijing时间 930
schedule:
- cron: "30 1 * * *"
```
3. Secret 新增`ANDROID_COOKIE`,`SK` ,`USER_AGENT``TOKEN` [方法详见](#31-手机抓包)
4. (可选) Secret 新增`PUSH_PLUS_TOKEN`用于推送通知, [详见](https://www.pushplus.plus/)
5. (可选) Secret 新增`SC_KEY`用于推送通知, [详见](https://sct.ftqq.com/)
6. (可选) Secret 新增`TG_BOT_TOKEN``TG_USER_ID`用于推送通知
7. (可选) Secret 新增`TG_BOT_API`用于自定义反代的`Telegram Bot API`
### 2.2 本地运行(支持多用户)
参考模板`app/config/config_example.toml`. 复制`app/config/config_example.toml``app/config/config.toml`,并按照需求配置
```bash
python3 -m venv .venv
source .venv/bin/activate
cd app
pip install -r requirements.txt
python main.py
```
### 2.3 本地 docker 运行
`docker-compose.yml`
本地生成一个`.env` 文件, 用于配置 docker-compose.yml 运行所需要的环境变量, 如下:
```
# Cookie
USER_AGENT = ""
ANDROID_COOKIE = ""
SK = ""
TOKEN = ""
# Notification
PUSH_PLUS_TOKEN = ""
SC_KEY = ""
TG_BOT_TOKEN = ""
TG_USER_ID = ""
# 定时设定(可选) 若未设定则随机定时执行
SCH_HOUR=
SCH_MINUTE=
```
## 3. 其它
### 3.1 手机抓包
> 抓包有一定门槛,请酌情尝试.
抓包工具可使用 HttpCanary教程参考[HttpCanary 抓包](https://juejin.cn/post/7177682063699968061)
1. 按照上述教程配置好 HttpCanary
2. 开始抓包,并打开什么值得买 APP
3. 过滤域名为`user-api.smzdm.com`的 post 请求
4. 点击右上角分享,复制 cURL转换 curl 请求为 python 格式,[方法](https://curlconverter.com/)
## 更新日志
- 2022-12-08, 签到失败,浏览器端签到需要滑动验证码认证
- 2023-01-11, 更改`User-Agent``iPhone`后可`bypass`滑块认证
- 2023-01-14, 登录认证失败, 签到失效
- 2023-02-18, 通过安卓端验证登录,感谢[jzksnsjswkw/smzdm-app](https://github.com/jzksnsjswkw/smzdm-app)的思路. 旧版代码查看[old](https://github.com/Chasing66/smzdm_bot/tree/old)分支
- 2023-02-25, 新增`all_reward``extra_reward`两个接口,本地支持多用户运行
## Stargazers over time
[![Stargazers over time](https://starchart.cc/Chasing66/smzdm_bot.svg)](https://starchart.cc/Chasing66/smzdm_bot)

View File

@@ -1,10 +0,0 @@
__pycache__/
.github/
.venv/
.vscode/
config/config.toml
config/cookies.json
.env
.dockerignore
.gitignore
Dockerfile

View File

@@ -1,17 +0,0 @@
FROM python:alpine as builder
RUN apk update && apk add --no-cache tzdata ca-certificates
ADD requirements.txt /tmp/
RUN pip3 install --user -r /tmp/requirements.txt
FROM python:alpine
WORKDIR /smzdm_bot
ENV TZ=Asia/Shanghai
COPY --from=builder /root/.local /usr/local
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
COPY . /smzdm_bot
CMD [ "python", "scheduler.py" ]

View File

@@ -1,87 +0,0 @@
import json
from typing import Dict
from urllib.parse import urljoin
import requests
from loguru import logger
class NotifyBot(object):
def __init__(self, content, title="什么值得买签到", **kwargs: Dict) -> None:
self.content = content
self.title = title
self.kwargs = kwargs
self.push_plus()
self.server_chain()
self.tg_bot()
def push_plus(self, template="html"):
try:
if self.kwargs.get("PUSH_PLUS_TOKEN", None):
PUSH_PLUS_TOKEN = self.kwargs.get("PUSH_PLUS_TOKEN")
else:
logger.info("⚠️ PUSH_PLUS_TOKEN not set, skip PushPlus nofitication")
return
url = "https://www.pushplus.plus/send"
body = {
"token": PUSH_PLUS_TOKEN,
"title": self.title,
"content": self.content,
"template": template,
}
data = json.dumps(body).encode(encoding="utf-8")
headers = {"Content-Type": "application/json"}
resp = requests.post(url, data=data, headers=headers)
if resp.status_code == 200:
logger.info("✅ Push Plus notified")
return resp.json()
except Exception as e:
logger.error(e)
def server_chain(self):
try:
if self.kwargs.get("SC_KEY", None):
SC_KEY = self.kwargs.get("SC_KEY")
else:
logger.info("⚠️ SC_KEY not set, skip ServerChain notification")
return
url = f"http://sc.ftqq.com/{SC_KEY}.send"
data = {"text": self.title, "desp": self.content}
resp = requests.post(url, data=data)
if resp.status_code == 200:
logger.info("✅ Server Chain notified")
return resp.json()
except Exception as e:
logger.error(e)
def tg_bot(self):
try:
if self.kwargs.get("TG_BOT_TOKEN", None) and self.kwargs.get(
"TG_USER_ID", None
):
TG_BOT_TOKEN = self.kwargs.get("TG_BOT_TOKEN")
TG_USER_ID = self.kwargs.get("TG_USER_ID")
else:
logger.info(
"⚠️ TG_BOT_TOKEN & TG_USER_ID not set, skip TelegramBot notification"
)
return
TG_BOT_API = self.kwargs.get("TG_BOT_API", "https://api.telegram.org/")
url = urljoin(TG_BOT_API, f"/bot{TG_BOT_TOKEN}/sendMessage")
headers = {"Content-Type": "application/x-www-form-urlencoded"}
params = {
"chat_id": str(TG_USER_ID),
"text": f"{self.title}\n{self.content}",
"disable_web_page_preview": "true",
}
resp = requests.post(url=url, headers=headers, params=params)
if resp.status_code == 200:
logger.info("✅ Telegram Bot notified")
return resp.json()
except Exception as e:
logger.error(e)

View File

@@ -1,18 +0,0 @@
import os
from random import randint
from apscheduler.schedulers.background import BlockingScheduler
from main import main
if __name__ == "__main__":
main()
SCH_HOUR = os.environ.get("SCH_HOUR", randint(0, 23))
SCH_MINUTE = os.environ.get("SCH_MINUTE", randint(0, 59))
scheduler = BlockingScheduler(timezone="Asia/Shanghai")
scheduler.add_job(main, "cron", hour=SCH_HOUR, minute=SCH_MINUTE)
print("Press Ctrl+{0} to exit".format("Break" if os.name == "nt" else "C"))
try:
scheduler.start()
except (KeyboardInterrupt, SystemExit):
pass

View File

@@ -9,10 +9,3 @@ USER_AGENT = ""
ANDROID_COOKIE = "" ANDROID_COOKIE = ""
SK = "" SK = ""
TOKEN = "" TOKEN = ""
[notify]
PUSH_PLUS_TOKEN = ""
SC_KEY = ""
TG_BOT_TOKEN = ""
TG_USER_ID = ""

View File

@@ -1,14 +0,0 @@
version: "3.9"
services:
smzdm_bot:
image: enwaiax/smzdm_bot
container_name: smzdm_bot
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "1m"
max-file: "1"
env_file:
- ${ENVIROMENT}.env
entrypoint: "sleep infinity"

View File

@@ -1,3 +1,8 @@
"""
0 8 * * * smzdm_checkin.py
const $ = new Env("什么值得买签到");
"""
import hashlib import hashlib
import os import os
import random import random
@@ -8,7 +13,7 @@ from pathlib import Path
import prettytable as pt import prettytable as pt
import requests import requests
from loguru import logger from loguru import logger
from notify.notify import NotifyBot from notify import send
from utils.file_helper import TomlHelper from utils.file_helper import TomlHelper
CURRENT_PATH = Path(__file__).parent.resolve() CURRENT_PATH = Path(__file__).parent.resolve()
@@ -74,11 +79,11 @@ class SmzdmBot(object):
tb.add_row([checkin_num, gold, point, exp, rank, cards]) tb.add_row([checkin_num, gold, point, exp, rank, cards])
logger.info(f"\n{tb}") logger.info(f"\n{tb}")
msg = f"""\n⭐签到成功{checkin_num} msg = f"""\n⭐签到成功{checkin_num}
🏅金币{gold} 🏅金币{gold}
🏅积分{point} 🏅积分{point}
🏅经验{exp} 🏅经验{exp}
🏅等级{rank} 🏅等级{rank}
🏅补签卡{cards}""" 🏅补签卡{cards}"""
return msg return msg
else: else:
logger.error("Faile to sign in") logger.error("Faile to sign in")
@@ -140,11 +145,6 @@ def conf_kwargs():
"SK": os.environ.get("SK"), "SK": os.environ.get("SK"),
"ANDROID_COOKIE": os.environ.get("ANDROID_COOKIE"), "ANDROID_COOKIE": os.environ.get("ANDROID_COOKIE"),
"TOKEN": os.environ.get("TOKEN"), "TOKEN": os.environ.get("TOKEN"),
"PUSH_PLUS_TOKEN": os.environ.get("PUSH_PLUS_TOKEN", None),
"SC_KEY": os.environ.get("SC_KEY", None),
"TG_BOT_TOKEN": os.environ.get("TG_BOT_TOKEN", None),
"TG_USER_ID": os.environ.get("TG_USER_ID", None),
"TG_BOT_API": os.environ.get("TG_BOT_API", None),
} }
conf_kwargs.update({"env_conf": True}) conf_kwargs.update({"env_conf": True})
else: else:
@@ -165,13 +165,13 @@ def main(conf_kwargs):
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
continue continue
NotifyBot(content=msg, **conf_kwargs["notify"]) send("什么值得买签到", msg)
else: else:
bot = SmzdmBot(conf_kwargs) bot = SmzdmBot(conf_kwargs)
msg = bot.checkin() msg = bot.checkin()
bot.all_reward() bot.all_reward()
bot.extra_reward() bot.extra_reward()
NotifyBot(content=msg, **conf_kwargs) send("什么值得买签到", msg)
if msg is None or "Fail to login in" in msg: if msg is None or "Fail to login in" in msg:
logger.error("Fail the Github action job") logger.error("Fail the Github action job")
sys.exit(1) sys.exit(1)

View File

@@ -1,6 +1,5 @@
import toml import toml
class TomlHelper: class TomlHelper:
def __init__(self, toml_filename): def __init__(self, toml_filename):
self.t_dict = dict() self.t_dict = dict()