这是一个自动发布推特的脚本,主要由ChatGPT编写,代码很简单,已开源。
由于在对话中透露了我的Twitter API Key,所以这次就不公布对话记录了,只简述一下开发的过程,以及踩到的坑。
我是想做一个类似于“每日大赛”的bot,但是主要针对AI绘画,这是常见的#PromptChallenge形式。
逻辑很简单,大致就是每天发布一个主题,然后请大家在此回复自己与之相关的作品,以便活跃气氛和进行自我展示。
但是我想添加一个特性,就是按字母排列,从A-Z,每天发布一个以当天字母开头的单词做为主题。
比如第一天是A-day,主题就是Apple……以此类推,等Z完成之后,再回到A,选另一个用A开头的词。
词库
首先我要求ChatGPT给我一个词汇列表,要求从A到Z,每个字母给我大约十个简单的、生动的、便于表达的英语单词。
为了便于处理和日后的增补,我让它直接以逗号分隔后给我,在后续的处理中,也提示它去掉多余的回行。
Apple, Adventure, Angel, Artichoke, Astronaut, Airplane, Antique, Autumn, Avalanche, Azure,Ant,
Butterfly, Beach, Bicycle, Bookshelf, Balloon, Bubble, Boat, Bird, Bridge, Bakery,Beetle,
然后,为了自动化和手动增补都不难,我先让它写一个独立的数据处理程序kw.py,将所有这些单词按其首字母分类,整理成一个JSON文件。类似下面这样的结构。
{
"a":
["Apple", "Adventure", "Angel"...],
"b":
[...],
...
}
语句库
数据处理完之后,内容处理还没有完成,我不想每天都说同样的话,所以我让它又写了一个列表的程序list.py。
这个程序将按从字母的数据,每次从相应字母中取出一个单词,套用一个随机语句模板。
语句的模板也是我让ChatGPT来生成的,大约就是同一句话的7种不同的说法。
套用模板后生成的就是每天发布的句子,比如这样:
Let's celebrate A-day with the keyword "Apple".
B-day is here, and the keyword is "Butterfly".
C-day is here, and the keyword is "Cat".
Welcome to D-day! The keyword for today is "Dragon".
...
这一步生成列表的操作说实话有些冗余,其实可以一次处理完成,但是我也想有一个可以编辑和临时调整的余地。
在这一步中踩了好几个坑,浪费了我不少的时间。
我要求ChatGPT每次运行这个程序的时候,都对比一下之前生成的文件,只把新增加的内容添加到列表末尾,以便我以后增加的时候不要将之前的内容打乱。
但是不知为什么,它并没有考虑到模板的区别,只是用第一句the keyword “…为判断指标,导致每次都增补不到位。
当时是半夜,我在迷迷糊糊的状态下写需求,所以只是不断让它调整,没意识到这么点问题它都搞不明白,所以反复折腾了好久。
另外由于在生成JSON的时候,字母的key是用的小写a,而列表时它选用了大写的A,由加上它习惯性的纠错写法,所以有个找不到key的错误一直没有明确提示,直到我认真看代码才发现。
我发现使用AI写代码有个问题就是你可能不会认真去读它写的代码,然而很多问题就出现在这里。
生成图片
我希望根据每个主题,自动生成一张图片,类似这种:

ChatGPT并没有使用我习惯的imageMagick,而是更习惯使用willow,由于功能不复杂,我就使用了它的方法。
在计算字体大小的时候,由于需要适应图片,需要做一个对字号以及文字最终实际大小的判断和调整,它在逻辑上犯了几个错误,包括在最后一步时使用了调整之前的尺寸,所以这一块也是我手动纠正的。
发表推特
终于调试好列表功能已经是第二天早晨了。我以前用AI写过一些自动发推的功能,所以没想到会太费劲。
但因为我使用的是免费的Web端ChatGPT3.5,它对于一些控件的理解可能停留在某个时间段,所以造成了更多的坑。
首先是在使用Tweepy发布推特时,它默认使用Twitter API v1的形式,导致我权限不够。直到我把以前成功的代码发给他参考,它才理解需要用另外一种方法。但是总是不由自主的用回原来的方式,导致方法不兼容。
这一部分最终是我在它写完所有其他逻辑后手动修改的,而且明确强调给它说:以后的修改在这个版本的基础之上,不要改动发布相关的代码。
转推
Twitter的API权限很奇怪,可以自动发原创贴,却好像不能随意转推,转推需要提升权限。
我不想折腾,所以就用发布URL的形式代替转推,反正出来的结构除了文末带着URL之外,整个体验和转推差不太多。
ChatGPT并不太理解,只是反复提醒我注意权限,要遵守推特的规则之类。
但当我提出建议,问“这样行不行”的时候,它还是给了我我需要的结果。
发布
我在发布时记录了发布完的地址,放在一个文件里,然后转推的时候再从这个文件里获取地址,用主号发布出去。
在上传到服务器时,可以方便的让AI告诉我要安装哪些模块,做哪些权限设置,它会精确给出指令,比我这个歪路子对linux只粗懂皮毛的水平强多了。
我的想法是用我的小号定时发布,用主号定时转推。
ChatGPT在编写crontab方面还是很拿手,不需要费什么心。我甚至让它帮我选一个时间点,以便中国、美国和欧洲这三个时区的推友都尽可能在非睡眠时间看到此贴。大约是欧洲时间的晚12点左右,虽然有点晚,但在中国是下午,在美国是早晨。
主号的转推也是出于这个目的,所以沿后12个小时。
调试
除了偶尔很复杂的问题之外,大部分时间你只要把运行时产生的错误粘贴给它,ChatGPT都可以“认识到自己的错误”,并重新题供新的代码,尽管有时反复犯同样的错误。
有时你也可以让它自查,或者重构一次,尽管它的逻辑和知识有时实在太弱智,但只要有耐心去解释,在必要时手动调整并强调,其实还是可以大幅提高编码的靠谱程度的。
在代码到了一定的量之后,我便不要求它提供完整代码,而是只修改具体的函数,这样它犯二的机率会小一点。
由于处理容量的问题,它还经常失忆,不过我发现关键的内容它还记得。
它对于一些第三方模块的不同版本的函数变化也不是很明确,有时需要我手动查询之后告诉它,至少在这个对话中它就会记住了。
比如排序逻辑有问题反复纠结的时候,我会要求它复述一遍它对我需求的理解,看是不是真的和我理解的相同。如果不同,我就调整我表达时的逻辑。
这种感觉有点奇妙,好像是在跟一个“天才白痴”儿童交流一样,你需要让它明白你要什么,同时你要借助它的强大力量和知识,还是蛮好玩的。

开源仓库
仓库地址:
https://github.com/LordDoomed/twt
我把代码上传到了Github,抹掉了我的API key,但是数据文件原样保存在了里面,也做为我自己的记录。
如果你需要使用这个代码,请尽可能修改掉数据,不要和我的一样,最好换别的内容,毕竟列举其实很容易。
如果你没有自己的服务器,可以试着用一些免费的云服务,这里的功能对系统要求应该很低。
或者你有与AI相关的健康的有趣的想法,也可以借用我的服务器,但会需要你的Twitter API Key。
并且,至少需要请我喝杯咖啡……当然如果你爱我也可以直接请啦……
下面是Buy Me a Coffee的链接(我最近才发现的这个网站,使用体验相当好。)