使用ChatGPT和Next.js构建一个开源项目

394 阅读3分钟

小介绍,我以前从未编码过,这对我来说看起来非常难,2 个月前我决定为什么不现在。🤷‍♀️

我的朋友建议我从开源项目开始,还帮助我完成了最初的简单设置步骤。

我几乎在每一步都使用了 ChatGpt,从弄清楚如何设置、安装、将 API 连接到代码的含义,如何重写函数或更改大小。

现在我要详细介绍一下我构建的第一个项目。

(更|多优质内|容:java567 点 c0m)

第 1 步. 设置环境

摆茶具

在我开始之前,我得到了设置包管理器的建议,比如 tea 来处理开发环境。

🥹 这些词在这一点上仍然是未知的“包管理器”

 sh <(curl https://tea.xyz)
 ​
 # --- OR ---
 # using brew
 brew install tea

当我得到它时,茶会帮助安装 node、npm、vercel 和我开发所需的任何其他包。

所以合而为一。

使用 TypeScript 和 Tailwindcss 设置 Next.js

我有一个基本的了解,即我需要前端。

我被教导从生成一个新的 Next.js 项目开始。同样使用 TypeScript 和 Tailwind CSS,所以请遵循以下步骤:

 npx create-next-app
 ​
 # ---
 # you'll be asked the following prompts
 What is your project named?  my-app
 Would you like to add TypeScript with this project?  Y/N
 # select `Y` for typescript
 Would you like to use ESLint with this project?  Y/N
 # select `Y` for ESLint
 Would you like to use Tailwind CSS with this project? Y/N
 # select `Y` for Tailwind CSS
 Would you like to use the `src/ directory` with this project? Y/N
 # select `N` for `src/` directory
 What import alias would you like configured? `@/*`
 # enter `@/*` for import alias

🥚 第 2 步。查找开源项目并在此基础上构建

我使用了这两个开源项目:

  1. Twitter Alghoritm 所以我可以根据 Linkedin 的算法对用户的帖子输入进行评分。

2.twitterbio

为了分别设置和打开每个项目,我将它们以 zip 格式下载到我的计算机上

🐣 Step.3 弄清楚代码

所以我有点被我所看到的震惊了,一开始我什么都想不通。

所以我做了什么,我向 ChatGPT 询问了我的应用程序的基本结构。

我把里面的每一个页面代码都抄下来,问它是做什么的,基本上就是问怎么修改。所以我开始有了一个更好的主意,应用程序前端在哪里,CSS 在哪里。

我仍然没有完全了解所有内容并且遗漏了这些东西,但我认为这绝对是快速学习。

我向 ChatGPT 提出的一些请求非常基本,现在对我来说真的很清楚,那时我问了所有问题,都是愚蠢的问题。

🐣 Step 4 构建项目

因此,在了解了一些基础知识之后,我继续进行自己的更改。开始在这些项目之上构建应用程序。

它有两部分=排名+生成器

Linkedin 帖子生成器算法

排名是根据不同的标准对您的帖子进行排名,从而提高性能。

我使用以下函数为 Linkedin 已知的内容改编了算法:

  1. 检测多个主题标签的功能
  2. 检测图像或视频的功能
  3. 检测帖子中网址的功能
  4. 支持使用表情符号的帖子的功能
  5. 宣传负面内容的功能
  6. 像后期格式化一样优先中断的功能。
  7. 减少行长度的功能
  8. 提问功能

与 Twitter 算法相比,Linkedin 并不公开。

 // function to detect multiple hashtags
 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 video
 function 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 post
 function 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>
     </>
   );
 };

打开 AI Api 和提示生成器

我使用 handle Prompt 来生成帖子。还有类型过滤器,所以我有 5 个基于类型的不同提示。 我刚刚为此连接了我的 OpenAI API。

 const handlePrompt = () => {
     let prompt;
     switch (vibe) {

下面提示

  prompt = `Generate post using this prompt, based on ${post}.  You are a LinkedinGPT, a large language model that generates viral posts for Linkedin. You are given a prompt of a post and must generate a post that is more likely to be liked and reposted than the original post.
 The Linkedin algorithm contains boosts and demotions based on what you are writing. Positive boosts are:
 ​
 - in each post add emoji
 - 200 characters in sentence maximum
 - Start each sentecnce from new line and ad numbers in first 2 lines
 - add 3 hashtags which 2 are generic and one very specific (at the end) Tags relate to post theme
 - add a question at the end of the post to start a discussion. Before the hashtags
 - first two lines should be catchy
 - Dont add links - links are not good.
 - If post copied in the field contain some numbers keep them the same.
 ​
 Add idea about which image or visual can be added at the end of the post (this text is not counted as part of post)
 ${post}
 ---
 Generated post length must be more than 800-1200 characters
 ---
 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`;

生成器接口

这是我的索引文件。来自帖子生成器。

       <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>
     </>
   );
 }

🐥 Step 5 推送项目

最后一步,我准备好推动了。

我在 GitHub 上创建存储库

 $ git remote add origin .. 
 git branch -M main
 git push -u origin main

并进一步在 Vercel 上创建帐户,用 Vercel 推送它并检查错误。

我推送的每一次更新

 git add .
 ​
 git commit -m “fix type”
 ​
 git push

为了检查我使用的错误,所以我不会推送所有错误。ChatGPT 帮助修复了很多错误,而我什至不知道如何找到它们。

 npm run build

(更|多优质内|容:java567 点 c0m)