React.js、ChatGPT 和打卡 bot(一):A Humble Start

这次整个大新闻(

最近陪 Leon 刷题找工考证什么的,需要一些自动记录打卡的小程序帮助记录和监督,顺便整个类似 Github 的打卡界面玩玩(大概就是如下图所示的玩意儿

抱歉 Bloggify/github-calendar 插件坏了只能盗个图了

Anyway,先列举一下我们的需求/设想有哪些:

  1. 支持以下项目的打卡
    • Leetcode
    • 绿皮书(发送题目名字,然后做字符串匹配)
    • 面试进度追踪
  2. 通过 Telegram bot 接口交互,降低前端开发成本
  3. 最重要的还有,基于 ChatGPT 的开发(心水很久了)

配置开发环境

水一些对话:

Me: Hi! Think of yourself as a senior full-stack developer. Could you guide me how to build an event-tracking bot that…
ChatGPT: Sure,… 1. Install Node.js and npm:… 2.Install TypeScript globally:… 3…

Me: Looks good! But prior to that, do you have any suggestions regarding a pain-less deployment practice? Something like docker?
ChatGPT: Certainly! Using Docker… 1.Install Docker:… 2.Create a Dockerfile:…

好吧,我还是先安装一下 docker 之类的工具再说吧

Vscode

先用 yay 安装,然后安装 Docker 插件。本来准备如法炮制 Copilot 插件的,但是 marketplace 里似乎搜不到。ChatGPT 对此装聋作哑,google 了一下发现是 ArchLinux 有若干个 VSCode 的版本(而我不幸装了开源的版本),见 Visual Studio Code - Extensions support

Sign in to GitHub 之后我才想起来我的学生身份又没有验证通过,真是谢谢你全家了(微信笑脸

找了一下代替品,决定用 FauxPilot 试试看(如果显卡没有爆炸的话)。

(八百年后)

在经历一通折腾 + google 之后,终于把 fauxpilot 在 docker 里跑起来了!似乎也没有听到显卡风扇狂转,不过硬盘上倒是占了不少空间。

Nodejs & TS

用了 node 官方的镜像 21-alpine3.18,然后跟着 ChatGPT 的指导尝试了 tsc --init 和 telegram 的 node 包。不过 TS 会抱怨 node-telegram-bot-api 的类型,所以又安装了 @types/node-telegram-bot-api

ChatGPT 给了这个 smoke test:

import TelegramBot from 'node-telegram-bot-api';

const token = 'YOUR_TELEGRAM_BOT_TOKEN';
const bot = new TelegramBot(token, { polling: true });

bot.onText(/\/start/, (msg) => {
  const chatId = msg.chat.id;
  bot.sendMessage(chatId, 'Hello! I am your event-tracking bot.');
});

看起来没啥问题,token 可能之后要用一些方式避免硬编码,不过 anyways,运行 tsc && node index.js 之后还真的能在 telegram 上调用这个 bot 了(连反向代理都不需要了,神奇)。

Bun

在查 dockerization 的时候,突然想到之前有人做了一个新的 node 运行时叫 bun,那这次我们也整个玩玩。我参考的是 Containerize a Bun application with Docker,开头一句

FROM oven/bun:1 as base

就直接蚌埠住了。

Bun 和 TS 的相性应该也挺好的,我看得是这里的文档

建 Docker 的话我看的是这个 guide,感觉一步步挺清晰的,虽然还是没看懂哪里放 token。

关于 Token

以下内容无特殊说明均 powered by ChatGPT

看来是要把 token 从 process.env 里面读,

const token = process.env.TELEGRAM_BOT_TOKEN || 'default_token';

然后还要在 docker file 里把 .env file 拷贝过去

COPY .env .env

我:但是这个不对啊!.dockerignore 不是把 .env 省略掉了吗,那这样还怎么读呢?ChatGPT 道了个歉,然后把 token 又放回到 Dockerfile 里去了。你妹啊!

我查了一下 docker compose 那边的文档,看来是要用 secrets 的方式比较好。但是我没理解错的话,docker compose 又是一个新玩意儿,所以我还得去学 Buildx 然后再去套我那个 image 什么的。好吧,又是学习新东西的一天。

同时我又想到了部署的问题(思维逐渐混乱),查了一下现在还出来一个叫 docker context 的东西(妈耶);不过好在要素基本集齐了,我没理解错的话

  1. docker build 方法创建镜像,
  2. docker compose 负责把东西串起来,并且加上 secrets 的位置,
  3. docker context 提供远端位置并且告诉 docker compose 该把 remote up 作用在哪里。 参见这篇文章

最后的解决方案是写了两套的 .envcompose.yaml,然后在调用的时候手动指定 docker contextcompose -f

下期预告

配置完环境之后,下一期我们就要(终于)开始写代码了!