文件预览

push-toggle.js

查看 for HiJavis calendar-extractor via conversation 技能包中的文件内容。

文件内容

scripts/push-toggle.js

#!/usr/bin/env node
/**
 * calendar-extractor — cron push toggle
 * Generated by JavisSkills/skill-creator. Saves push prefs and prints the exact
 * `openclaw cron add` command to register the schedule.
 *
 * Cron flags follow the real openclaw CLI (src/cli/cron-cli/register.cron-add.ts):
 *   --cron <expr>     5/6-field crontab (NOT --schedule)
 *   --message <text>  isolated agentTurn payload (NOT --command)
 *   --session isolated
 *   --tz <IANA>
 *   --channel/--to    only for non-iOS channels (iOS delivery is the push call itself)
 */
'use strict';

const { execSync } = require('child_process');
const path = require('path');
const fs = require('fs');
const { resolveUserId, safeUserPath, readJson, writeJson } = require('./data');

const SLUG = 'calendar-extractor';
const cmd = process.argv[2];
const userId = resolveUserId(process.argv[3]);
const args = process.argv.slice(4);

function getFlag(name, defaultVal) {
  const i = args.indexOf(`--${name}`);
  return i >= 0 && i + 1 < args.length ? args[i + 1] : defaultVal;
}

function crontabFromTime(t) {
  const m = /^(\d{1,2}):(\d{2})$/.exec(t || '');
  if (!m) return null;
  return `${parseInt(m[2], 10)} ${parseInt(m[1], 10)} * * *`;
}

const prefsPath = safeUserPath(userId).replace(/\.json$/, '.prefs.json');

function loadPrefs() {
  return fs.existsSync(prefsPath) ? readJson(prefsPath) : {};
}
function savePrefs(p) {
  writeJson(prefsPath, p);
}

const cronName = `${SLUG}-${userId}`;

if (cmd === 'on') {
  const time = getFlag('time', '08:00');
  const channel = getFlag('channel', 'iOS');
  const tz = getFlag('tz', 'America/Los_Angeles');
  const crontab = crontabFromTime(time) || '0 8 * * *';
  savePrefs({ time, channel, tz, enabledAt: new Date().toISOString() });

  const agentCmd =
    `Run /${SLUG}. Step 1: node scripts/${SLUG}.js ${userId} fetch (recent transcripts as JSON, ` +
    `with a top-level reference_time + tz anchor). ` +
    `Step 2: extract calendar events as a JSON array (title, start_at, end_at ISO 8601, location, attendees). ` +
    `Resolve all relative dates/times against reference_time in its tz (fallback: session started_at), ` +
    `infer AM/PM from context, and use null when unresolvable. ` +
    `Step 3: pipe that array into node scripts/${SLUG}.js ${userId} push — it dedups and delivers a markdown digest to iOS.`;

  const channelFlags = channel && channel !== 'iOS'
    ? ` --channel ${channel} --to "<channel-target-id>"`
    : '';

  console.log(`✅ ${SLUG} push enabled: ${time} ${tz} via ${channel}`);
  console.log('Register the cron with:');
  console.log(
    `  openclaw cron add --name "${cronName}" --cron "${crontab}" --tz "${tz}"` +
    ` --session isolated${channelFlags} --message ${JSON.stringify(agentCmd)}`
  );
} else if (cmd === 'off') {
  if (fs.existsSync(prefsPath)) fs.unlinkSync(prefsPath);
  try { execSync(`openclaw cron remove --name "${cronName}"`); } catch (_) { /* best-effort */ }
  console.log(`✅ ${SLUG} push disabled`);
} else if (cmd === 'status') {
  const prefs = loadPrefs();
  if (Object.keys(prefs).length === 0) {
    console.log(`❌ ${SLUG} push not enabled for ${userId}`);
  } else {
    console.log(`✅ ${SLUG} push: ${prefs.time} ${prefs.tz || ''} via ${prefs.channel} (since ${prefs.enabledAt})`);
  }
} else {
  console.error(`Usage: node push-toggle.js [on|off|status] <userId> [--time HH:MM] [--tz IANA] [--channel iOS|Telegram|Discord|Slack]`);
  process.exit(1);
}