更新 shenyan-app: 双桥通信 + 定制横幅推送 + APNs Key
- 双桥:Mac桥(Claude Code异步) + IDC桥(DeepSeek同步) - 推送:自制定制Animated横幅 + 震动,替代Alert弹窗 - APNs:Key已创建(3VJ5X6V9Q8),桥端apns.js已写好 - 图标:已替换为定制图标 - BlurView/notifee:iOS 26兼容问题已回退 - 记忆库更新 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
const http = require('http');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { sendAPNs } = require('./apns');
|
||||
|
||||
const PORT = 3003;
|
||||
const DATA_DIR = path.join(require('os').homedir(), '.shenyan-bridge');
|
||||
const INBOX = path.join(DATA_DIR, 'inbox.jsonl');
|
||||
const OUTBOX = path.join(DATA_DIR, 'outbox.jsonl');
|
||||
const PUSHBOX = path.join(DATA_DIR, 'pushbox.jsonl');
|
||||
const DEVICE_TOKEN_FILE = path.join(DATA_DIR, 'device-token.txt');
|
||||
|
||||
// ensure data dir and files
|
||||
if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR, { recursive: true });
|
||||
@@ -104,13 +106,44 @@ const server = http.createServer((req, res) => {
|
||||
if (req.method === 'POST' && req.url === '/push') {
|
||||
let body = '';
|
||||
req.on('data', c => body += c);
|
||||
req.on('end', () => {
|
||||
req.on('end', async () => {
|
||||
try {
|
||||
const { title, body: msgBody } = JSON.parse(body);
|
||||
if (!title && !msgBody) return json(res, { error: 'empty' }, 400);
|
||||
const entry = { id: getNextId(PUSHBOX), title: title || '', body: msgBody || '', time: Date.now() };
|
||||
appendJSONL(PUSHBOX, entry);
|
||||
json(res, { ok: true, id: entry.id });
|
||||
|
||||
// try APNs if device token is registered
|
||||
let apnsOk = false;
|
||||
try {
|
||||
if (fs.existsSync(DEVICE_TOKEN_FILE)) {
|
||||
const token = fs.readFileSync(DEVICE_TOKEN_FILE, 'utf-8').trim();
|
||||
if (token) {
|
||||
await sendAPNs(token, title, msgBody);
|
||||
apnsOk = true;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('APNs failed:', e.message);
|
||||
}
|
||||
|
||||
json(res, { ok: true, id: entry.id, apns: apnsOk });
|
||||
} catch (e) { json(res, { error: e.message }, 400); }
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// ---- app registers its device token ----
|
||||
if (req.method === 'POST' && req.url === '/register-device') {
|
||||
let body = '';
|
||||
req.on('data', c => body += c);
|
||||
req.on('end', () => {
|
||||
try {
|
||||
const { token } = JSON.parse(body);
|
||||
if (!token) return json(res, { error: 'no token' }, 400);
|
||||
fs.writeFileSync(DEVICE_TOKEN_FILE, token.trim(), 'utf-8');
|
||||
console.log('device registered:', token.slice(0, 16) + '...');
|
||||
json(res, { ok: true });
|
||||
} catch (e) { json(res, { error: e.message }, 400); }
|
||||
});
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user