天天看點

使用ChatGPT和Next.js建構一個開源項目

作者:曉楓Motivation

小介紹,我以前從未編碼過,這對我來說看起來非常難,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.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?/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)

繼續閱讀