使用Astro快速搭建GPTs导航站「提供6800+GPTs数据包」

797 阅读4分钟

Github

github.com/CH563/gtps-…

如使用README的Vercel一键部署,只需看数据库创建这一步 #

效果预览:

image-white.png

Logo & 界面设计全来自于 ChatGPT 的 DALL·E

选用Astro,主要是轻量级快速开发,性能满分

page-speed.png

初始化项目

  1. 使用官方模版
pnpm create astro@latest
  1. 安装TailwindCss
pnpm astro add tailwind
  1. 安装Vercel和数据库工具 - 白嫖Vercel免费服务器
pnpm astro add vercel
pnpm add @vercel/postgres
  1. 运行服务 - 访问 http://localhost:4321/
pnpm run dev

简单几步项目就运行起来了

爬取GPTs数据

发布会了,大量的GPTs被创建出来,创意的GPTs非常多

现在只需从Google里爬取即可,搜索 「site:chat.openai.com/g/」 ,即可以看到所有收录的GPTs应用

如需获取ai画画分类的话,搜索 「site:chat.openai.com/g/ Drawing」

WX20231120-202441.png

爬虫工具使用: github.com/bda-researc…

支持使用了Cheerio/JSDOM来操作标签

也可以使用已经爬取的6800+的数据包: GPTs数据包

数据库

白嫖Vercel免费服务器,同时也使用免费的256M的 Postgres 数据库。

image.png

创建完成后,复制环境变量信息到项目的.env文件

image.png

在Vercel的Postgres页面的Query下快速创建三个表

image.png

  1. GPTs数据存储表
CREATE TABLE "public"."gpts_lists" (
    "id" int8 NOT NULL,
    "title" varchar,
    "url" varchar,
    "icon" varchar,
    "author" varchar,
    "description" text,
    "content" text,
    "twitter" varchar,
    "youtube" varchar,
    "category" varchar,
    "weights" int4 DEFAULT 0,
    "scores" int4 DEFAULT 0,
    "created_titme" timestamptz DEFAULT now(),
    "search_key" varchar,
    PRIMARY KEY ("id")
);
  1. 分类信息表
-- Sequence and defined type
CREATE SEQUENCE IF NOT EXISTS categories_id_seq;

-- Table Definition
CREATE TABLE "public"."categories" (
    "id" int4 NOT NULL DEFAULT nextval('categories_id_seq'::regclass),
    "categories_name" varchar(255) NOT NULL,
    PRIMARY KEY ("id")
);
  1. GPTs数据与分类的关系表,一个GPTs可以对应1-3个分类,多对多的关系
CREATE TABLE "public"."list_categories" (
    "list_id" int4 NOT NULL,
    "category_id" int4 NOT NULL,
    CONSTRAINT "list_categories_category_id_fkey" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id"),
    CONSTRAINT "list_categories_list_id_fkey" FOREIGN KEY ("list_id") REFERENCES "public"."gpts_lists"("id"),
    PRIMARY KEY ("list_id","category_id")
);

下载数据包INSERT数据: GPTs数据包

开发API接口

按照Astro的目录规定,在pages/api创建文件即是api接口

设计了4个接口,外加1个提供给创建GPTs时自定义Actions事件使用的search接口

分类查询接口:GET /api/categories

  • 全量获取所有分类

GPTs列表查询接口: GET /api/get

  • 获取GPTs数据
  • 参数:page - 用于翻页
  • 参数:cate - 分类ID,用于查询分类下的数据
  • 参数:keyword - 关键字搜索

GPTs列表总数接口: GET /api/get-count

  • 获取GPTs数据总数,跟列表拆分,主要是怕数据量多时,查COUNT会导致列表数据返回慢
  • 参数:cate - 分类ID,用于查询分类下的数据
  • 参数:keyword - 关键字搜索

GPTs详情: GET /api/get-by-key

  • 获取GPTs详情,使用key字段,是想让URL更有语义,也把key加了数据库索引
  • 参数:key - 对应的是列表数据的search_key

GPTs搜索:POST /api/search.json

  • 提供创建自定义GPTs的Actions使用
  • 接口创建使用openapi的格式复制Actions里即可,如下展示通过助手对话查找GPTs:

image.png

chat.openai.com/g/g-RftUD9s…

页面开发

Astro 以.astro后缀命名,语法与 JSX 语法相似。支持使用所有主流的UI框架

为了轻量开发,直接使用了astro模版语法来做SSR,数据是在服务器端读取,渲染到前端显示

前端的异步请求,使用原生JS来做交互处理,页面上实现了

  • 关键字搜索
  • 分类切换时数据请求和页面渲染
  • 分页数据加载与渲染

分类数据渲染模块 Categories.astro

---
let lists = [{id:0,categories_name:'👌 All'},{id:-1,categories_name:'🔥 Popular'}];
const searchVal = Astro.url.searchParams.get('s') || '';
const response = await fetch(`${Astro.url.origin}/api/categories`);
if (response.ok) {
    const json = await response.json();
    lists.push(...json.data.lists);
}
---

<div id="categories" class="flex gap-2 flex-wrap py-4 text-sm [&_[data-status=active]]:bg-green-800 [&_[data-status=active]]:text-white [&_[data-status=active]]:border-green-800">
{
    lists.map((item: {id: number, categories_name: string}) => (
        <button data-status={(item.id === 0 && !searchVal) && 'active'} data-id={item.id} class="border rounded-lg px-4 py-1 bg-white hover:border-green-600 hover:text-green-600 dark:bg-black dark:border-gray-700 dark:hover:border-green-600">{item.categories_name}</button>
    ))
}
</div>

Astro 组件的两个代码围栏(---)之间的 frontmatter 组件脚本内部定义本地 JavaScript 变量。然后,可以使用类似 JSX 的表达式将这些变量注入到组件的 HTML 模板中!

轻量的模版语法,使用起来非常爽

更多查看仓库源码:github.com/CH563/gtps-…

部署

项目开发完成后,提交到githud

登录到Vercel,添加新项目:

image.png

选择提交上的项目,「Import」

image.png

因为已使用Astro安装了Vercel,Vercel自动配置Astro Preset

image.png

环境变量记得检查不要漏添加,不然数据库无法读取

image.png

致此,Astro就完成并部署上线了

好久没写博文了,以上只是记录了体验Astro使用和Vercel部署,如有问题或建议请指正,谢谢大家!

查看仓库源码:github.com/CH563/gtps-…