科技

AI写个代码:Serverless Telegram Bot

最开始

Serverless最大的好处,就是不用操心工程和运行环境,而 Cloudflare 免费的额度,对所有非商用场景,都足够足够了。

计划用 Telegram Bot 作为前端,帮助自己记录一些需要周期性打卡的事儿。作为既没有写过 Worker,也没有用过 D1 的前端苦手,自然是 AI 搭手干活啦。

本程序基于 Serverless 架构的 Cloudflare Worker 和 D1 基于 SQLite 的边缘数据库产品。

image.png

开局

起手 Prompt 开局。

请使用 Cloudflare Workers 和 Cloudflare D1 数据库,绑定 Telegram Bot,实现一个如下功能的机器人打卡助手。

在 D1 中建立一张 count_log 表,表结构如下:

CREATE TABLE IF NOT EXISTS count_log (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    count_name TEXT NOT NULL,
    count_type TEXT,
    count_value INTEGER NOT NULL,
    count_date DATE NOT NULL
);

- 机器人接收到的聊天文本信息,进行解析。识别出命令和参数。
- 根据不同的命令,实现不同功能。

### 第一个命令:打卡

会在后台对{内容}这个名词进行一次打卡,记录当天的日期,并返回截止当前打卡的总次数。

例子: 打卡 俯卧撑
输出: 俯卧撑打卡成功,累计打卡 1 次

### 第二个命令:重置打卡

会在后台对{内容}这个名词,重置之前的打卡次数为 0,并记录这一次重置的日期。

例子: 重置打卡 俯卧撑
输出: 重置打卡成功,俯卧撑累计打卡 0 次

### 第三个命令:查询打卡历史

会展示记录过的最近 30 次{内容}这个名字的计数记录,包括重置的记录(如果有)。

例子:查询打卡历史 俯卧撑
输出:
> 俯卧撑 2023-09-01
> 俯卧撑 2023-09-02

请提供完整的代码,对应的工程目录结构。

输出的第一版代码:

// index.js

addEventListener('fetch', event => {

event.respondWith(handleRequest(event.request))

})

async function handleRequest(request) {

if (request.method === 'POST') {

let body = await request.text()

let message = JSON.parse(body).message

let chatId = message.chat.id

let text = message.text

let response = await handleCommand(chatId, text)

return new Response(response, {

headers: {

'Content-Type': 'application/json'

}

})

}

return new Response('OK')

}

async function handleCommand(chatId, text) {

let words = text.split(' ')

let command = words[0]

let name = words.slice(1).join(' ')

let responseText

switch(command) {

case '/打卡':

responseText = await countLog(chatId, name, '打卡')

break

case '/重置打卡':

responseText = await resetCount(chatId, name)

break

case '/查询打卡历史':

responseText = await getHistory(chatId, name)

break

default:

responseText = '未识别的命令'

}

return JSON.stringify({

method: 'sendMessage',

chat_id: String(chatId),

text: responseText

})

}

// 连接数据库

const db = D1.table('count_log')

// 打卡

async function countLog(chatId, name, type) {

let date = new Date().toISOString().slice(0, 10)

// 查询今天是否已经打卡

let result = await db.get(name, date)

if (result) {

// 如果今天已经打卡,累加次数

await db.put(name, date, {

count_value: result.count_value + 1

})

} else {

// 如果今天还没打卡,插入新记录

await db.insert({

count_name: name,

count_type: type,

count_value: 1,

count_date: date

})

}

// 查询最新次数

result = await db.get(name, date)

return `${name}打卡成功,累计打卡${result.count_value}次`

}

// 重置打卡次数

async function resetCount(chatId, name) {

let date = new Date().toISOString().slice(0, 10)

await db.insert({

count_name: name,

count_type: '重置',

count_value: 0,

count_date: date

})

return `重置打卡成功,${name}累计打卡0次`

}

// 查询打卡历史

async function getHistory(chatId, name) {

let records = await db.filter(record => record.count_name === name)

.sortBy('count_date')

.reverse()

.limit(30)

let history = records.map(record => {

return `${record.count_name} ${record.count_date}`

}).join('\n')

return history

}

这样,就有了初始版本的代码框架,基本的代码功能(虽然很多 API 其实不能用)。

细节功能的例子

具体功能的 Prompt

请使用Javascript实现一个解析命令行文本的功能。

要求:

- 接受一个字符串
- 对这个字符串做解析,能识别命令和参数
- 根据不同的命令,调用不同的方法

SQL 编写的例子

写 SQL 的 Prompt

SQLite 中有这样一张表

---
CREATE TABLE IF NOT EXISTS count_log (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    count_name TEXT NOT NULL,
    count_type TEXT,
    count_value INTEGER NOT NULL,
    count_date DATE NOT NULL
);
---

帮我写一个 SQL,统计所有 id 大于最后一个 count_type = 'reset' 的记录的count_value的总和。如果不存在count_type = 'reset'的记录,则返回所有满足条件的记录。

其余细节

总之,作为一个对 JS 完全不熟悉的人,很快就能构件一个基础功能完备的工程。在没有 AI 的时候,可能需要超过 10 小时摸索才能搞定的小工程,如今 2-3 小时足以。

以下是样例:

image.png

最后

感谢 Cloudflare,业界良心。免费的提供了足够大部分人构件任何系统的基础设施。

本程序基于 Claude 编写,因为 ChatGPT 的模型构建的时候, Cloudflare D1 还没有发布。

Github 仓库在 这里

Powered by Hugo · Theme 玄墨 Xuanmo