Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Redis

Tạo Trình lập lịch Tweet với Upstash:Hướng dẫn từng bước

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ông nghệ Mô tả Nền tảng cơ sở dữ liệu UpstashServerless. Chúng tôi đang sử dụng cả Upstash Queue &QStash để lưu trữ các tweet trong hàng đợi và API lịch trình POST tương ứng với tần suất nhất định.Next.jsThe React Framework dành cho Web. Chúng tôi đang sử dụng shadcn/ui phổ biến để tạo nguyên mẫu giao diện người dùng nhanh chóng. Khung TailwindCSSCSS để xây dựng các thiết kế tùy chỉnh. VercelMột nền tảng đám mây để triển khai và mở rộng quy mô các ứng dụng web.PrettierOpinionated mã định dạng cho kiểu mã nhất quán.

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.

Tạo Trình lập lịch Tweet với Upstash:Hướng dẫn từng bước

Tạo Trình lập lịch Tweet với Upstash:Hướng dẫn từng bước

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.

Tạo Trình lập lịch Tweet với Upstash:Hướng dẫn từng bước

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.

Tạo Trình lập lịch Tweet với Upstash:Hướng dẫn từng bước

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.

Tạo Trình lập lịch Tweet với Upstash:Hướng dẫn từng bước

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 message trong Quyền ứng dụng .
    • Chọn Web App, Automated App or Bot trong Loại ứng dụng .
    • Nhập http://localhost:3000/api/auth/callback/twitter dưới dạng URI gọi lại/URL chuyển hướng .
  • Đi tới Keys and tokens trong 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 ID và lưu trữ ở nơi an toàn dưới dạng TWITTER_CLIENT_ID .
    • Sao chép Client Secret và lưu trữ ở nơi an toàn dưới dạng TWITTER_CLIENT_SECRET .

Đó 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:

  • Yes khi được nhắc sử dụng TypeScript.
  • No khi được nhắc sử dụng ESLint.
  • Yes khi được nhắc sử dụng CSS Tailwind.
  • No khi được nhắc sử dụng src/ thư mục.
  • Yes khi được nhắc sử dụng Bộ định tuyến ứng dụng.
  • No khi đượ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:

  • Yes khi được nhắc sử dụng TypeScript.
  • Default khi được nhắc chọn kiểu sẽ sử dụng.
  • Slate khi được nhắc chọn màu cơ bản.
  • app/globals.css khi được nhắc nhập tệp CSS chung.
  • yes khi được nhắc sử dụng biến CSS cho màu sắc.
  • Leave blank khi được nhắc nhập tiền tố tailwind tùy chỉnh.
  • tailwind.config.ts khi được nhắc nhập vị trí của tailwind.config.js.
  • @/components khi được nhắc định cấu hình bí danh cho các thành phần.
  • @/lib/utils khi được nhắc định cấu hình bí danh cho utils.
  • Yes khi được nhắc chọn sử dụng Thành phần máy chủ React.
  • Yes khi đượ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 RedisQueue các lớp được xuất bởi các gói.
  • Xuất redis phiên bản trỏ đến URL Upstash Redis bằng mã thông báo ủy quyền yêu cầu.
  • Xuất queue dụ trỏ đến Upstash Redis được tạo ở trên. Nó đặt tên hàng đợi thành tweetsconcurrencyLimit đế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 queue ví 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 NextResponse chứ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 GET Trì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 generateAuthURL chức năng trợ giúp của Twitter SDK.
  • Chuyển hướng đến URL ủy quyền được tạo bằng redirect phươ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 redis phiên bản đang sử dụng Upstash Redis.
  • Nhập NextResponse chứ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 GET Trì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 code tham 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 requestAccessToken hoạ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_token từ 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_token làm chìa khóa trong Upstash Redis.
  • Chuyển hướng đến URL chỉ mục (/ ) sử dụng redirect phương pháp NextResponse.

Bây giờ bạn đã hoàn thành quy trình Twitter OAuth 2.0.

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 redis phiên bản đang sử dụng Upstash Redis.
  • Nhập NextResponse chức năng trợ giúp mở rộng API phản hồi web.
  • Xuất GET Trì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_token khóa trong Upstash Redis.
  • Trả về phản hồi JSON chứa ok boolean 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 useFormStateuseFormStatus 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 &rarr;</>}
 </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/ui Lệ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ị textarea Phầ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ị Button tí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 useEffect hook để đặ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 useEffectuseState hook 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ị Button thành phần (bởi shadcn/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 FormTwitter các thành phần được tạo trước đó.
  • Nhập useFormState hook 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ụng state biế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 schedule hà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_form id và được thiết lập để gọi formAction khi 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 redisqueue các phiên bản đang sử dụng Upstash Redis và Upstash Queue tương ứng.
  • Nhập verifySignatureAppRouter củ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 tweet chấ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 POST Trì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ọi tweet chứ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.

Tạo Trình lập lịch Tweet với Upstash:Hướng dẫn từng bước

Đ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 Endpoint tab.
  • Nhập URL làm URL tuyệt đối cho /api/schedule của bạn điểm cuối.
  • Chọn TypeScheduled .
  • Chọn Everyevery 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 .env  tậ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.