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

发布时间 2023-06-18 06:46:57作者: 晓风晓浪

小介绍,我以前从未编码过,这对我来说看起来非常难,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)