好的, 我们来添加 RSS 订阅功能, 评价系统, 以及邮件通知功能。这需要几个步骤:

  1. 添加 RSS 订阅功能
  2. 实现评价系统
  3. 添加邮件发送功能
  4. 实现交互通知

让我们逐步实现这些功能:

  1. 添加 RSS 订阅功能

首先, 安装 RSS 生成库:

bun add feed

然后, 在 src/index.ts 中添加 RSS 生成路由:

import { Feed } from 'feed';
 
// ... 其他导入
 
app.get('/rss', async ({ set }) => {
  const allPosts = await db.select().from(posts).all();
 
  const feed = new Feed({
    title: "My Blog",
    description: "This is my personal blog!",
    id: "http://example.com/",
    link: "http://example.com/",
    language: "en",
    image: "http://example.com/image.png",
    favicon: "http://example.com/favicon.ico",
    copyright: "All rights reserved 2023, Your Name",
    updated: new Date(allPosts[0].createdAt), // use latest post date
    generator: "Feed for Node.js",
    feedLinks: {
      rss2: "http://example.com/rss"
    },
    author: {
      name: "Your Name",
      email: "you@example.com",
      link: "http://example.com/about"
    }
  });
 
  allPosts.forEach(post => {
    feed.addItem({
      title: post.title,
      id: `http://example.com/posts/${post.id}`,
      link: `http://example.com/posts/${post.id}`,
      description: post.content.substring(0, 100) + '...',
      content: post.content,
      author: [
        {
          name: "Your Name",
          email: "you@example.com",
          link: "http://example.com/about"
        }
      ],
      date: new Date(post.createdAt)
    });
  });
 
  set.headers['Content-Type'] = 'application/rss+xml';
  return feed.rss2();
});
  1. 实现评价系统

更新 src/db/schema.ts 以添加评论表:

export const comments = sqliteTable('comments', {
  id: integer('id').primaryKey(),
  postId: integer('post_id').notNull().references(() => posts.id),
  authorEmail: text('author_email').notNull(),
  content: text('content').notNull(),
  createdAt: integer('created_at', { mode: 'timestamp' }).notNull().default(sql`CURRENT_TIMESTAMP`),
});

src/index.ts 中添加评论相关的路由:

app.post('/api/comment', async ({ body }) => {
  const { postId, authorEmail, content } = body as { postId: number, authorEmail: string, content: string };
  const newComment = await db.insert(comments).values({ postId, authorEmail, content }).returning().get();
  return newComment;
});
 
app.get('/api/comments/:postId', async ({ params }) => {
  const postComments = await db.select().from(comments).where(eq(comments.postId, parseInt(params.postId))).all();
  return postComments;
});
  1. 添加邮件发送功能

首先, 安装邮件发送库:

bun add nodemailer

然后, 创建一个新文件 src/utils/mailer. Ts:

import nodemailer from 'nodemailer';
 
const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: parseInt(process.env.SMTP_PORT || '587'),
  secure: process.env.SMTP_SECURE === 'true',
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});
 
export async function sendMail(to: string, subject: string, text: string, html: string) {
  const info = await transporter.sendMail({
    from: '"Your Blog" <noreply@yourblog.com>',
    to,
    subject,
    text,
    html,
  });
 
  console.log('Message sent: %s', info.messageId);
}
  1. 实现交互通知

src/index.ts 中, 当有新评论时发送邮件通知:

import { sendMail } from './utils/mailer';
 
// ... 其他代码
 
app.post('/api/comment', async ({ body }) => {
  const { postId, authorEmail, content } = body as { postId: number, authorEmail: string, content: string };
  const newComment = await db.insert(comments).values({ postId, authorEmail, content }).returning().get();
  
  // 获取文章信息
  const post = await db.select().from(posts).where(eq(posts.id, postId)).get();
  
  // 获取文章作者信息
  const author = await db.select().from(users).where(eq(users.id, post.authorId)).get();
  
  // 发送邮件通知作者
  await sendMail(
    author.email,
    `New comment on your post "${post.title}"`,
    `You have a new comment from ${authorEmail} on your post "${post.title}": ${content}`,
    `<h1>New comment on your post "${post.title}"</h1><p>From: ${authorEmail}</p><p>${content}</p>`
  );
 
  return newComment;
});
  1. 更新 src/components/Blog.tsx 以显示评论和评论表单:
// ... 其他导入
 
interface Comment {
  id: number;
  authorEmail: string;
  content: string;
  createdAt: number;
}
 
export const Blog: React.FC<BlogProps> = ({ posts, user }) => {
  // ... 其他代码
 
  return (
    <div>
      {/* ... 其他JSX */}
      <div id="posts">
        {posts.map(post => (
          <article key={post.id}>
            <h2>{post.title}</h2>
            <div dangerouslySetInnerHTML={{ __html: marked(post.content) }} />
            <small>Created at: {new Date(post.createdAt).toLocaleString()}</small>
            {user && (
              <>
                <button hx-get={`/api/post/${post.id}`} hx-target="closest article" hx-swap="outerHTML">
                  Load Full Post
                </button>
                <button hx-delete={`/api/post/${post.id}`} hx-target="closest article" hx-swap="outerHTML">
                  Delete Post
                </button>
              </>
            )}
            <div hx-get={`/api/comments/${post.id}`} hx-trigger="load">
              Loading comments...
            </div>
            <form hx-post="/api/comment" hx-swap="beforeend" hx-target="closest div">
              <input type="hidden" name="postId" value={post.id} />
              <input type="email" name="authorEmail" placeholder="Your email" required />
              <textarea name="content" placeholder="Your comment" required></textarea>
              <button type="submit">Add Comment</button>
            </form>
          </article>
        ))}
      </div>
    </div>
  );
};
  1. 添加环境变量:

确保在你的环境中设置了以下邮件相关的变量:

SMTP_HOST=your_smtp_host
SMTP_PORT=your_smtp_port
SMTP_SECURE=true_or_false
SMTP_USER=your_smtp_username
SMTP_PASS=your_smtp_password
  1. 运行数据库迁移:
Bun run generate
bun run push

这个实现添加了以下功能:

  1. RSS 订阅功能, 允许用户通过 RSS 阅读器订阅博客更新。
  2. 评论系统, 允许访客对博客文章进行评论。
  3. 邮件通知功能, 当有新评论时, 会自动通知文章作者。

这个实现还可以进一步改进, 例如:

  • 添加评论审核功能, 防止垃圾评论。
  • 实现评论回复功能, 并为回复添加邮件通知。
  • 添加评论分页功能, 以处理大量评论。
  • 实现评论编辑和删除功能。
  • 添加评论者头像支持 (如 Gravatar)。
  • 实现评论点赞功能。
  • 添加评论反垃圾措施, 如验证码或 reCAPTCHA。
  • 优化邮件模板, 使其更美观。
  • 添加邮件退订功能。

记住, 在实际部署时, 你需要确保所有用户输入都经过适当的清理和验证, 以防止 XSS 攻击和其他安全问题。此外, 考虑实现速率限制以防止评论系统被滥用。