چگونه اولین پروژه منبع باز خود را با ChatGPT و Next.js بسازم. 10 هزار کاربر در 24 ساعت 🤯

مقدمه کوچکی بود، من قبلا هرگز کدنویسی نکرده بودم و به نظرم خیلی سخت بود و 2 ماه پیش تصمیم گرفتم که چرا الان نه.🤷♀️
دوستانم به من پیشنهاد دادند که با پروژه های متن باز شروع کنم و همچنین در اولین قدم های ساده برای راه اندازی به من کمک کردند.
من از ChatGpt عملاً برای هر حرکتی که از نحوه تنظیم smth، نصب، اتصال API به معنای کد، نحوه بازنویسی توابع یا تغییر اندازه ها انجام دادم، استفاده کردم.
حالا در مورد اولین پروژه ای که ساختم کمی بیشتر می گویم.
در این مقاله چه خواهید یافت؟
من در حال تکامل از 🥚 به 🐥 هستم
🥚 مرحله 1. تنظیم محیط
🥚 مرحله 2. پروژه های متن باز را پیدا کنید و در بالا بسازید
🐣 مرحله 3 کشف کد
🐣 مرحله 4 ساخت پروژه
🐥 مرحله 5 فشار دادن پروژه
🐥 مرحله 6. اشتراک گذاری در شبکه های اجتماعی (آمار اینجا)
پروژه ای که می سازم چیست؟
Linkedin Post Generator – مولد پست برای ایجاد هوش مصنوعی تولید شده برای Linkedin. https://www.postgenerator.app
در GitHub https://github.com/shnai0/linkedin-post-generator
در زیر تمام آمار روزهای اول راه اندازی و ویروسی شدن در لینکدین را به اشتراک می گذارم.
چرا Linkedin Post Generator؟
ابتدا مدتی بود که با پلتفرم لینکدین آزمایش می کردم.
من زمان زیادی را برای نوشتن پست در لینکدین صرف می کنم، مانند حداقل 1 ساعت در هر پست و به میانبر فکر می کردم.
بنابراین، من بیش از 100 سازنده مختلف و بیش از 300 پیام مختلف را تجزیه و تحلیل کردم تا راههایی برای ایجاد سریعتر پستهای مؤثرتر پیدا کنم.
بنابراین، در اینجا من می خواهم اصول اولیه کاری را که انجام دادم گام به گام به اشتراک بگذارم.
🥚 مرحله 1. تنظیم محیط
چای را تنظیم کنید
قبل از شروع، توصیه میکنم یک مدیر بسته راهاندازی کنم، مانند چای برای مدیریت محیط توسعه.
🥹 این کلمات هنوز ناشناخته هستند “یک مدیر بسته”
sh <(curl https://tea.xyz)
# --- OR ---
# using brew
brew install tea
همانطور که من آن را دریافت می کنم کمک چای برای نصب node، npm، vercel و هر بسته دیگری که برای توسعه نیاز دارم.
بنابراین همه در یک.
راه اندازی Next.js با TypeScript و Tailwindcss
من درک اولیه ای داشتم که برای فرانت اند به smth نیاز دارم.
به من آموزش داده شد که با ایجاد یک پروژه جدید 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. پروژه های متن باز را پیدا کنید و در بالا بسازید
من از این دو پروژه منبع باز استفاده کردم:
- Twitter Alghoritm https://github.com/coryetzkorn/twitter-algorithm بنابراین می توانم به ورودی پست کاربران بر اساس الگوریتم لینکدین امتیاز بدهم.
2. توییتر بیو ژنراتور
https://github.com/Nutlope/twitterbio
این یکی به من کمک کرد تا بفهمم چگونه Open.AI را به هم متصل کنم و با آن پست هایی برای Linkedin ایجاد کنم. در کد فعلی، BIO تولید کرد
برای تنظیم و باز کردن هر یک از پروژه ها به طور جداگانه آنها را به صورت فشرده در رایانه خود دانلود کردم
🐣 مرحله 3 کشف کد
بنابراین من به نوعی از آنچه می بینم شوکه شدم و در ابتدا نتوانستم چیزی را بفهمم.
بنابراین کاری که من انجام دادم از ChatGPT در مورد ساختار اصلی برنامه خود پرسیدم.
من هر کد صفحه را در آن کپی کردم و پرسیدم چه کاری انجام می دهد و اساساً می پرسم که چگونه می توان تغییرات ایجاد کرد. بنابراین من شروع به دریافت ایده بهتری می کنم، جایی که جلوی برنامه، کجا CSS است.
من هنوز هیچ ایده کاملی از همه چیز ندارم و چیزها را از دست داده ام، اما فکر می کنم قطعاً یادگیری سریع است.
برخی از درخواستهایی که از ChatGPT ارائه کردم بسیار ابتدایی بودند، و اکنون برای من کاملاً واضح به نظر میرسند، در آن مرحله همه چیز را پرسیدم، همه سؤالات احمقانه.
🐣 مرحله 4 ساخت پروژه
بنابراین پس از کشف برخی از اصول اولیه، من به ایجاد تغییرات خود ادامه می دهم. شروع به ساخت برنامه در بالای این پروژه ها کنید.
دارای دو بخش = رتبه + ژنراتور
الگوریتم مولد پست لینکدین
رتبه بندی رتبه بندی پست شما بر اساس معیارهای مختلف است که عملکرد را افزایش می دهد.
من با استفاده از توابع، الگوریتمی را برای آنچه برای لینکدین میدانیم تطبیق دادم:
- قابلیت تشخیص چندین هشتگ
- عملکرد تشخیص تصویر یا ویدیو
- تابعی برای شناسایی آدرس های اینترنتی در پست
- عملکردی برای حمایت از پست هایی که از ایموجی ها استفاده می کنند
- عملکردی برای تبلیغ محتوای منفی
- تابع اولویت بندی شکست مانند قالب بندی پست.
- عملکرد کاهش طول خط
- عملکرد پرسیدن سوال
در مقایسه با الگوریتم توییتر، لینکدین عمومی نیست.
// 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 و Prompts Generator را باز کنید
من از 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>
</>
);
}
🐥 مرحله 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
🐥 مرحله 6. اشتراک گذاری در اجتماعی و جمع آوری بازخورد
از آنجایی که پروژه لینکدین بود، پست را در آنجا رها کردم. و ویروسی شد با 200 هزار بازدید و حتی متنفر 🙂
پیوند به پست
https://www.linkedin.com/feed/update/urn:li:activity:7053373191133499392/
آمار در 24 ساعت اول:
⭐️ 20000 نمایش لینکدین
⭐️ 7000 بازدید از وبسایت
⭐️ 600 لایک
⭐️ بیش از 11000 پست ایجاد شد
⭐️ 3+ نفرت دارند
⭐️ 3+ پیشنهاد پروژه مشترک
الان دارم چیکار میکنم؟
من در حال ساخت ریزابزارهای مختلف و مشارکت در پروژه های منبع باز موجود هستم.
چالش این ماه برای افزایش Papermark.io در GitHub به 1000 ستاره.
papermark.io – جایگزین منبع باز برای Docsend
به ما ستاره بده⭐️
چرا Papermark؟
من قبلاً زمانی که می خواستم سرمایه جمع کنم با Docsend مشکلات زیادی داشتم که خیلی اذیتم کرد.
بنابراین من این پروژه را در صورت رشد بیشتر مفید یافتم. جالب است که جایگزین منبع باز داشته باشید.
اگر در حال ساخت پروژه منبع باز هستید، با من به اشتراک بگذارید 👀