Wenlan
Wenlan is a source-backed AI knowledge base and LLM wiki for AI work: organize documents and decisions into pages you can find, inspect, and review.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Loading the full README. The saved excerpt is shown below.
个人模块化仪表板,将邮件待办、育儿提示、GitHub 活跃度聚合到一个页面。 当前版本:M3 - 育儿 Tips 配置化 架构版本:v0.2 (冻结) 1. 访问 Google Cloud Console 2. 创建新项目或选择现有项目 3. 启用 Gmail API: • 左侧菜单选择「API 和服务」→「已启用的 API 和服务」 • 点击「启用 API 和服务」 • 搜索「Gmail API」并启用 4. 创建 OAuth 客户端 ID: • 左侧菜单选择「API 和服务」→「凭据」 • 点击「创建凭据」→「OAuth 客户端 ID」 • 应用类型选择「Web 应用」 • 授权重定向 URI 添加: • http://localhost:3000/api/auth/callback/google (本地开发) • https://your-domain.com/api/auth/callback/google (生产环境) • 点击「创建」,保存客户端 ID 和客户端密钥Read the full README ↗
个人模块化仪表板,将邮件待办、育儿提示、GitHub 活跃度聚合到一个页面。
当前版本:M3 - 育儿 Tips 配置化
架构版本:v0.2 (冻结)
npm install
复制 .env.example 到 .env.local:
cp .env.example .env.local
http://localhost:3000/api/auth/callback/google (本地开发)https://your-domain.com/api/auth/callback/google (生产环境)http://localhost:3000 (本地开发)http://localhost:3000/api/auth/callback/github (本地开发)https://your-domain.com/api/auth/callback/github (生产环境)权限范围说明:
read:user:读取用户基本信息user:email:读取用户邮箱将凭证填入 .env.local:
AUTH_SECRET=your-random-secret-here-at-least-32-characters
NEXTAUTH_URL=http://localhost:3000
GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
# LINE Messaging API webhook(家庭群 @秋宝管家 -> Grok Bot)
LINE_CHANNEL_SECRET=
GROKBOT_WEBHOOK_URL=
GROKBOT_WEBHOOK_KEY=
# 只转发该群的 @秋宝管家。未配置或为空则一条都不转发
LINE_ALLOWED_GROUP_ID=
生成 AUTH_SECRET:
openssl rand -base64 32
家庭群有人 @秋宝管家 时,未登录的 POST /api/line/webhook 校验 x-line-signature,只把群内文本提及转发给 Grok Bot(本路由不回复 LINE)。生产环境把下列 URL 填到 LINE Developers 的 Webhook:
https://personal-dashboard-pi-nine.vercel.app/api/line/webhook
Vercel 需要配置:LINE_CHANNEL_SECRET、GROKBOT_WEBHOOK_URL、GROKBOT_WEBHOOK_KEY、LINE_ALLOWED_GROUP_ID(只转发该群;未配置或为空则一条都不转发)。
npm run dev
打开浏览器访问 http://localhost:3000
npm run build
npm start
当前包含三个模块:
in:inbox is:unread)https://www.googleapis.com/auth/gmail.readonlypersonalized: false)personalized: true)read:user、user:email(仅读取公开活动)在 modules/ 下创建新的模块目录:
modules/
your-module/
manifest.ts # 模块清单
server.ts # 服务端数据加载
ui.tsx # 卡片 UI 组件
index.ts # 导出模块契约
import type { ModuleManifest } from '@/lib/module-types';
export const manifest: ModuleManifest = {
id: 'your-module',
name: '模块名称',
description: '模块描述',
version: '0.1.0',
defaultEnabled: true,
requires: [], // 依赖的连接器: ['gmail', 'github']
configKeys: [], // 需要的配置键
layout: { minWidth: 'full', priority: 40 }, // priority 越小越靠前
};
import type { ModuleContext, ModuleLoadResult } from '@/lib/module-types';
export type YourModuleData = {
// 定义你的数据类型
};
export async function load(ctx: ModuleContext): Promise<ModuleLoadResult<YourModuleData>> {
// 检查连接器状态
if (!ctx.connectors.someConnector?.ready) {
return { status: 'disconnected', connector: 'someConnector' };
}
// 加载数据
const data: YourModuleData = {
// 你的数据
};
return {
status: 'ok',
data,
fetchedAt: new Date().toISOString(),
};
}
'use client';
import type { ModuleLoadResult } from '@/lib/module-types';
import type { YourModuleData } from './server';
type Props = {
result: ModuleLoadResult<YourModuleData>;
onRefresh: () => void;
};
export function Card({ result, onRefresh }: Props) {
// 处理不同的状态
if (result.status === 'disconnected') {
return <div>未连接</div>;
}
if (result.status === 'error') {
return <div>错误: {result.message}</div>;
}
if (result.status === 'ok') {
return (
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-bold">模块名称</h2>
{/* 你的 UI */}
</div>
);
}
return null;
}
import type { ModuleContract } from '@/lib/module-types';
import { manifest } from './manifest';
import { load } from './server';
import { Card } from './ui';
export const yourModule: ModuleContract = {
manifest,
load,
Card,
};
在 modules/index.ts 中注册新模块:
import { registerModule } from '@/lib/module-registry';
import { yourModule } from './your-module';
export function initializeModules() {
// 现有模块...
registerModule(yourModule);
}
如果需要新的配置项,在 lib/module-types.ts 中更新:
export type ModuleId = 'mail-todos' | 'parenting-tips' | 'github-activity' | 'your-module';
export type UserSettings = {
onboardingCompleted: boolean;
modules: Record<ModuleId, { enabled: boolean }>;
config: {
// 现有配置...
'your.configKey'?: string;
};
};
This is the beginning of the README. Read the rest at the original. Read the full README ↗