Skip to content
58 changes: 37 additions & 21 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,59 @@ name: "Common airport Checkin"

on:
schedule:
- cron: "0 14 * * *" # scheduled at 06:00 (UTC+8) everyday
- cron: "0 14 * * *" # 每天 UTC 14:00 → 北京时间 22:00(视夏令时可能有1小时偏移)
workflow_dispatch:

env:
RUN_ENV: 'prod'

jobs:
build:
checkin:
runs-on: ubuntu-latest
# if: github.ref == 'refs/heads/master'

steps:
- name: Checkout master
uses: actions/checkout@v2
with:
fetch-depth: 0
# ref: master
- name: Checkout code
uses: actions/checkout@v4 # 建议升级到 v4,更稳定

- name: Set up python
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.10.16
python-version: '3.10'

- name: Random sleep
- name: Random sleep (anti-ban on schedule)
if: github.event_name == 'schedule'
run: sleep $(shuf -i 10-300 -n 1)
run: sleep $(shuf -i 30-480 -n 1) # 30秒~8分钟随机延迟,更自然

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run sign
pip install requests # 如果 requirements.txt 只用到 requests,可直接装
# 如果有 requirements.txt 且内容较多,保留下面这行
# pip install -r requirements.txt

- name: Run airport check-in script
env:
URL: ${{ secrets.URL }}
SCKEY: ${{ secrets.SCKEY }}
EMAIL: ${{ secrets.EMAIL }}
PASSWD: ${{ secrets.PASSWD }}
CONFIG: ${{ secrets.CONFIG }}
run: |
python3 ./main.py
# 机场相关(至少需要 URL 和 CONFIG 之一)
URL: ${{ secrets.URL }}
CONFIG: ${{ secrets.CONFIG }} # 多账号首选方式(推荐)

# 单账号兼容(可选,如果没用 CONFIG 可以 fallback)
EMAIL: ${{ secrets.EMAIL }}
PASSWD: ${{ secrets.PASSWD }}

# 推送方式一:Server酱(旧版/新版 Turbo 均可)
SCKEY: ${{ secrets.SCKEY }}

# 推送方式二:WxPusher(目前最稳定推荐)
WXPUSHER_APPTOKEN: ${{ secrets.WP_APP_TOKEN }} # 注意:你的原名是 WP_APP_TOKEN
WXPUSHER_UID: ${{ secrets.WXPUSHER_UID }}

# 控制推送方式(可选,不填默认 both)
# 可选值:serverchan / wxpusher / both
PUSH_METHOD: ${{ secrets.PUSH_METHOD || 'both' }}

run: python3 ./main.py

- name: Show timestamp (debug)
if: always()
run: date -u +"%Y-%m-%d %H:%M:%S UTC"
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
| 参数 | 是否必须 | 内容 |
| ------------ | ------------ | ------------ |
| CONFIG| 是 | 账号密码 |
| URL| 是 | 机场网址 |
| SCKEY | 否 | Sever酱秘钥 |
<br/>
<b>其中URL的值必须是机场网站的地址,例如:https://example.com</b>,尾部不要加''' / '''号 config写法:一行账号一行密码
<b>其中URL的值必须是机场网站的地址,例如:https://example.com</b>,尾部不要加''' / '''号 CONFIG写法:一行账号一行密码

3. 到`Actions`中创建一个workflow,运行一次,以后每天项目都会自动运行。<br/>
4. 最后,可以到Run sign查看签到情况,同时也会也会将签到详情推送到Sever酱。
133 changes: 85 additions & 48 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,99 @@
import requests, json, re, os

# 机场的地址
url = os.environ.get('URL')
# 配置用户名(一般是邮箱)

config = os.environ.get('CONFIG')
# server酱
SCKEY = os.environ.get('SCKEY')
# Server酱 SCKEY
SCKEY = os.environ.get('SCKEY', '') # 默认空字符串
# WxPusher 配置
WXPUSHER_APPTOKEN = os.environ.get('WXPUSHER_APPTOKEN', '')
WXPUSHER_UID = os.environ.get('WXPUSHER_UID', '')
# 可选推送方式:'serverchan', 'wxpusher', 'both',默认 'both' 如果都配置了
PUSH_METHOD = os.environ.get('PUSH_METHOD', 'both').lower()

login_url = '{}/auth/login'.format(url)
check_url = '{}/user/checkin'.format(url)

def sign(order,user,pwd):
session = requests.session()
global url,SEKEY
header = {
def sign(order, user, pwd):
session = requests.session()
header = {
'origin': url,
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}
data = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}
data = {
'email': user,
'passwd': pwd
}
}
try:
print(f'===账号{order}进行登录...===')
print(f'账号:{user}')
res = session.post(url=login_url, headers=header, data=data).text
print(res)
response = json.loads(res)
print(response['msg'])
# 进行签到
res2 = session.post(url=check_url, headers=header).text
print(res2)
result = json.loads(res2)
print(result['msg'])
content = result['msg']
except Exception as ex:
content = '签到失败'
print(content)
print("出现如下异常%s" % ex)

# 进行推送
pushed = False

# Server酱推送
if (PUSH_METHOD in ['serverchan', 'both']) and SCKEY:
try:
print(f'===账号{order}进行登录...===')
print(f'账号:{user}')
res = session.post(url=login_url,headers=header,data=data).text
print(res)
response = json.loads(res)
print(response['msg'])
# 进行签到
res2 = session.post(url=check_url,headers=header).text
print(res2)
result = json.loads(res2)
print(result['msg'])
content = result['msg']
# 进行推送
if SCKEY != '':
push_url = 'https://sctapi.ftqq.com/{}.send?title=机场签到&desp={}'.format(SCKEY, content)
requests.post(url=push_url)
print('推送成功')
except Exception as ex:
content = '签到失败'
print(content)
print("出现如下异常%s"%ex)
if SCKEY != '':
push_url = 'https://sctapi.ftqq.com/{}.send?title=机场签到&desp={}'.format(SCKEY, content)
requests.post(url=push_url)
print('推送成功')
print('===账号{order}签到结束===\n'.format(order=order))
push_url = 'https://sctapi.ftqq.com/{}.send?title=机场签到&desp={}'.format(SCKEY, content)
resp = requests.post(url=push_url)
print('Server酱推送响应:', resp.text)
if resp.status_code == 200:
print('Server酱推送成功')
pushed = True
else:
print('Server酱推送失败:', resp.status_code)
except Exception as e:
print('Server酱推送异常:', e)

# WxPusher推送
if (PUSH_METHOD in ['wxpusher', 'both']) and WXPUSHER_APPTOKEN and WXPUSHER_UID:
try:
wxpusher_url = "https://wxpusher.zjiecode.com/api/send/message"
payload = {
"appToken": WXPUSHER_APPTOKEN,
"content": content,
"summary": "机场签到", # 可选,微信消息标题
"contentType": 1, # 1=纯文本
"uids": [WXPUSHER_UID]
}
resp = requests.post(wxpusher_url, json=payload)
print('WxPusher响应:', resp.text)
result = resp.json()
if result.get("code") == 1000:
print('WxPusher推送成功')
pushed = True
else:
print('WxPusher推送失败:', result)
except Exception as e:
print('WxPusher推送异常:', e)

if not pushed:
print('未配置有效的推送方式,跳过推送')

print('===账号{order}签到结束===\n'.format(order=order))

if __name__ == '__main__':
configs = config.splitlines()
if len(configs) %2 != 0 or len(configs) == 0:
print('配置文件格式错误')
exit()
user_quantity = len(configs)
user_quantity = user_quantity // 2
for i in range(user_quantity):
user = configs[i*2]
pwd = configs[i*2+1]
sign(i,user,pwd)

configs = config.splitlines()
if len(configs) % 2 != 0 or len(configs) == 0:
print('配置文件格式错误')
exit()
user_quantity = len(configs) // 2
for i in range(user_quantity):
user = configs[i * 2]
pwd = configs[i * 2 + 1]
sign(i, user, pwd)