Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

สร้างตัวกำหนดเวลาทวีตด้วย Upstash:คำแนะนำทีละขั้นตอน

ในคำแนะนำทีละขั้นตอนนี้ ฉันพูดถึงวิธีที่ฉันสร้าง Tweet Scheduler โดยใช้ Upstash QStash, Upstash Redis, Next.js Server Actions และ Vercel การกำหนดเวลาโพสต์ Twitter ช่วยให้คุณคงสถานะที่สม่ำเสมอ มีส่วนร่วมกับผู้ชมของคุณในเวลาที่เหมาะสม และจัดการกลยุทธ์เนื้อหาของคุณได้อย่างมีประสิทธิภาพ

ข้อกำหนดเบื้องต้น

คุณจะต้องมีสิ่งต่อไปนี้:

  • Node.js 18 หรือใหม่กว่า
  • บัญชี Upstash
  • บัญชีทวิตเตอร์
  • บัญชี Vercel

กลุ่มเทคโนโลยี

คู่มือนี้ใช้เทคโนโลยีต่อไปนี้:

เทคโนโลยี คำอธิบาย แพลตฟอร์มฐานข้อมูล UpstashServerless เรากำลังใช้ทั้ง Upstash Queue และ QStash เพื่อจัดเก็บทวีตในคิวและ API กำหนดการ POST ที่ความถี่ที่กำหนดตามลำดับ Next.jsThe React Framework สำหรับเว็บ เรากำลังใช้ shadcn/ui เพื่อสร้างต้นแบบ UI ที่รวดเร็ว เฟรมเวิร์ก TailwindCSSCSS สำหรับการสร้างการออกแบบที่กำหนดเอง แพลตฟอร์มคลาวด์ VercelA สำหรับการปรับใช้และปรับขนาดแอปพลิเคชันเว็บ ตัวจัดรูปแบบโค้ด PrettierOpinionated สำหรับรูปแบบโค้ดที่สอดคล้องกัน

ขั้นตอน

หากต้องการทำตามคำแนะนำนี้ให้เสร็จสิ้นและปรับใช้ตัวกำหนดเวลาทวีตของคุณเอง คุณจะต้องทำตามขั้นตอนเหล่านี้:

  • การตั้งค่า Upstash Redis
  • การตั้งค่า Upstash QStash
  • การตั้งค่าแอปพลิเคชันนักพัฒนา Twitter
  • สร้างแอปพลิเคชัน Next.js ใหม่
  • ใช้การตรวจสอบสิทธิ์ผู้ใช้ด้วย Twitter OAuth 2.0
  • สร้างอินเทอร์เฟซผู้ใช้เพื่อกำหนดเวลาทวีต
  • กำหนดเวลาทวีตโดยใช้ Upstash QStash
  • ปรับใช้กับ Vercel

การตั้งค่า Upstash Redis

เมื่อคุณสร้างบัญชี Upstash และเข้าสู่ระบบแล้ว คุณจะไปที่แท็บ Redis และสร้างฐานข้อมูล

สร้างตัวกำหนดเวลาทวีตด้วย Upstash:คำแนะนำทีละขั้นตอน

สร้างตัวกำหนดเวลาทวีตด้วย Upstash:คำแนะนำทีละขั้นตอน

หลังจากที่คุณสร้างฐานข้อมูลแล้ว ให้เลื่อนลงไปจนกว่าคุณจะพบส่วน REST API และเลือก 09 ปุ่ม คัดลอกเนื้อหาและบันทึกไว้ในที่ที่ปลอดภัย

สร้างตัวกำหนดเวลาทวีตด้วย Upstash:คำแนะนำทีละขั้นตอน

การตั้งค่าอัพสแตช QStash

หากต้องการกำหนดเวลาคำขอ POST ไปยังจุดสิ้นสุดการกำหนดเวลาในช่วงเวลาที่กำหนด คุณจะใช้ QStash ไปที่แท็บ QStash และเลื่อนลงไปที่แท็บตัวสร้างคำขอ

สร้างตัวกำหนดเวลาทวีตด้วย Upstash:คำแนะนำทีละขั้นตอน

คัดลอก QStash URL, TOKEN, คีย์การลงนามปัจจุบัน และคีย์การลงนามถัดไป และบันทึกไว้ในที่ที่ปลอดภัย

สร้างตัวกำหนดเวลาทวีตด้วย Upstash:คำแนะนำทีละขั้นตอน

การตั้งค่าแอปพลิเคชันนักพัฒนา Twitter

หากต้องการตั้งค่าการรับรองความถูกต้องด้วย Twitter OAuth 2.0 คุณจะต้องสร้างแอปพลิเคชันในพอร์ทัลนักพัฒนา Twitter หากต้องการตั้งค่าแอปพลิเคชัน Twitter ให้ทำดังต่อไปนี้:

  • เปิดพอร์ทัลนักพัฒนาของ Twitter> โครงการ
  • สร้างโครงการ
  • ไปที่แท็บการตั้งค่าในการตั้งค่าแอปพลิเคชันของคุณ และดำเนินการดังต่อไปนี้:
    • เลือก 14 ในการอนุญาตของแอป .
    • เลือก 22 ในประเภทของแอป .
    • กรอก 32 เป็น URI เรียกกลับ / URL ตอบกลับ .
  • ไปที่ 41 ในการตั้งค่าแอปพลิเคชันของคุณ ให้เลื่อนลงและดำเนินการดังต่อไปนี้:
    • คัดลอก 54 และเก็บไว้ที่ไหนสักแห่งที่ปลอดภัยเป็น 63 .
    • คัดลอก 78 และเก็บไว้ที่ไหนสักแห่งที่ปลอดภัยเป็น 82 .

นั่นคือทั้งหมดที่คุณต้องมีเพื่อตั้งค่าแอปพลิเคชัน Twitter Developer สำหรับ OAuth 2.0 ให้สำเร็จ

สร้างแอปพลิเคชัน Next.js ใหม่

เริ่มต้นด้วยการสร้างโครงการ Next.js ใหม่ เปิดเทอร์มินัลของคุณและรันคำสั่งต่อไปนี้:

npx create-next-app@latest schedule-qstash-queue-upstash

เมื่อได้รับแจ้ง ให้เลือก:

  • 97 เมื่อได้รับแจ้งให้ใช้ TypeScript
  • 108 เมื่อได้รับแจ้งให้ใช้ ESLint
  • 117 เมื่อได้รับแจ้งให้ใช้ Tailwind CSS
  • 129 เมื่อได้รับแจ้งให้ใช้ 130 ไดเร็กทอรี
  • 143 เมื่อได้รับแจ้งให้ใช้ App Router
  • 157 เมื่อได้รับแจ้งให้ปรับแต่งนามแฝงการนำเข้าเริ่มต้น (167 ).

เมื่อเสร็จแล้ว ให้ย้ายไปยังไดเร็กทอรีโปรเจ็กต์และเริ่มแอปในโหมดการพัฒนาโดยดำเนินการคำสั่งต่อไปนี้:

cd schedule-qstash-queue-upstash
npm run dev

แอปควรทำงานบน localhost:3000

ตอนนี้ สร้าง 179 ไฟล์ที่รากของโครงการของคุณ คุณกำลังจะเพิ่มรายการที่เราบันทึกไว้จากส่วนด้านบน

มันควรมีลักษณะดังนี้:

# .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_..."

การรวมส่วนประกอบ shadcn/ui

หากต้องการสร้างต้นแบบอินเทอร์เฟซผู้ใช้อย่างรวดเร็ว คุณจะต้องตั้งค่า 181 ด้วย Next.js 190 คือชุดของส่วนประกอบที่ออกแบบมาอย่างสวยงามซึ่งคุณสามารถคัดลอกและวางลงในแอปของคุณได้ ในหน้าต่างเทอร์มินัลของคุณ ให้รันคำสั่งด้านล่างเพื่อเริ่มการตั้งค่า 206 :

npx shadcn-ui@latest init

คุณจะถูกถามคำถามสองสามข้อเพื่อกำหนดค่า 219 ให้เลือกดังต่อไปนี้:

  • 222 เมื่อได้รับแจ้งให้ใช้ TypeScript
  • 236 เมื่อได้รับแจ้งให้เลือกสไตล์ที่จะใช้
  • 240 เมื่อได้รับแจ้งให้เลือกสีพื้นฐาน
  • 259 เมื่อได้รับแจ้งให้ป้อนไฟล์ CSS ส่วนกลาง
  • 267 เมื่อได้รับแจ้งให้ใช้ตัวแปร CSS สำหรับสี
  • 273 เมื่อได้รับแจ้งให้ป้อนคำนำหน้า tailwind ที่กำหนดเอง
  • 285 เมื่อได้รับแจ้งให้ป้อนตำแหน่งของ tailwind.config.js
  • 295 เมื่อได้รับแจ้งให้กำหนดค่านามแฝงสำหรับส่วนประกอบ
  • 304 เมื่อได้รับแจ้งให้กำหนดค่านามแฝงสำหรับยูทิลิตี้
  • 315 เมื่อได้รับแจ้งให้เลือกการใช้งานส่วนประกอบเซิร์ฟเวอร์ React
  • 322 เมื่อได้รับแจ้งให้ดำเนินการเขียนการกำหนดค่าไปยังส่วนประกอบ.json

เมื่อเสร็จแล้ว คุณได้ตั้งค่า CLI ที่ช่วยให้เราสามารถเพิ่มส่วนประกอบ React ลงในแอปพลิเคชัน Next.js ของคุณได้อย่างง่ายดาย ถัดไป ในหน้าต่างเทอร์มินัลของคุณ ให้รันคำสั่งด้านล่างเพื่อรับองค์ประกอบปุ่ม อินพุต พื้นที่ข้อความ ป๊อปโอเวอร์ ปฏิทิน และขนมปังปิ้ง:

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

เมื่อเสร็จแล้ว คุณจะเห็น 331 ไดเรกทอรีภายใน 342 ไดเร็กทอรีที่มี 358 , 361 , 371 , 384 , 394 , 405 , 413 , 428 และ 431 .

จากนั้น เปิด 440 ไฟล์และทำการเพิ่มเติมต่อไปนี้:

+ // 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>
 )
}

ในการเปลี่ยนแปลงโค้ดข้างต้น คุณได้นำเข้า 457 แล้ว ส่วนประกอบ (สร้างโดย 463 ) และตรวจสอบให้แน่ใจว่ามีอยู่ในแอปพลิเคชัน Next.js ทั้งหมดของคุณ ช่วยให้คุณสามารถแสดงการแจ้งเตือนแบบโทสต์ได้จากทุกที่ในโค้ดของคุณผ่านทาง 474 ขอเกี่ยว.

สร้างคิวขั้นสูงเพื่อจัดเก็บทวีตตามกำหนดเวลา

ในส่วนนี้ คุณจะได้เรียนรู้วิธีใช้ Upstash Queue เพื่อจัดเก็บข้อมูลทวีตตามกำหนดเวลา คุณจะได้เรียนรู้วิธีสร้างโค้ดฝั่งเซิร์ฟเวอร์ซึ่งเรียกใช้เป็นฟังก์ชันแทนการใช้บนเส้นทาง API โดยใช้การดำเนินการของเซิร์ฟเวอร์ Next.js

ขั้นแรก ในหน้าต่างเทอร์มินัลของคุณ ให้ดำเนินการต่อไปนี้เพื่อติดตั้ง Upstash SDK:

npm install @upstash/qstash @upstash/queue @upstash/redis@1.28.0

คำสั่งดังกล่าวจะติดตั้งแพ็คเกจต่อไปนี้:

  • 488 :SDK เพื่อโต้ตอบกับอินสแตนซ์ Upstash QStash ของคุณผ่านคำขอ HTTP
  • 493 :SDK เพื่อจัดการคิวข้อความตามสตรีม สนับสนุนโดย Upstash Redis
  • 504 :SDK เพื่อโต้ตอบผ่านคำขอ HTTP ด้วย Redis ซึ่งสร้างขึ้นบน Upstash REST API

เริ่มต้นไคลเอนต์ Upstash Redis และ Upstash Queue

หากต้องการใช้ไลบรารีที่ติดตั้งด้านบนเพื่อโต้ตอบกับ Upstash Queue ของคุณ ให้สร้างไฟล์ 517 ด้วยรหัสต่อไปนี้:

// 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,
})

โค้ดด้านบนทำหน้าที่ดังต่อไปนี้:

  • นำเข้า 529 และ 533 คลาสที่ส่งออกโดยแพ็คเกจ
  • ส่งออก 545 อินสแตนซ์ที่ชี้ไปที่ Upstash Redis URL พร้อมด้วยโทเค็นการอนุญาตคำขอ
  • ส่งออก 553 อินสแตนซ์ที่ชี้ไปที่ Upstash Redis ที่สร้างขึ้นด้านบน ตั้งชื่อคิวเป็น 560 และ 575 ถึง 5 ทำให้สามารถประมวลผลข้อความพร้อมกันได้สูงสุด 5 รายการ

เมื่อใช้อินสแตนซ์คิว คุณจะสร้างการดำเนินการเซิร์ฟเวอร์ Next.js ที่จะยอมรับข้อความทวีตและวันที่ทวีตเพื่อสร้างและผลักดันออบเจ็กต์ทวีตเข้าไปในคิวสำหรับการประมวลผลในอนาคต สร้างไฟล์ 580 ด้วยรหัสต่อไปนี้:

// 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 }
 }
}

โค้ดด้านบนทำหน้าที่ดังต่อไปนี้:

  • นำเข้า 599 ตัวอย่าง
  • ส่งออกการทำงานของเซิร์ฟเวอร์ชื่อ 605 ที่ยอมรับการส่งแบบฟอร์มที่มีข้อความและวันที่ของทวีตตามกำหนดเวลา
  • คำนวณเวลาระหว่างนั้นจนถึงเวลาที่ทวีตถูกกำหนดไว้
  • แทรกวัตถุทวีตที่มีวันที่และข้อความที่มีการหน่วงเวลาที่ตั้งไว้เป็นเวลาที่คำนวณไว้ข้างต้น

ด้วยวิธีนี้ คุณจึงมั่นใจได้ว่าทวีตจะถูกผลักไปที่คิวเฉพาะเมื่อมีการกำหนดเวลาไว้เท่านั้น วิธีนี้ช่วยลดความยุ่งยากในการรักษาสถานะของคิว ทำให้มั่นใจได้ว่า เท่านั้น ทวีตที่กำหนดไว้ในแต่ละวันจะอยู่ในคิว

มาดูการขออนุญาตจากผู้ใช้เพื่อทวีตในนามของพวกเขาโดยใช้โฟลว์ PKCE ของ OAuth 2.0

ใช้การตรวจสอบสิทธิ์ผู้ใช้ด้วย Twitter OAuth 2.0

ในส่วนนี้ คุณจะได้เรียนรู้วิธีตั้งค่าขั้นตอนการตรวจสอบสิทธิ์ Twitter OAuth 2.0 ในแอปพลิเคชันของคุณโดยการกำหนดค่าไคลเอนต์ Twitter OAuth และใช้ฟังก์ชันตัวช่วยที่ Twitter SDK มอบให้สำหรับงานการตรวจสอบสิทธิ์ ขั้นตอนการตรวจสอบสิทธิ์เกี่ยวข้องกับการสร้างการอนุญาตและจุดสิ้นสุดการโทรกลับ ทำให้ผู้ใช้สามารถให้สิทธิ์การเข้าถึงและรับโทเค็น โดยโทเค็นการเข้าถึงจะถูกจัดเก็บไว้ใน Upstash Redis คุณยังจะสร้างสถานะการตรวจสอบสิทธิ์ผ่านจุดสิ้นสุดที่ระบุว่ามีโทเค็นการเข้าถึงที่ถูกต้องใน Upstash Redis

ขั้นแรก ในหน้าต่างเทอร์มินัลของคุณ ให้รันคำสั่งด้านล่างเพื่อติดตั้งไลบรารีที่จำเป็นสำหรับการใช้การรับรองความถูกต้อง Twitter OAuth 2.0:

npm install twitter-api-sdk

คำสั่งดังกล่าวจะติดตั้งแพ็คเกจต่อไปนี้:

  • 611 :TypeScript SDK สำหรับ Twitter API

สร้างไคลเอนต์การตรวจสอบสิทธิ์ Twitter

เพื่อให้สามารถสร้าง URL การอนุญาตโดยไม่ต้องเจาะลึกความซับซ้อนของ Twitter API คุณจะต้องใช้ไคลเอนต์การรับรองความถูกต้องโดย Twitter SDK สร้างไฟล์ 625 ภายใน 632 ไดเร็กทอรีด้วยรหัสต่อไปนี้:

// 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'],
})

โค้ดด้านบนเริ่มต้นด้วยการนำเข้าตัวช่วยตรวจสอบสิทธิ์จาก Twitter SDK จากนั้นจะส่งออกไคลเอ็นต์การตรวจสอบสิทธิ์ซึ่งจะช่วยประหยัดเวลาในการเรียนรู้ไวยากรณ์ Twitter API โดยจัดให้มีฟังก์ชันตัวช่วยในการสร้าง URL การอนุญาตและขอโทเค็นการเข้าถึงจากผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์

เตรียม URL การอนุญาต Twitter

ขั้นตอนแรกในโฟลว์ OAuth 2.0 คือผู้ใช้จะถูกเปลี่ยนเส้นทางไปยัง URL การให้สิทธิ์ URL การอนุญาตเป็นจุดสิ้นสุดที่เซิร์ฟเวอร์ OAuth 2.0 มอบให้ โดยที่ผู้ใช้ถูกเปลี่ยนเส้นทางเพื่อเริ่มกระบวนการอนุญาตโดยการให้สิทธิ์แก่แอปพลิเคชันไคลเอนต์ โดยปกติ ผู้ใช้จะมีตัวเลือกหลายตัวเลือก (เช่น 643 , 658 ฯลฯ) ที่หน้าจอลงชื่อเข้าใช้/อัป จากนั้นจะพาไปยังหน้าจอการอนุญาตที่โฮสต์ไว้ของแพลตฟอร์ม (ที่นี่ Twitter)

สร้างไฟล์ 663 ด้วยรหัสต่อไปนี้:

// 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)
}

โค้ดด้านบนทำหน้าที่ดังต่อไปนี้:

  • นำเข้า 675 ฟังก์ชันตัวช่วยที่ขยาย Web Response API
  • นำเข้า 684 สร้างไว้ก่อนหน้านี้
  • ส่งออก 697 ตัวจัดการ HTTP ซึ่งตอบสนองต่อคำขอ GET ขาเข้าบน 707 .
  • สร้าง URL การอนุญาตโดยใช้ 711 ฟังก์ชันตัวช่วยของ Twitter SDK
  • เปลี่ยนเส้นทางไปยัง URL การอนุญาตที่สร้างขึ้นโดยใช้ 725 วิธีการ NextResponse

เรามาต่อกันที่การสร้างอุปกรณ์ปลายทางที่ตอบสนองต่อคำขอเมื่อผู้ใช้อนุญาตแอปพลิเคชัน Twitter ของคุณด้วยการเข้าถึง

เตรียม URL โทรกลับเพื่อขออนุมัติ

ขั้นตอนที่สองในโฟลว์ OAuth 2.0 ตอบสนองต่อการโทรกลับจากแพลตฟอร์มการตรวจสอบสิทธิ์ ในการจัดการคำขอโทรกลับการอนุญาตที่เข้ามาจาก Twitter คุณจะต้องกำหนดค่าตำแหน่งข้อมูลในแอปพลิเคชันของคุณซึ่งผู้ใช้จะถูกเปลี่ยนเส้นทางหลังจากให้สิทธิ์การเข้าถึง URL โทรกลับนี้จำเป็นสำหรับการรับรหัสอนุญาต ทำให้แอปพลิเคชันของคุณสามารถบันทึกโทเค็นการเข้าถึงที่ได้รับใน Upstash Redis ด้วยโทเค็นนั้น คุณสามารถทวีตอัตโนมัติผ่าน API ในแอปพลิเคชันของคุณได้

สร้างไฟล์ 730 ด้วยรหัสต่อไปนี้:

// 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)
}

โค้ดด้านบนทำหน้าที่ดังต่อไปนี้:

  • นำเข้า 748 อินสแตนซ์ที่ใช้ Upstash Redis
  • นำเข้า 758 ฟังก์ชันตัวช่วยที่ขยาย Web Response API
  • นำเข้า 760 สร้างไว้ก่อนหน้านี้
  • ส่งออก 773 ตัวจัดการ HTTP ซึ่งตอบสนองต่อคำขอ GET ขาเข้าบน 786 .
  • ทำลายโครงสร้าง 790 พารามิเตอร์การค้นหาจาก URL โทรกลับ
  • สร้าง URL การอนุญาตเหมือนก่อนหน้านี้เป็นแฮ็กเพื่ออัปเดตสถานะภายในที่สร้างโดย SDK
  • เรียก 808 ทำงานโดย Twitter SDK เพื่อรับการเข้าถึงและรีเฟรชโทเค็น ซึ่งจะช่วยให้คุณสร้างทวีตผ่าน API ได้
  • ทำลายโครงสร้าง 810 จาก 824 วัตถุที่ได้รับ
  • บันทึกค่าโทเค็นการเข้าถึงที่ได้รับด้วย 833 เป็นกุญแจสำคัญใน Upstash Redis
  • เปลี่ยนเส้นทางไปยัง URL ดัชนี (849 ) โดยใช้ 859 วิธีการ NextResponse

ตอนนี้คุณดำเนินการขั้นตอน Twitter OAuth 2.0 เสร็จแล้ว

มี 865 ที่ถูกต้อง ในอินสแตนซ์ Upstash Redis เป็นตัวบ่งชี้สถานะโฟลว์การตรวจสอบสิทธิ์ หากต้องการสื่อสารสิ่งเดียวกันในส่วนติดต่อผู้ใช้ ให้สร้างไฟล์ 879 ด้วยรหัสต่อไปนี้:

// 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 })
}

โค้ดด้านบนทำหน้าที่ดังต่อไปนี้:

  • นำเข้า 880 อินสแตนซ์ที่ใช้ Upstash Redis
  • นำเข้า 892 ฟังก์ชันตัวช่วยที่ขยาย Web Response API
  • ส่งออก 900 ตัวจัดการ HTTP ซึ่งตอบสนองต่อคำขอ GET ขาเข้าบน 916 .
  • ดึงค่าที่เกี่ยวข้องกับ 928 คีย์ใน Upstash Redis
  • ส่งคืนการตอบสนอง JSON ที่มี 938 บูลีนที่ระบุว่ามีโทเค็นการเข้าถึงที่ถูกต้องอยู่ใน Upstash Redis หรือไม่

มาดูการสร้างอินเทอร์เฟซผู้ใช้เพื่อใช้จุดสิ้นสุด API ที่คุณสร้างขึ้นกันดีกว่า

สร้างอินเทอร์เฟซผู้ใช้เพื่อกำหนดเวลาทวีต

ในส่วนนี้ คุณจะได้เรียนรู้วิธีสร้างสถานะแบบฟอร์มเชิงโต้ตอบโดยใช้ React hooks 947 และ 958 และเรียกใช้การทำงานของเซิร์ฟเวอร์เพื่อกำหนดเวลาทวีต

ขั้นแรก คุณจะต้องสร้างส่วนประกอบ React ที่แสดงแบบฟอร์มที่มีข้อมูลทวีตที่จะกำหนดเวลาไว้ และแสดงการแจ้งเตือนแบบโทสต์ที่ระบุว่าข้อมูลทวีตนั้นหรือไม่ สร้างไฟล์ 963 ด้วยรหัสต่อไปนี้:

// 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>
 </>
 )
}

โค้ดด้านบนทำหน้าที่ดังต่อไปนี้:

  • นำเข้าส่วนประกอบที่สร้างโดย 974 คำสั่ง CLI ก่อนหน้านี้
  • ส่งออกองค์ประกอบ React ที่แสดง 986 ที่ซ่อนไว้ด้วยสายตา องค์ประกอบ HTML ที่อธิบายวันที่ของทวีตตามกำหนดเวลา
  • ส่วนประกอบยังแสดงผล 991 องค์ประกอบ HTML เพื่อยอมรับข้อความทวีตจากผู้ใช้ด้วยสายตา
  • ส่วนประกอบยังแสดงผล 1004 ซึ่งถูกปิดใช้งานตามเงื่อนไขตามสถานะของการส่งแบบฟอร์มก่อนหน้า
  • ส่วนประกอบยังใช้ 1014 ขอเพื่อรีเซ็ตแบบฟอร์มหากการกระทำของเซิร์ฟเวอร์ส่งผลให้สำเร็จ ไม่ว่าจะด้วยวิธีใด ระบบจะแสดงการแจ้งเตือนแบบปิ้งที่มุมขวาล่างเพื่อระบุสถานะของคำขอ

ต่อไป คุณจะสร้างส่วนประกอบที่แสดงสถานะสถานะการตรวจสอบสิทธิ์ Twitter ของผู้ใช้ สร้างไฟล์ 1027 ด้วยรหัสต่อไปนี้:

// 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>
 )
}

โค้ดด้านบนทำหน้าที่ดังต่อไปนี้:

  • นำเข้า 1038 และ 1048 hooks โดย React เพื่อใช้ในการดึงข้อมูลสถานะของการตรวจสอบสิทธิ์ผู้ใช้
  • ส่งออกส่วนประกอบ React ที่แสดงผล 1057 ส่วนประกอบ (โดย 1061 ) ในสถานะที่แตกต่างกัน โดยเชื่อมโยงแต่ละสถานะกับสถานะการตรวจสอบสิทธิ์ Twitter ของผู้ใช้

เพื่อแสดงแบบฟอร์มสำหรับผู้ใช้ที่อนุญาตให้พวกเขาโต้ตอบและกำหนดเวลาทวีตขณะที่พวกเขาเปิดเส้นทางดัชนี (เช่น 1074 ) สร้างไฟล์ 1083 ด้วยรหัสต่อไปนี้:

// 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>
 )
}

โค้ดด้านบนทำหน้าที่ดังต่อไปนี้:

  • นำเข้า 1090 และ 1106 ส่วนประกอบที่สร้างขึ้นก่อนหน้านี้
  • นำเข้า 1117 hook โดย React เพื่อให้สามารถประมวลผลข้อมูลที่ส่งคืนโดยการกระทำของเซิร์ฟเวอร์ Next.js โดยใช้ 1121 ตัวแปรและอนุญาตให้เรียกใช้การกระทำของเซิร์ฟเวอร์ผ่านการส่งแบบฟอร์ม
  • นำเข้า 1136 การทำงานของเซิร์ฟเวอร์ที่สร้างขึ้นก่อนหน้านี้
  • ส่งออกส่วนประกอบ React ที่มี 1147 ส่วนประกอบที่มี 1150 id และตั้งค่าให้เรียกใช้ 1169 เมื่อผู้ใช้ส่งแบบฟอร์ม

กำหนดเวลาทวีตโดยใช้ Upstash QStash

หากต้องการกำหนดเวลาทวีตในนามของผู้ใช้ คุณจะต้องสร้างตำแหน่งข้อมูลที่จะใช้ข้อมูลทวีตที่จัดเก็บไว้ใน Upstash Queue จากนั้น POST ไปที่ Twitter API เพื่อดำเนินการทวีต สร้างไฟล์ 1176 ด้วยรหัสต่อไปนี้:

// 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)

โค้ดด้านบนทำหน้าที่ดังต่อไปนี้:

  • นำเข้า 1188 และ 1193 อินสแตนซ์ที่ใช้ Upstash Redis และ Upstash Queue ตามลำดับ
  • นำเข้า 1203 ฟังก์ชั่นโดย Upstash ที่จะตรวจสอบลายเซ็นคำขอเพื่อให้แน่ใจว่าคำขอมาจาก QStash เท่านั้น
  • สร้างฟังก์ชัน 1218 ที่ยอมรับข้อความทวีตและโทเค็นการเข้าถึงเพื่อดำเนินการทวีตในนามของผู้ใช้ที่ได้รับการรับรองความถูกต้อง
  • สร้าง 1220 ตัวจัดการ HTTP ซึ่งตอบสนองต่อคำขอ POST ขาเข้าที่ 1233 . ดึงข้อความ 4 ข้อความจาก Upstash Queue และเรียกใช้ 1248 ฟังก์ชั่นในการทวีตในนามของผู้ใช้

การใช้ Upstash QStash คุณสามารถกำหนดเวลากระบวนการดำเนินการทวีตได้ สมมติว่าคุณต้องการทำให้เป็นอัตโนมัติ โดยทุกๆ วันในเวลาเที่ยงคืน กระบวนการจะเริ่มต้นเองและทวีตก็ดับลง ในการทำเช่นนั้น คุณจะใช้จุดสิ้นสุดที่สร้างขึ้นก่อนหน้านี้:1252 ใน QStash

สร้างตัวกำหนดเวลาทวีตด้วย Upstash:คำแนะนำทีละขั้นตอน

ไปที่แท็บ QStash ในคอนโซล Upstash เลื่อนลงไปที่แท็บ Request Builder และดำเนินการต่อไปนี้:

  • เลือก 1268 แท็บ
  • กรอก 1272 เป็น URL ที่สมบูรณ์ไปยัง 1286 ของคุณ จุดสิ้นสุด
  • เลือก 1291 เป็น 1306 .
  • เลือก 1318 เป็น 1327 .
  • คลิก 1330 .

ด้วยขั้นตอนข้างต้น คุณได้สร้างงานที่ POST เป็น 1347 ทุกวันเวลาเที่ยงคืน

นั่นเป็นการเรียนรู้มากมาย! คุณทำเสร็จแล้วตอนนี้ ✨

ปรับใช้กับ Vercel

ตอนนี้พื้นที่เก็บข้อมูลพร้อมที่จะปรับใช้กับ Vercel แล้ว ใช้ขั้นตอนต่อไปนี้เพื่อปรับใช้:

  • เริ่มต้นด้วยการสร้างพื้นที่เก็บข้อมูล GitHub ที่มีโค้ดของแอปของคุณ
  • จากนั้น ไปที่แดชบอร์ด Vercel และสร้างโปรเจ็กต์ใหม่ .
  • เชื่อมโยงโปรเจ็กต์ใหม่กับที่เก็บ GitHub ที่คุณเพิ่งสร้างขึ้น
  • ในการตั้งค่า ให้อัปเดต 1352  เพื่อจับคู่กับ 1368 ในพื้นที่ของคุณ  ไฟล์
  • คลิก 1370 .

ข้อมูลเพิ่มเติม

หากต้องการข้อมูลเชิงลึกโดยละเอียดเพิ่มเติม โปรดสำรวจข้อมูลอ้างอิงที่อ้างถึงในโพสต์นี้

  • พื้นที่เก็บข้อมูล GitHub
  • ขั้นตอนของ Twitter OAuth 2.0
  • การสร้างโทเค็นแอป Twitter
  • ตอบสนองแบบฟอร์ม Hooks
  • การทำงานของเซิร์ฟเวอร์ Next.js

บทสรุป

ในคู่มือนี้ คุณได้เรียนรู้วิธีสร้าง Tweet Scheduler ที่มีประสิทธิภาพโดยใช้ประโยชน์จากฐานข้อมูล Redis อันทรงพลังของ Upstash และคิว QStash ความสามารถในการปรับขนาดของ Upstash ช่วยให้มั่นใจได้ถึงการจัดเก็บและการกำหนดเวลาทวีตที่เชื่อถือได้ รวมกับการใช้งานที่ราบรื่นบน Vercel สร้างระบบอัตโนมัติเต็มรูปแบบ