Trong hướng dẫn từng bước này, tôi nói về cách tôi xây dựng Trình lập lịch Tweet bằng cách sử dụng Upstash QStash, Upstash Redis, Next.js Server Actions và Vercel. Việc lên lịch đăng bài trên Twitter giúp bạn duy trì sự hiện diện nhất quán, tương tác với khán giả vào thời điểm tối ưu và quản lý hiệu quả chiến lược nội dung của mình.
Điều kiện tiên quyết
Bạn sẽ cần những thứ sau:
- Node.js 18 trở lên
- Tài khoản Upstash
- Tài khoản Twitter
- Tài khoản Vercel
Ngăn xếp công nghệ
Các công nghệ sau được sử dụng trong hướng dẫn này:
Các bước
Để hoàn thành hướng dẫn này và triển khai công cụ lập lịch tweet của riêng bạn, bạn cần làm theo các bước sau:
- Thiết lập Upstash Redis
- Thiết lập QStash Upstash
- Thiết lập ứng dụng dành cho nhà phát triển Twitter
- Tạo ứng dụng Next.js mới
- Triển khai xác thực người dùng bằng Twitter OAuth 2.0
- Xây dựng giao diện người dùng để lên lịch đăng bài
- Lên lịch đăng Tweet bằng Upstash QStash
- Triển khai tới Vercel
Thiết lập Upstash Redis
Khi bạn đã tạo tài khoản Upstash và đăng nhập, bạn sẽ chuyển tới tab Redis và tạo cơ sở dữ liệu.


Sau khi bạn đã tạo cơ sở dữ liệu, hãy cuộn xuống cho đến khi bạn tìm thấy phần REST API và chọn .env nút. Sao chép nội dung và lưu ở nơi an toàn.

Thiết lập QStash Upstash
Để lên lịch các yêu cầu POST tới điểm cuối lập lịch theo một khoảng thời gian nhất định, bạn sẽ sử dụng QStash. Chuyển đến tab QStash và cuộn xuống tab Trình tạo yêu cầu.

Sao chép URL QStash, TOKEN, Khóa ký hiện tại và Khóa ký tiếp theo và lưu chúng ở nơi an toàn.

Thiết lập ứng dụng dành cho nhà phát triển Twitter
Để thiết lập xác thực bằng Twitter OAuth 2.0, bạn sẽ tạo một ứng dụng trong Cổng thông tin dành cho nhà phát triển Twitter. Để thiết lập ứng dụng Twitter, hãy làm như sau:
- Mở Cổng thông tin dành cho nhà phát triển của Twitter> Dự án.
- Tạo dự án.
- Chuyển đến tab Cài đặt trong cài đặt ứng dụng của bạn và thực hiện các thao tác sau:
- Chọn
Read and write and Direct messagetrong Quyền ứng dụng . - Chọn
Web App, Automated App or Bottrong Loại ứng dụng . - Nhập
http://localhost:3000/api/auth/callback/twitterdưới dạng URI gọi lại/URL chuyển hướng .
- Chọn
- Đi tới
Keys and tokenstrong cài đặt ứng dụng của bạn, cuộn xuống và thực hiện như sau:- Sao chép
Client IDvà lưu trữ ở nơi an toàn dưới dạngTWITTER_CLIENT_ID. - Sao chép
Client Secretvà lưu trữ ở nơi an toàn dưới dạngTWITTER_CLIENT_SECRET.
- Sao chép
Đó là tất cả những gì bạn cần để thiết lập thành công Ứng dụng dành cho nhà phát triển Twitter cho OAuth 2.0.
Tạo ứng dụng Next.js mới
Hãy bắt đầu bằng cách tạo một dự án Next.js mới. Mở terminal của bạn và chạy lệnh sau:
npx create-next-app@latest schedule-qstash-queue-upstash Khi được nhắc, hãy chọn:
Yeskhi được nhắc sử dụng TypeScript.Nokhi được nhắc sử dụng ESLint.Yeskhi được nhắc sử dụng CSS Tailwind.Nokhi được nhắc sử dụngsrc/thư mục.Yeskhi được nhắc sử dụng Bộ định tuyến ứng dụng.Nokhi được nhắc tùy chỉnh bí danh nhập mặc định (@/*).
Sau khi hoàn tất, hãy chuyển vào thư mục dự án và khởi động ứng dụng ở chế độ phát triển bằng cách thực hiện lệnh sau:
cd schedule-qstash-queue-upstash
npm run dev Ứng dụng phải chạy trên localhost:3000.
Bây giờ, hãy tạo một .env tập tin ở thư mục gốc của dự án của bạn. Bạn sẽ thêm các mục chúng tôi đã lưu từ các phần trên.
Nó sẽ trông giống như thế này:
# .env
# Obtained from the steps as above
# Twitter Environment Variables
TWITTER_CLIENT_ID="..."
TWITTER_CLIENT_SECRET="..."
TWITTER_AUTH_CALLBACK_URL="http://localhost:3000/api/auth/callback/twitter"
# Upstash Environment Variables
UPSTASH_REDIS_REST_URL="https://...upstash.io"
UPSTASH_REDIS_REST_TOKEN="...="
QSTASH_URL="https://qstash.upstash.io/v2/publish/"
QSTASH_TOKEN="...="
QSTASH_CURRENT_SIGNING_KEY="sig_..."
QSTASH_NEXT_SIGNING_KEY="sig_..." Tích hợp các thành phần shadcn/ui
Để nhanh chóng tạo mẫu giao diện người dùng, bạn sẽ thiết lập shadcn/ui với Next.js. shadcn/ui là tập hợp các thành phần được thiết kế đẹp mắt mà bạn có thể sao chép và dán vào ứng dụng của mình. Trong cửa sổ terminal của bạn, hãy chạy lệnh bên dưới để bắt đầu thiết lập shadcn/ui :
npx shadcn-ui@latest init
Bạn sẽ được hỏi một số câu hỏi để định cấu hình components.json , hãy chọn như sau:
Yeskhi được nhắc sử dụng TypeScript.Defaultkhi được nhắc chọn kiểu sẽ sử dụng.Slatekhi được nhắc chọn màu cơ bản.app/globals.csskhi được nhắc nhập tệp CSS chung.yeskhi được nhắc sử dụng biến CSS cho màu sắc.Leave blankkhi được nhắc nhập tiền tố tailwind tùy chỉnh.tailwind.config.tskhi được nhắc nhập vị trí của tailwind.config.js.@/componentskhi được nhắc định cấu hình bí danh cho các thành phần.@/lib/utilskhi được nhắc định cấu hình bí danh cho utils.Yeskhi được nhắc chọn sử dụng Thành phần máy chủ React.Yeskhi được nhắc tiếp tục ghi cấu hình vào Components.json.
Khi đã xong, bạn đã thiết lập CLI cho phép chúng tôi dễ dàng thêm các thành phần React vào ứng dụng Next.js của bạn. Tiếp theo, trong cửa sổ terminal của bạn, hãy chạy lệnh bên dưới để nhận các phần tử nút, đầu vào, vùng văn bản, cửa sổ bật lên, lịch và bánh mì nướng:
npx shadcn-ui@latest add button
npx shadcn-ui@latest add input
npx shadcn-ui@latest add textarea
npx shadcn-ui@latest add toast
npx shadcn-ui@latest add popover
npx shadcn-ui@latest add calendar
Khi đã xong, bây giờ bạn sẽ thấy ui thư mục bên trong app/components thư mục chứa button.tsx , input.tsx , calendar.tsx , input.tsx , popover.tsx , textarea.tsx , toast.tsx , toaster.tsx , và use-toast.ts .
Tiếp theo, mở app/layout.tsx tập tin và thực hiện các bổ sung sau:
+ // File: app/layout.tsx
import './globals.css'
+ import { cn } from '@/lib/utils'
import type { Metadata } from 'next'
+ import { Inter } from 'next/font/google'
+ import { Toaster } from '@/components/ui/toaster'
+ const fontSans = Inter({
+ subsets: ['latin'],
+ variable: '--font-sans',
+ })
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body
+ className={cn(fontSans.variable, 'min-w-screen flex min-h-screen flex-col items-center justify-center bg-background font-sans antialiased')}
>
{children}
+ <Toaster />
</body>
</html>
)
}
Trong những thay đổi mã ở trên, bạn đã nhập Toaster thành phần (được tạo bởi shadcn/ui ) và đảm bảo rằng nó có trong toàn bộ ứng dụng Next.js của bạn. Nó cho phép bạn hiển thị thông báo chúc mừng từ bất kỳ đâu trong mã của bạn thông qua useToast móc.
Tạo hàng đợi cập nhật để lưu trữ các Tweet đã lên lịch
Trong phần này, bạn sẽ tìm hiểu cách sử dụng Hàng đợi Upstash để lưu trữ thông tin tweet đã lên lịch. Bạn sẽ tìm hiểu cách tạo mã phía máy chủ được gọi dưới dạng hàm thay vì qua tuyến API bằng cách sử dụng Tác vụ máy chủ Next.js.
Trước tiên, trong cửa sổ terminal của bạn, hãy thực hiện thao tác sau để cài đặt SDK Upstash:
npm install @upstash/qstash @upstash/queue @upstash/redis@1.28.0 Lệnh trên cài đặt các gói sau:
@upstash/qstash:SDK để tương tác với phiên bản Upstash QStash của bạn qua các yêu cầu HTTP.@upstash/queue:SDK để quản lý hàng đợi tin nhắn dựa trên luồng, được hỗ trợ bởi Upstash Redis.@upstash/redis:SDK để tương tác qua các yêu cầu HTTP với Redis, được xây dựng dựa trên API Upstash REST.
Khởi tạo Upstash Redis và Upstash Queue Client
Để sử dụng các thư viện được cài đặt ở trên nhằm tương tác với Hàng đợi Upstash của bạn, hãy tạo tệp lib/upstash.ts với đoạn mã sau:
// File: lib/upstash.ts
import { Redis } from '@upstash/redis'
import { Queue } from '@upstash/queue'
export const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL as string,
token: process.env.UPSTASH_REDIS_REST_TOKEN as string,
})
export const queue = new Queue({
redis,
queueName: 'tweets',
concurrencyLimit: 5,
}) Đoạn mã trên thực hiện như sau:
- Nhập
RedisvàQueuecác lớp được xuất bởi các gói. - Xuất
redisphiên bản trỏ đến URL Upstash Redis bằng mã thông báo ủy quyền yêu cầu. - Xuất
queuedụ trỏ đến Upstash Redis được tạo ở trên. Nó đặt tên hàng đợi thànhtweetsvàconcurrencyLimitđến 5, cho phép xử lý tối đa 5 tin nhắn đồng thời.
Bằng cách sử dụng phiên bản hàng đợi, bạn sẽ tạo Hành động máy chủ Next.js sẽ chấp nhận văn bản tweet và ngày tweet để tạo và đẩy đối tượng tweet vào hàng đợi để xử lý trong tương lai. Tạo một tệp app/schedule.server.tsx với đoạn mã sau:
// File: app/schedule.server.tsx
'use server'
import { queue } from '@/lib/upstash'
import type { FormProps } from './form'
export async function schedule(_: any, formData: FormData): Promise<FormProps> {
try {
const tweet_text = formData.get('tweet_text') as string
const tweet_date = formData.get('tweet_date') as string
const now = new Date().getTime()
const delay = new Date(tweet_date).getTime() - now
await queue.sendMessage({ tweet_text, tweet_date }, delay)
return { ok: true, tweet_date }
} catch (e) {
console.log(e)
return { ok: false }
}
} Đoạn mã trên thực hiện như sau:
- Nhập
queueví dụ - Xuất hành động máy chủ có tên
schedule, chấp nhận việc gửi biểu mẫu có chứa văn bản và ngày của tweet được lên lịch. - Tính thời gian từ đó đến thời điểm tweet được lên lịch.
- Chèn đối tượng tweet chứa ngày và văn bản với độ trễ được đặt thành thời gian được tính ở trên.
Với điều này, bạn đã đảm bảo rằng tweet chỉ được đẩy vào hàng đợi khi nó được lên lịch. Điều này giúp đơn giản hóa quá trình duy trì trạng thái của hàng đợi, đảm bảo rằng chỉ các tweet được lên lịch vào bất kỳ ngày nào đều có sẵn trong hàng đợi.
Hãy chuyển sang việc nhận ủy quyền từ người dùng để thay mặt họ tweet bằng luồng PKCE OAuth 2.0.
Triển khai xác thực người dùng bằng Twitter OAuth 2.0
Trong phần này, bạn sẽ tìm hiểu cách thiết lập luồng xác thực Twitter OAuth 2.0 trong ứng dụng của mình bằng cách định cấu hình ứng dụng khách Twitter OAuth và sử dụng các chức năng trợ giúp do Twitter SDK cung cấp cho các tác vụ xác thực. Luồng xác thực bao gồm việc tạo các điểm cuối ủy quyền và gọi lại, cho phép người dùng cấp quyền truy cập và nhận mã thông báo, với mã thông báo truy cập được lưu trữ trong Upstash Redis. bạn cũng sẽ tạo trạng thái xác thực thông qua điểm cuối cho biết sự hiện diện của mã thông báo truy cập hợp lệ trong Upstash Redis.
Trước tiên, trong cửa sổ terminal của bạn, hãy chạy lệnh bên dưới để cài đặt thư viện cần thiết nhằm triển khai Xác thực Twitter OAuth 2.0:
npm install twitter-api-sdk Lệnh trên sẽ cài đặt gói sau:
twitter-api-sdk:SDK TypeScript cho API Twitter.
Tạo ứng dụng khách xác thực Twitter
Để có thể tạo URL ủy quyền mà không cần đi sâu vào sự phức tạp của API Twitter, bạn sẽ sử dụng ứng dụng khách xác thực bằng Twitter SDK. Tạo một tệp twitter.ts bên trong lib thư mục có mã sau:
// File: lib/twitter.ts
import { auth } from 'twitter-api-sdk'
export const authClient = new auth.OAuth2User({
client_id: process.env.TWITTER_CLIENT_ID as string,
callback: process.env.TWITTER_AUTH_CALLBACK_URL as string,
client_secret: process.env.TWITTER_CLIENT_SECRET as string,
scopes: ['tweet.write', 'tweet.read', 'offline.access', 'users.read'],
}) Đoạn mã trên bắt đầu bằng việc nhập trình trợ giúp xác thực từ Twitter SDK. Sau đó, nó xuất ứng dụng khách xác thực để tiết kiệm thời gian tìm hiểu cú pháp API Twitter bằng cách cung cấp các hàm trợ giúp để tạo URL ủy quyền và yêu cầu mã thông báo truy cập từ người dùng đã xác thực.
Chuẩn bị URL ủy quyền Twitter
Bước đầu tiên trong quy trình OAuth 2.0 là người dùng được chuyển hướng đến URL ủy quyền. URL ủy quyền là điểm cuối được cung cấp bởi máy chủ OAuth 2.0 nơi người dùng được chuyển hướng để bắt đầu quá trình ủy quyền bằng cách cấp quyền cho ứng dụng khách. Thông thường, người dùng sẽ có nhiều lựa chọn (chẳng hạn như Continue with Twitter , Continue with Google , v.v.) tại màn hình đăng nhập/đăng ký, sau đó được đưa tới màn hình ủy quyền được lưu trữ trên máy chủ của nền tảng (ở đây là Twitter).
Tạo một tệp app/api/auth/twitter/route.ts với đoạn mã sau:
// File: app/api/auth/twitter/route.ts
export const dynamic = 'force-dynamic'
import { NextResponse } from 'next/server'
import { authClient } from '@/lib/twitter'
export async function GET() {
// Obtain an authorization URL from Twitter
const authUrl = authClient.generateAuthURL({
state: 'state',
code_challenge: 'challenge',
code_challenge_method: 'plain',
})
// Return with a 303 as a redirect to the authorization URL
return NextResponse.redirect(authUrl, 303)
} Đoạn mã trên thực hiện như sau:
- Nhập
NextResponsechức năng trợ giúp mở rộng API phản hồi web. - Nhập
authClientđược tạo trước đó. - Xuất
GETTrình xử lý HTTP đáp ứng các yêu cầu GET đến trên/api/auth/twitter. - Tạo URL ủy quyền bằng
generateAuthURLchức năng trợ giúp của Twitter SDK. - Chuyển hướng đến URL ủy quyền được tạo bằng
redirectphương pháp NextResponse.
Hãy chuyển sang tạo điểm cuối đáp ứng yêu cầu khi người dùng cấp quyền truy cập cho ứng dụng Twitter của bạn.
Chuẩn bị URL gọi lại ủy quyền
Bước thứ hai trong quy trình OAuth 2.0 là phản hồi các lệnh gọi lại từ nền tảng xác thực. Để xử lý yêu cầu gọi lại ủy quyền đến từ Twitter, bạn sẽ định cấu hình điểm cuối trong ứng dụng của mình nơi người dùng sẽ được chuyển hướng sau khi cấp quyền truy cập. URL gọi lại này rất cần thiết để nhận mã ủy quyền, cho phép ứng dụng của bạn lưu mã thông báo truy cập thu được trong Upstash Redis. Với mã thông báo đó, bạn có thể tự động hóa các dòng tweet qua API trong ứng dụng của mình.
Tạo một tệp app/api/auth/callback/twitter/route.ts với đoạn mã sau:
// File: app/api/auth/callback/twitter/route.ts
export const dynamic = 'force-dynamic'
import { redis } from '@/lib/upstash'
import { NextResponse } from 'next/server'
import { authClient } from '@/lib/twitter'
export async function GET(request: Request) {
// Look for the callback URL to contain code
const code = new URL(request.url).searchParams.get('code')
// If no code query param found, return 403
if (!code) return NextResponse.json({}, { status: 403 })
// If code query param found, create another authorization URL to update internal code_verifier
authClient.generateAuthURL({
state: 'state',
code_challenge: 'challenge',
code_challenge_method: 'plain',
})
// Obtain the access_token to use it for making requests in the future
const {
token: { access_token },
} = await authClient.requestAccessToken(code)
// Save the access_token in Upstash
await redis.set('twitter_oauth_access_token', access_token)
// Return back to homepage
return NextResponse.redirect(new URL('/', request.url), 303)
} Đoạn mã trên thực hiện như sau:
- Nhập
redisphiên bản đang sử dụng Upstash Redis. - Nhập
NextResponsechức năng trợ giúp mở rộng API phản hồi web. - Nhập
authClientđược tạo trước đó. - Xuất
GETTrình xử lý HTTP đáp ứng các yêu cầu GET đến trên/api/auth/callback/twitter. - Hủy cấu trúc
codetham số truy vấn từ URL gọi lại. - Tạo một URL ủy quyền giống như trước đây dưới dạng hack để cập nhật trạng thái nội bộ do SDK tạo.
- Gọi tới
requestAccessTokenhoạt động bằng Twitter SDK để có được quyền truy cập và làm mới mã thông báo, điều này sẽ cho phép bạn tạo các tweet qua API. - Hủy cấu trúc
access_tokentừtokenđối tượng thu được. - Lưu giá trị mã thông báo truy cập thu được bằng
twitter_oauth_access_tokenlàm chìa khóa trong Upstash Redis. - Chuyển hướng đến URL chỉ mục (
/) sử dụngredirectphương pháp NextResponse.
Bây giờ bạn đã hoàn thành quy trình Twitter OAuth 2.0.
Có twitter_oauth_access_token hợp lệ trong phiên bản Upstash Redis là chỉ báo về trạng thái luồng xác thực. Để giao tiếp tương tự trong giao diện người dùng, hãy tạo một tệp app/api/auth/twitter/authenticated/route.ts với đoạn mã sau:
// File: app/api/auth/twitter/authenticated/route.ts
export const dynamic = 'force-dynamic'
import { redis } from '@/lib/upstash'
import { NextResponse } from 'next/server'
export async function GET() {
try {
const access_token = await redis.get<string>('twitter_oauth_access_token')
if (!access_token) return NextResponse.json({ ok: false }, { status: 200 })
return NextResponse.json({ ok: true }, { status: 200 })
}
catch(e) {}
return NextResponse.json({ ok: false }, { status: 200 })
} Đoạn mã trên thực hiện như sau:
- Nhập
redisphiên bản đang sử dụng Upstash Redis. - Nhập
NextResponsechức năng trợ giúp mở rộng API phản hồi web. - Xuất
GETTrình xử lý HTTP phản hồi các yêu cầu GET đến trên/api/auth/twitter/authenticated. - Tìm nạp giá trị liên quan đến
twitter_oauth_access_tokenkhóa trong Upstash Redis. - Trả về phản hồi JSON chứa
okboolean cho biết liệu có mã thông báo truy cập hợp lệ trong Upstash Redis hay không.
Hãy chuyển sang tạo giao diện người dùng để sử dụng các điểm cuối API mà bạn đã tạo này.
Xây dựng giao diện người dùng để lên lịch đăng bài
Trong phần này, bạn sẽ tìm hiểu cách tạo trạng thái biểu mẫu phản ứng bằng cách sử dụng React hook useFormState và useFormStatus và gọi hành động của máy chủ để lên lịch tweet.
Trước tiên, bạn sẽ tạo một thành phần React để hiển thị một biểu mẫu chứa thông tin của tweet sắp được lên lịch và hiển thị thông báo chúc mừng cho biết liệu thông tin tweet có hay không. Tạo một tệp app/form.tsx với đoạn mã sau:
// File: app/form.tsx
'use client'
// UI Imports
import { cn } from '@/lib/utils'
import { format } from 'date-fns'
import { Button } from '@/components/ui/button'
import { Calendar } from '@/components/ui/calendar'
import { useToast } from '@/components/ui/use-toast'
import { Textarea } from '@/components/ui/textarea'
import { Calendar as CalendarIcon } from 'lucide-react'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
// Form Status hook
import { useFormStatus } from 'react-dom'
import { useEffect, useState } from 'react'
// Define Form Props
export interface FormProps {
ok?: boolean
tweet_date?: string
}
export default function ({ ok, tweet_date }: FormProps) {
const { toast } = useToast()
// Use React's useFormStatus hook to detect form submission state
const { pending } = useFormStatus()
useEffect(() => {
// If the form is not pending
if (!pending) {
// If the server ok-ed the query, reset the form
if (ok) {
const scheduleForm = document.getElementById('schedule_form') as HTMLFormElement
if (scheduleForm) scheduleForm.reset()
// Display that scheduling was succesful
toast({
title: 'Scheduled Tweet',
description: tweet_date,
})
} else {
// Display that scheduling failed
toast({
variant: 'destructive',
title: 'Uh oh! Something went wrong.',
description: 'There was a problem with your request.',
})
}
}
}, [pending])
// Listen to the date picker changes
const [date, setDate] = useState<Date>()
return (
<>
<span className="font-semibold">Tweet Scheduler</span>
{/* Date Picker for Scheduling Tweet on future dates */}
<input id="tweet_date" name="tweet_date" className="hidden" value={date?.toString()} />
<Popover>
<PopoverTrigger asChild>
<Button variant={'outline'} className={cn('w-[280px] justify-start text-left font-normal', !date && 'text-muted-foreground')}>
<CalendarIcon className="mr-2 h-4 w-4" />
{date ? format(date, 'PPP') : <span>Pick a date</span>}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar mode="single" selected={date} onSelect={setDate} />
</PopoverContent>
</Popover>
{/* Text Area for Entering Text of Tweet */}
<Textarea id="tweet_text" name="tweet_text" className="min-h-[300px] w-[280px]" placeholder="Tweet" />
{/* Schedule Button Tweet */}
<Button disabled={pending} className="w-[280px]">
{pending ? 'Scheduling...' : <>Schedule →</>}
</Button>
</>
)
} Đoạn mã trên thực hiện như sau:
- Nhập các thành phần được tạo bởi
shadcn/uiLệnh CLI trước đó. - Xuất thành phần React để hiển thị
inputẩn trực quan Phần tử HTML mô tả ngày đăng tweet đã lên lịch. - Thành phần này cũng hiển thị
textareaPhần tử HTML để chấp nhận nội dung tweet một cách trực quan từ người dùng. - Thành phần này cũng hiển thị
Buttontính năng này bị vô hiệu hóa có điều kiện dựa trên trạng thái của (các) lần gửi biểu mẫu trước đó. - Thành phần này cũng sử dụng
useEffecthook để đặt lại biểu mẫu nếu hành động của máy chủ dẫn đến thành công. Dù bằng cách nào, nó cũng hiển thị thông báo chúc mừng ở góc dưới cùng bên phải để cho biết trạng thái của yêu cầu.
Tiếp theo, bạn sẽ tạo một thành phần hiển thị trạng thái xác thực Twitter của người dùng. Tạo một tệp components/twitter.tsx với đoạn mã sau:
// File: components/twitter.tsx
'use client'
import { useEffect, useState } from 'react'
import { Button } from '@/components/ui/button'
export default function () {
const state: { [k: string]: { message: string; variant: 'outline' | 'secondary' | 'destructive' } } = {
pending: {
message: '...',
variant: 'outline',
},
true: {
message: '✔️ Authenticated Instance',
variant: 'secondary',
},
false: {
message: '1-Time Authentication with Twitter →',
variant: 'destructive',
},
}
const [authenticated, setAuthenticated] = useState<string | boolean>('pending')
useEffect(() => {
fetch('/api/auth/twitter/authenticated')
.then((res) => res.json())
.then((res) => {
setAuthenticated(res.ok as boolean)
})
}, [])
{
/* Authenticate with Twitter */
}
return (
<Button
className="w-[280px]"
onClick={() => {
if (!authenticated) window.location.href = '/api/auth/twitter'
}}
variant={state[authenticated.toString()].variant}
>
{state[authenticated.toString()].message}
</Button>
)
} Đoạn mã trên thực hiện như sau:
- Nhập
useEffectvàuseStatehook của React để sử dụng chúng nhằm tìm nạp trạng thái xác thực người dùng. - Xuất thành phần React hiển thị
Buttonthành phần (bởishadcn/ui) ở các trạng thái khác nhau, liên kết từng trạng thái với trạng thái xác thực Twitter của người dùng.
Để hiển thị một biểu mẫu cho người dùng cho phép họ tương tác và lên lịch tweet khi họ mở lộ trình chỉ mục (tức là / ), tạo tệp app/page.tsx với đoạn mã sau:
// File: app/page.tsx
'use client'
// Form with Pending Status
import Form from './form'
// Form with access to the server returned data
import { useFormState } from 'react-dom'
// Scheduling Next.js Action
import Twitter from '@/components/twitter'
import { schedule } from './schedule.server'
export default function () {
const [state, formAction] = useFormState(schedule, {})
return (
<div className="flex w-[300px] flex-col gap-y-3 p-5">
<Twitter />
<form id="schedule_form" action={formAction} className="flex w-[300px] flex-col gap-y-3">
<Form {...state} />
</form>
</div>
)
} Đoạn mã trên thực hiện như sau:
- Nhập
FormvàTwittercác thành phần được tạo trước đó. - Nhập
useFormStatehook bởi React để có thể xử lý dữ liệu được trả về bởi hành động máy chủ Next.js bằng cách sử dụngstatebiến và cho phép gọi hành động của máy chủ thông qua việc gửi biểu mẫu. - Nhập
schedulehành động máy chủ được tạo trước đó. - Hiển thị thành phần React chứa
<form>thành phần cóschedule_formid và được thiết lập để gọiformActionkhi người dùng gửi biểu mẫu.
Lên lịch đăng Tweet bằng Upstash QStash
Để lên lịch tweet thay mặt người dùng, bạn sẽ tạo một điểm cuối sẽ sử dụng dữ liệu tweet được lưu trữ trong Hàng đợi Upstash và sau đó POST lên API Twitter để thực hiện các tweet. Tạo một tệp app/api/schedule/route.ts với đoạn mã sau:
// File: app/api/schedule/route.ts
export const dynamic = 'force-dynamic'
import { NextResponse } from 'next/server'
import { queue, redis } from '@/lib/upstash'
import { verifySignatureAppRouter } from '@upstash/qstash/dist/nextjs'
interface TweetBody {
tweet_text?: string
tweet_date?: number
}
async function tweet(access_token: string, text: string | undefined) {
if (text) {
await fetch('https://api.twitter.com/2/tweets', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: ['Bearer', access_token].join(' '),
},
body: JSON.stringify({ text }),
})
}
}
async function handler() {
const access_token = await redis.get<string>('twitter_oauth_access_token')
if (!access_token) return NextResponse.json({}, { status: 403 })
const tweets = await Promise.all(Array.from({ length: 4 }, () => queue.receiveMessage<TweetBody>()))
await Promise.all(tweets.map((i) => tweet(access_token, i?.body?.tweet_text)))
return NextResponse.json({}, { status: 200 })
}
export const POST = verifySignatureAppRouter(handler) Đoạn mã trên thực hiện như sau:
- Nhập
redisvàqueuecác phiên bản đang sử dụng Upstash Redis và Upstash Queue tương ứng. - Nhập
verifySignatureAppRoutercủa Upstash sẽ xác minh chữ ký yêu cầu để đảm bảo rằng yêu cầu chỉ đến từ QStash. - Tạo hàm
tweetchấp nhận văn bản tweet và mã thông báo truy cập để thực hiện tweet thay mặt cho người dùng đã được xác thực. - Tạo một
POSTTrình xử lý HTTP phản hồi các yêu cầu POST đến trên/api/schedule. Nó tìm nạp 4 tin nhắn từ Hàng đợi Upstash và gọitweetchức năng thực hiện các tweet thay mặt cho người dùng.
Sử dụng Upstash QStash, bạn có thể lên lịch quá trình thực hiện các tweet. Giả sử bạn muốn tự động hóa nó sao cho mỗi ngày vào lúc nửa đêm, quá trình này sẽ tự khởi động và các dòng tweet sẽ xuất hiện. Để làm điều đó, bạn sẽ sử dụng điểm cuối được tạo trước đó:/api/schedule trong QStash.

Đi tới tab QStash trong bảng điều khiển Upstash, cuộn xuống tab Trình tạo yêu cầu và thực hiện như sau:
- Chọn
Endpointtab. - Nhập
URLlàm URL tuyệt đối cho/api/schedulecủa bạn điểm cuối. - Chọn
TypelàScheduled. - Chọn
Everylàevery day at midnight. - Nhấp vào
Schedule.
Với các bước trên là bạn đã tạo được công việc POST tới /api/schedule mỗi ngày vào lúc nửa đêm.
Đó là rất nhiều học hỏi! Bây giờ bạn đã hoàn tất ✨
Triển khai lên Vercel
Kho lưu trữ hiện đã sẵn sàng để triển khai lên Vercel. Hãy làm theo các bước sau để triển khai:
- Bắt đầu bằng cách tạo kho lưu trữ GitHub chứa mã ứng dụng của bạn.
- Sau đó, điều hướng tới Trang tổng quan Vercel và tạo Dự án mới .
- Liên kết dự án mới với kho lưu trữ GitHub mà bạn vừa tạo.
- Trong Cài đặt , cập nhật
Environment Variablesđể khớp với những thông tin đó ở địa phương của bạn.envtập tin. - Nhấp vào
Deploy.
Thông tin thêm
Để biết thêm thông tin chi tiết, hãy khám phá các tài liệu tham khảo được trích dẫn trong bài đăng này.
- Kho lưu trữ GitHub
- Luồng OAuth 2.0 của Twitter
- Tạo mã thông báo ứng dụng Twitter
- Móc biểu mẫu phản ứng
- Tác vụ máy chủ Next.js
Kết luận
Trong hướng dẫn này, bạn đã học cách xây dựng Trình lập lịch Tweet mạnh mẽ bằng cách tận dụng cơ sở dữ liệu Redis mạnh mẽ và hàng đợi QStash của Upstash. Khả năng mở rộng của Upstash đảm bảo khả năng lưu trữ và lập lịch tweet đáng tin cậy, kết hợp với việc triển khai liền mạch trên Vercel tạo nên một hệ thống hoàn toàn tự động.