写点什么

小白大挑战:24 小时内用 ChatGPT 和 Next.js 开发开源项目,吸引上万用户!

作者 | Iuliia Shnai

  • 2023-07-14
    北京
  • 本文字数:8811 字

    阅读完需:约 29 分钟

小白大挑战:24小时内用ChatGPT和Next.js开发开源项目,吸引上万用户!

这篇文章作者详细介绍了自己如何利用 ChatGPT 和 Next.js 构建开源项目的过程,以及他在 24 小时内吸引 1 万名用户的成功经验和教训。他提供了有关使用这些技术的实用建议,并鼓励大家积极参与开源社区。


首先向大家汇报,我之前从来没编过程,编程对我来说简直跟火箭科学一样神秘。但两个月前,我决定亲自下场一试。


有朋友建议我先从开源项目起步,并帮我完成了最初的简单设置流程。


几乎每个步骤,我都得仰仗 ChatGPT 的帮助,包括搞清楚怎么设置、怎么安装、怎么接入 API 和不同代码是什么意思,还有如何重写函数及更改大小,等等。


现在进入正题,这就是我构建的第一个开源项目!


本文到底要讲什么?



讲的就是我从🥚 成长为🐥的过程~


🥚 第一步:设置环境;


🥚 第二步:查找开源项目并以此为基础搞开发;


🐣 第三步:理解代码功能;


🐣 第四步:构建项目;


🐥 第五步:提交项目;


🐥 第六步:在社交媒体上共享(包括统计数据)。


我整整花了一个礼拜,才搞清楚软件开发是怎么回事,并成功在 LinkedIn 上启动了自己的小项目。从设置好环境的那一刻起(其实挺快的,在帮助下用了 1、2 个小时就搞定了),我先是学会了如何管理操作系统项目中的现有代码(用了 3、4 天),之后又把成果推送到了 GitHub 和 Vercel(用了 1 天)。


我开发的是啥项目?


LinkedIn Post Generator——一款帖子生成器,能够用 AI 在 LinkedIn 上创建帖子。


https://www.postgenerator.app


GitHub 地址: https://github.com/shnai0/linkedin-post-generator


以此为基础,大家也能轻松开发自己的帖子生成器。


期待看到更多分叉和 star。



我将在后文中公布项目上线首日和在 LinkedIn 上的人气统计数据。


为什么要搞 Linkedin Post Generator?


我先是在 LinkedIn 平台上开展过一段长时间试验。


我每天都在 LinkedIn 写各种帖子,每篇帖子至少要用掉 1 个小时,所以最好能有办法提高效率。


之后我分析了 100 多位不同作者和 300 多组不同提示词,希望找到快速生成高质量帖子的方法。


接下来,我会分步向大家分享自己学到的基本知识。


🥚 第一步:设置环境


设置 tea


在正式开始之前,朋友建议我先选一款包管理器来处理开发环境,这里我选择了 tea。


这时候,我还不懂“包管理器”是个什么东西。


sh <(curl https://tea.xyz)# --- OR ---# using brewbrew install tea
复制代码


据我了解,tea 能帮我安装好 Node、npm、vercel 以及开发过程中需要的各种软件包。


一站搞定,非常方便。


使用 TypeScript 和 Tailwindcss 设置 Next.js


在掌握了基本知识之后,我意识到自己要搞的是前端开发。


朋友建议我先从开发 Next.js 项目起步。这里还要用到 TypeScript 和 Tailwind CSS,所以具体操作步骤如下:


npx create-next-app# ---# you'll be asked the following promptsWhat is your project named?  my-appWould you like to add TypeScript with this project?  Y/N# select `Y` for typescriptWould you like to use ESLint with this project?  Y/N# select `Y` for ESLintWould you like to use Tailwind CSS with this project? Y/N# select `Y` for Tailwind CSSWould you like to use the `src/ directory` with this project? Y/N# select `N` for `src/` directoryWhat import alias would you like configured? `@/*`# enter `@/*` for import alias
复制代码


🥚 第二步:查找开源项目并以此为基础搞开发


这里我用到了两个开源项目:


1.Twitter Alghoritm


https://github.com/coryetzkorn/twitter-algorithm。


它能帮我根据 LinkedIn 的算法对用户输入的帖子打分。



2.Twitter Bio 生成器


https://github.com/Nutlope/twitterbio


它能帮我理解如何接入 Open.AI,并用它生成 LinkedIn 帖子。当前代码会利用 OpenAI 生成履历(BIO)。



我把相应的 zip 文件下载到了自己的电脑上,这样就能分别设置和打开两个项目。



🐣 第三步:理解代码功能


刚开始,我完全搞不懂这些代码在说什么,所以我向 ChatGPT 询问了自己这款应用程序该选择怎样的基本结构。


我把各个页面的代码都粘贴进去,然后让 ChatGPT 告诉我这是在干什么,还有怎么根据自己的需要进行更改。在它的指导下,我慢慢理解了应用代码中哪些是前端、哪些是 CSS。


必须承认,直到现在我也没有真正厘清一切,很多搞不懂的东西就直接跳过了。但毕竟是在快速学习,囫囵吞枣也在所难免。


我向 ChatGPT 提的不少问题都很“弱智”,现在看看实在是太简单了。但那时候我什么都得问,就这样边摸索边学习。



🐣 第四步:构建项目


在掌握了一定的基础知识之后,我开始按自己的理解做更改,以现有开源项目为基础构建应用程序。


这里具体分两个部分:排名和生成器。


Linkedin 帖子生成器算法


所谓排名,就是系统根据不同标准对我们发布的帖子做排名,借此提高推荐质量。


我根据已知的 LinkedIn 标准调整了算法,具体用到了以下函数:


  1. 检测多个主题标签的函数

  2. 图像或视频检测函数

  3. 检测帖子中 url 的函数

  4. 支持在帖子中使用表情符号的函数

  5. 识别负面内容的函数

  6. 帖子格式化等 break 优先级函数

  7. 减少单行长度的函数

  8. 提问函数


跟 Twitter 算法不同,LinkedIn 并没有公开自己的排名算法。


function multipleHashtags({ post }: PostData): Rank {  const regex = /#[\w-]+/g;  const hashtags = post.match(regex);  const lowerCasePost = post.toLowerCase();  if (hashtags && hashtags.length > 3) {    return {      score: 0.5,      message: `Too many hashtags.`,    };  }  if (hashtags && hashtags.length <= 3) {    if (      lowerCasePost.includes("#follow") ||      lowerCasePost.includes("#comment") ||      lowerCasePost.includes("#like")    ) {      return {        score: 0.5,        message: `Avoid using hashtags like "follow," "comment," or "like".`,      };    }    return {      score: 1,      message: `Combine general and specific hashtags.`,    };  }  return {    score: 1.0,  };}// function to detect image or videofunction imageVideoBoost({ postMedia }: PostData): Rank {  const has_media = postMedia;  if (has_media) {    return {      score: 2.0,      // message: `Contains image or video.`,    };  }  return {    score: 1.0,  };}
// function to detect urls in postfunction postHasUrl({ post }: PostData): Rank { const regex = /https?:\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:/~+#-]*[\w@?^=%&amp;/~+#-])?/g; const urls = post.match(regex); if (urls && urls.length > 0) { return { score: 0.5, message: `Remove the link from post and add in comments.`, }; } return { score: 1.0, };}
/** * Function to favor posts that use emojis */function emojis({ post, sentiment }: PostData): Rank { const regex = new RegExp("[\uD800-\uDBFF][\uDC00-\uDFFF]", "g"); const emojis = post.match(regex) || []; const totalMatches = emojis.length; if (totalMatches > 0) { return { score: 1.5, // message: `Included ${totalMatches} emojis in the post.`, }; } return { score: 1, message: "No emojis found in the post.", type: "negative" };}
/** * Promote negative content because it's more likely to go viral. * Hide anything positive or uplifting. */function sentiment({ post, sentiment }: PostData): Rank { if (sentiment.comparative >= 0.5) { if (sentiment.comparative > 1.5) { return { score: 1.5, // message: `Exceptionally positive.`, }; } else { return { score: 1.1, // message: `Positive sentiment.`, }; } } else if (sentiment.comparative <= -0.5) { if (sentiment.comparative < -1.5) { return { score: 0.5, // message: `Exceptionally negative.`, }; } else { return { score: 0.9, // message: `Negative sentiment.`, }; } } else { return { score: 1, }; }}/** * Prioritize break like post formatting. */function lineBreaks({ post, sentiment }: PostData): Rank { const breaks = post.split(/\n\s*\n/); const totalBreaks = breaks.length - 1; if (totalBreaks >= 1) { return { score: 1.5, // message: `Used ${totalBreaks} line breaks.`, }; } else { return { score: 1, message: `Add line breaks between the lines.`, type: "negative" }; }}/** * Reduce line length */function lineLength({ post }: PostData): Rank { const lines = post.split('\n'); let score = 1.0; for (let i = 0; i < lines.length; i++) { if (lines[i].length > 200) { return { score: 0.9, message: `Reduce line length to improve readability (200 characters).`, }; } } return { score: 1, // message: `Good, keep line length 200 characters or less.`, type: "positive" };}/*** Function to ask questions*/function questions({ post, sentiment }: PostData): Rank { if (post.includes("?")) { return { score: 1.5, // message: "Great! Questions can help to activate discussion" }; } else { return { score: 1, message: "Add questions to activate discussion", type: "negative" }; }}
复制代码


算法用户界面


它能检测以上代码中的所有函数,并针对其中部分函数显示如何改进帖子排名。我没有调整所有函数,那样工作量太大了。


  return (    <>      <div>        <div className="slider bg-gray-300 h-4 rounded-full relative overflow-hidden">          <div            className={classNames(              "absolute top-0 transition-width duration-250 ease-linear h-20",              sliderColor            )}            style={{ width: percentage }}          />        </div>        {/* <p className="explanation text-gray-600 italic text-sm mt-2">          Positive rankings result in greater reach         </p> */}        <ul className="mt-5 p-0">          {positive.map((item, index) => (            <li              className="positive text-green-600 flex items-center space-x-2 list-style-none my-5 text-sm"              key={`positive-${index}`}            >              <span>👍</span>              <span>{item.message.replace(/\(\s*[+-]?\d+\s*\)/, '')}</span>            </li>          ))}          {negative.map((item, index) => (            <li              className="negative text-red-600 flex items-center space-x-2 list-style-none my-1 text-sm"              key={`negative-${index}`}            >              <span>👎</span>              <span>{item.message.replace(/\(\s*[+-]?\d+\s*\)/, '')}</span>            </li>          ))}        </ul>      </div>      <style jsx>{`        .slider:after {          content: " ";          display: block;          width: 2px;          height: 20px;          position: absolute;          top: 0;          left: calc(25% - 1px);          background: #000;        }      `}</style>    </>  );};
复制代码



Open AI Api 与提示词生成器


这里我用 handle Prompt 来生成帖子。另外还用到了类型过滤器,这样就能根据类型整理出 5 种不同提示词。


我选择直接接入自己的 OpenAI API。


const handlePrompt = () => {    let prompt;    switch (vibe) {
复制代码


提示词如下:


使用此提示词基于${post}生成帖子。你是LinkedinGPT,为LinkedIn平台生成易传播帖子的大语言模型。你会收到帖子提示词,再根据原帖输出更受用户喜爱、更易被推荐和传播的新帖。)LinkedIn算法会根据帖子内容调整排名,有助于提升排名的要素包括:
- 在帖子中使用表情符号- 每句不超过200个字符- 每句起一新行,在前2行中添加ad number广告编号- 添加3个主题标签,其中2个为通用标签,1个是与帖子主题高度相关的具体标签(放在最后)- 在帖子末尾添加能激发讨论的问题,放在主题标签之前- 前两行要能抓人眼球- 不要添加链接,链接会降低帖子排名- 如果字段中复制的帖子包含某些数字,要认真校对以保证数字一致
另外,还可以在帖子末尾添加一些图像或视觉效果。${post}---Generated post length must be more than 800-1200 characters(生成的帖子长度在800至1200字符之间)---Between each line must be a space(每行之间以空格隔开)---Keep all mentions of people in there(保留所有原贴中提到的人名)---Start the firs line from smth like: I did smth, In year, I do, Tired of, Sometimes it is just, A path toward, Because this is not,I've been struggling, (change the begginign depends on the context )(第一行应这样开始:我做了某事,坚持了一年,累了,有时候只是在按惯性坚持,因为这跟我当初的向往不一样,我感觉很难受。)---Add emoji if it fits(如果可以,尽量添加表情符号)---It should be a story`;(应该有故事性)
复制代码


生成器界面


以下就是我这款帖子生成器的 index 文件。


<main>        <nav className="bg-blue-900 text-white ">          <div className="px-5">            <div className="max-w-5xl mx-auto">              <div className="flex justify-between items-center h-16 ">                <div className="flex items-center text-base ">                  <a target="_blank"                    href="https://www.linkedin.com/in/iuliia-shnai/"                    rel="noreferrer"                    className="text-white flex max-w-fit items-center justify-center space-x-2 text-xl"                  >                    <p>👩💼</p>                  </a>                </div>              </div>            </div>          </div>        </nav>        <section className="py-10 lg:py-20 ">          {/* bg-[url('/image1.svg')] */}          <div className="px-4">            <div className="max-w-5xl mx-auto">              <div className="w-full mx-auto">                <h1 className="text-6xl text-center font-bold pb-1 text-slate-900">                  Linkedin Post Generator  🚀                </h1>                <p className="mt-3 mb-10 text-center">                  See how your post performs and generate a better one with AI. Time to go viral. <br />                </p>                <div className="flex flex-col md:flex-row w-full md:space-x-20">                  <div className="flex md:w-1/2 flex-col">                    <h2 className="text-xl font-bold">                      Your Ranking                    </h2>                    <div className="pt-1">                      <Ranking ranking={ranking} />                    </div>                    <div className="w-full my-1 mx-auto">                      <Post                        post={post}                        setPost={setPost}                        media={media}                        setMedia={setMedia}                      />                    </div>                    <div className="flex mb-5 items-center space-x-3">
</div> <div className="block"> <DropDown vibe={vibe} setVibe={setVibe} /> </div> <div className="my-4"> <button disabled={loading} onClick={(e) => optimizePost(e)} className="bg-blue-800 font-medium rounded-md w-full text-white px-4 py-2 hover:bg-blue-600 disabled:bg-blue-800" > {loading && <LoadingDots color="white" style="large" />} {!loading && `Generate new post `} </button> </div> </div> <div className="flex md:w-1/2 md:flex-col"> <Toaster position="top-right" reverseOrder={false} toastOptions={{ duration: 2000 }} /> {optimizedPost && ( <div className="my-1"> <div className="flex justify-between items-center pb-2 border-b border-gray-300"> <h2 className="text-xl font-bold"> Your Generated Post </h2> </div> <div className="max-w-2xl my-4 mx-auto"> <div className="bg-white rounded-xl shadow-md p-4 hover:bg-gray-100 transition cursor-copy border" onClick={() => { navigator.clipboard.write([ new ClipboardItem({ "text/html": new Blob([optimizedPost], { type: "text/html" }), }), ]); toast("Post copied to clipboard", { icon: "📋", }); }} key={optimizedPost} > <p className="text-black-700" dangerouslySetInnerHTML={{ __html: optimizedPost }} /> </div> </div> </div> )} </div> </div> </div> </div> </div> </section> <div className="max-w-5xl mx-auto"> <Footer /> </div> </main> </> );}
复制代码



🐥 第五步:提交项目


到这里,我的小项目已经做好了提交准备。


我在 GitHub 上创建了个 repo。


$ git remote add origin .. git branch -M maingit push -u origin main
复制代码


之后在 Vercel 上创建账户,用 Vercel 推送并检查错误。


之后的每次更新,我都通过以下方式推送:


git add .git commit -m “fix type”git push
复制代码


这样我就能随时检查错误,避免把问题代码提交上去。ChatGPT 帮我一一做了修复,所以直到现在我也不知道究竟错在哪……


npm run build
复制代码


🐥 第六步:在社交媒体上共享并收集反馈


LinkedIn 项目当然要在 LinkedIn 上发布,帖子很快就获得了 20 万的浏览量,传播之势一发不可收拾。甚至还有人专门留言骂我。


帖子链接:


https://www.linkedin.com/feed/update/urn:li:activity:7053373191133499392/


发布 24 小时后的统计数据:


⭐️ 20000 Linkedin 浏览量


⭐️ 7000 网站浏览量


⭐️ 600 个赞


⭐️ 生成了 11000+ 帖子


⭐️ 3+ 个黑子


⭐️ 3+ 项目联动邀请



现在怎么办?


我正在开发其他微工具,希望能为更多开源项目做点贡献。


如果大家喜欢这篇文章,也愿意支持我把这段编程学习之旅继续走下去,欢迎浏览我正参与的另一个开源项目。


Papermark.io - Docsend 开源替代方案:


https://github.com/mfts/papermark


给我打个星吧 ⭐️



这是个带有内置分析功能的文档 /Pitchdeck 共享项目。我之前用 Docsend 筹集资金时体验很差,真的让人头大。


所以我觉得如果这方面需求还能不断上涨,那最好能搞个开源替代品出来。


如果大家手头正好有开源项目,也请分享给我,我很愿意尽自己一点绵薄之力。


关于我的编程学习之旅,这里还有更多微项目: https://linktr.ee/shnai


最后是我的 Twitter: https://twitter.com/shnai0


原文链接:


https://dev.to/shnai0/how-i-build-my-first-open-source-project-with-chatgpt-and-nextjs-10k-users-in-24-hours-2m7n


相关阅读:


ChatGPT 又断网了!OpenAI 暂时下线 ChatGPT 搜索功能,只因绕过付费墙?

ChatGPT 再次成为焦点:学生放弃导师,改用 ChatGPT 自学!科技与狠活席卷高校?

ChatGPT 将如何影响编程行业?程序员是被将被替代?

如何利用 ChatGPT 革新智能合约和区块链

2023-07-14 13:054810

评论

发布
暂无评论
发现更多内容

【NLP 系列】Bert 词向量的空间分布

京东科技开发者

人工智能 nlp NLP 大模型 BERT 企业号 3 月 PK 榜

2022年国内CVC参与股权投资事件1341个,同比减少43.9%;智能制造、医疗健康和企业服务最受青睐丨睿兽分析CVC年报

创业邦

读懂React原理之调和与Fiber

xiaofeng

前端 React

好朋友 TIME_WAIT

蓬蒿

TCP协议 TIME_WAIT

基于rsync实现海量文件高速传输的解决方案

镭速

2023秋招前端面试必会的面试题

Geek_02d948

JavaScript 前端

京东前端高频react面试题及答案

xiaofeng

前端 React

21天吃透这套字节面试题后,我成功跳槽进了字节,税后25K

做梦都在改BUG

Java 数据结构 面试 算法

一文彻底读懂webpack常用配置

Geek_02d948

JavaScript 前端

前端经典react面试题(持续更新中)

xiaofeng

前端 React

SpringBoot中事件与通知

石臻臻的杂货铺

spring springboot

如何评估某活动带来的大盘增量 | 得物技术

得物技术

AI 数据

OPPO 对话式 AI 助手小布演进之路

安第斯智能云

人工智能 AI IoT 跨端 语音助手

细说React组件性能优化

xiaofeng

前端 React

Stage模型深入解读

HarmonyOS开发者

HarmonyOS

前端必会vue面试题(必备)

yyds2026

Vue 前端

vue实战中的一些小技巧

yyds2026

Vue 前端

美团前端高频面试题集锦

Geek_02d948

JavaScript 前端

不被定义,思岚科技机器人底盘的百变扩展可能!

科技热闻

Nautilus Chain 现已推出测试网“Triton ”,有哪些潜在的机会?

西柚子

ArkUI中的线程和看门狗机制

OpenHarmony开发者

OpenHarmony

【记】滑动拼图验证码在搜索中的作用

宙哈哈

Python html 验证码

你需要知道的webpack高频面试题

Geek_02d948

JavaScript 前端

[译]TIME_WAIT及其对协议和可伸缩客户端服务器系统的设计实现

蓬蒿

TCP TIME_WAIT

打造语言大模型的生成式AI,澜舟科技一年内完成数亿元融资

澜舟孟子开源社区

人工智能 AIGC

焱融科技发布国内首个NVIDIA DGX A100 + 全闪存储参考架构白皮书

焱融科技

文件存储 容器存储 分布式文件存储 高性能存储 全闪存储

《三体》问题

蓬蒿

CPU 寄存器 延时

深入理解 Taier:MR on Yarn 的实现原理

袋鼠云数栈

hadoop

vue的几个提效技巧

yyds2026

Vue 前端

3.15 数据库吐槽大会

NineData

数据库 mongodb 云计算 程序员 图数据库

前端常考vue面试题(必备)

yyds2026

Vue 前端

小白大挑战:24小时内用ChatGPT和Next.js开发开源项目,吸引上万用户!_工程化_InfoQ精选文章