126 lines
3.1 KiB
JavaScript
Raw Permalink Normal View History

/**
* Notion API 服务封装
*
* 所有 Notion 数据库读写操作走这里带内存缓存
* 版权国作登字-2026-A-00037559
*/
'use strict';
var Client;
try {
Client = require('@notionhq/client').Client;
} catch (_) {
// 如果 @notionhq/client 未安装,提供降级方案
Client = null;
}
var notion = Client ? new Client({ auth: process.env.NOTION_TOKEN }) : null;
// ====== 内存缓存5分钟有效======
var cache = new Map();
var CACHE_TTL = 5 * 60 * 1000;
function getCached(key) {
var item = cache.get(key);
if (item && Date.now() - item.time < CACHE_TTL) return item.data;
return null;
}
function setCache(key, data) {
cache.set(key, { data: data, time: Date.now() });
}
function clearCache() {
cache.clear();
}
// ====== 查询数据库 ======
async function queryDB(dbId, filter, sorts, pageSize) {
if (!notion) {
throw new Error('Notion client not initialized (NOTION_TOKEN missing or @notionhq/client not installed)');
}
if (!dbId) {
throw new Error('Database ID not provided');
}
pageSize = pageSize || 50;
var cacheKey = JSON.stringify({ dbId: dbId, filter: filter, sorts: sorts, pageSize: pageSize });
var cached = getCached(cacheKey);
if (cached) return cached;
var body = { database_id: dbId, page_size: pageSize };
if (filter) body.filter = filter;
if (sorts) body.sorts = sorts;
var result = await notion.databases.query(body);
setCache(cacheKey, result);
return result;
}
// ====== 写入数据库 ======
async function writeToDB(dbId, properties) {
if (!notion) {
throw new Error('Notion client not initialized');
}
return notion.pages.create({
parent: { database_id: dbId },
properties: properties
});
}
// ====== Notion 属性提取器 ======
function extractRichText(prop) {
if (!prop) return '';
if (prop.type === 'rich_text' && prop.rich_text) {
return prop.rich_text.map(function(t) { return t.plain_text; }).join('');
}
if (prop.type === 'title' && prop.title) {
return prop.title.map(function(t) { return t.plain_text; }).join('');
}
return '';
}
function extractTitle(props) {
for (var key in props) {
var val = props[key];
if (val && val.type === 'title' && val.title) {
return val.title.map(function(t) { return t.plain_text; }).join('');
}
}
return '';
}
function extractNumber(prop) {
if (!prop || prop.type !== 'number') return null;
return prop.number;
}
function extractSelect(prop) {
if (!prop || prop.type !== 'select') return '';
return prop.select ? prop.select.name : '';
}
function extractMultiSelect(prop) {
if (!prop || prop.type !== 'multi_select') return [];
return (prop.multi_select || []).map(function(s) { return s.name; });
}
function extractDate(prop) {
if (!prop || prop.type !== 'date') return '';
return prop.date ? prop.date.start : '';
}
module.exports = {
notion: notion,
queryDB: queryDB,
writeToDB: writeToDB,
clearCache: clearCache,
extractRichText: extractRichText,
extractTitle: extractTitle,
extractNumber: extractNumber,
extractSelect: extractSelect,
extractMultiSelect: extractMultiSelect,
extractDate: extractDate
};