157 lines
4.5 KiB
JavaScript
157 lines
4.5 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Notion Page Watcher
|
|
* Monitors a Notion page for changes and suggests next actions
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { getPage, getAllBlocks, blocksToMarkdown, normalizeId } = require('./notion-to-md.js');
|
|
|
|
const STATE_FILE = path.join(__dirname, '../memory/notion-watch-state.json');
|
|
|
|
// Load watch state
|
|
function loadState() {
|
|
if (!fs.existsSync(STATE_FILE)) {
|
|
return { pages: {} };
|
|
}
|
|
return JSON.parse(fs.readFileSync(STATE_FILE, 'utf8'));
|
|
}
|
|
|
|
// Save watch state
|
|
function saveState(state) {
|
|
const dir = path.dirname(STATE_FILE);
|
|
if (!fs.existsSync(dir)) {
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
}
|
|
fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2), 'utf8');
|
|
}
|
|
|
|
// Check a specific page for changes
|
|
async function checkPage(pageId, localPath) {
|
|
try {
|
|
// Normalize pageId to handle different formats
|
|
const normalizedPageId = normalizeId(pageId);
|
|
|
|
const state = loadState();
|
|
const pageState = state.pages[normalizedPageId] || {};
|
|
|
|
// Fetch current page state
|
|
const page = await getPage(normalizedPageId);
|
|
const lastEditedTime = page.last_edited_time;
|
|
const title = page.properties?.title?.title?.[0]?.plain_text || 'Untitled';
|
|
|
|
// Check if page was edited since last check
|
|
const hasChanges = !pageState.lastEditedTime ||
|
|
new Date(lastEditedTime) > new Date(pageState.lastEditedTime);
|
|
|
|
const result = {
|
|
pageId: normalizedPageId,
|
|
title,
|
|
lastEditedTime,
|
|
hasChanges,
|
|
localPath,
|
|
actions: []
|
|
};
|
|
|
|
if (hasChanges) {
|
|
// Fetch blocks and convert to markdown
|
|
const blocks = await getAllBlocks(normalizedPageId);
|
|
const notionMarkdown = blocksToMarkdown(blocks);
|
|
|
|
// Compare with local file if it exists
|
|
let localMarkdown = '';
|
|
let localDiffers = false;
|
|
|
|
if (fs.existsSync(localPath)) {
|
|
localMarkdown = fs.readFileSync(localPath, 'utf8');
|
|
// Simple comparison (could be enhanced with proper diff)
|
|
localDiffers = localMarkdown.trim() !== notionMarkdown.trim();
|
|
}
|
|
|
|
result.notionMarkdown = notionMarkdown;
|
|
result.localDiffers = localDiffers;
|
|
result.blockCount = blocks.length;
|
|
|
|
// Suggest actions
|
|
if (pageState.lastEditedTime) {
|
|
result.actions.push(`📝 Page edited since last check (${new Date(pageState.lastEditedTime).toLocaleString()})`);
|
|
} else {
|
|
result.actions.push('🆕 First time checking this page');
|
|
}
|
|
|
|
if (localDiffers) {
|
|
result.actions.push(`⚠️ Local markdown differs from Notion version`);
|
|
result.actions.push(`💡 Suggested: Sync Notion → markdown to update local file`);
|
|
}
|
|
|
|
// Update state
|
|
pageState.lastEditedTime = lastEditedTime;
|
|
pageState.lastChecked = new Date().toISOString();
|
|
pageState.title = title;
|
|
state.pages[normalizedPageId] = pageState;
|
|
saveState(state);
|
|
|
|
} else {
|
|
result.actions.push('✓ No changes since last check');
|
|
}
|
|
|
|
return result;
|
|
|
|
} catch (error) {
|
|
return {
|
|
pageId: normalizeId(pageId),
|
|
error: error.message,
|
|
actions: [`❌ Error checking page: ${error.message}`]
|
|
};
|
|
}
|
|
}
|
|
|
|
// CLI interface
|
|
async function main() {
|
|
const args = process.argv.slice(2);
|
|
|
|
// Get page ID and local path from args or environment
|
|
let pageId = args[0];
|
|
let localPath = args[1];
|
|
|
|
// Fallback to environment variables if not provided
|
|
if (!pageId) pageId = process.env.NOTION_WATCH_PAGE_ID;
|
|
if (!localPath) localPath = process.env.NOTION_WATCH_LOCAL_PATH;
|
|
|
|
if (!pageId || !localPath) {
|
|
console.error(`Usage: watch-notion.js <page-id> <local-path>
|
|
|
|
Arguments:
|
|
page-id Notion page ID to monitor
|
|
local-path Local markdown file path for comparison
|
|
|
|
Environment variables (optional):
|
|
NOTION_WATCH_PAGE_ID Default page ID
|
|
NOTION_WATCH_LOCAL_PATH Default local path
|
|
|
|
Examples:
|
|
node watch-notion.js "abc123..." "/path/to/draft.md"
|
|
|
|
# Using environment variables
|
|
export NOTION_WATCH_PAGE_ID="abc123..."
|
|
export NOTION_WATCH_LOCAL_PATH="/path/to/draft.md"
|
|
node watch-notion.js
|
|
`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const result = await checkPage(pageId, localPath);
|
|
console.log(JSON.stringify(result, null, 2));
|
|
return result;
|
|
}
|
|
|
|
if (require.main === module) {
|
|
main().catch(err => {
|
|
console.error('Fatal error:', err);
|
|
process.exit(1);
|
|
});
|
|
} else {
|
|
module.exports = { checkPage };
|
|
}
|