11import { GoogleGenerativeAI } from '@google/generative-ai' ;
22
33export interface Env {
4+ RATE_LIMIT : KVNamespace ;
45 GEMINI_API_KEY : string ;
56}
67
@@ -10,6 +11,33 @@ const corsHeaders = {
1011 'Access-Control-Allow-Headers' : 'Content-Type' ,
1112} ;
1213
14+ const MAX_REQUESTS_ALLOWED = 10 ;
15+ const DURATION = 60_000 ;
16+
17+ async function checkRateLimit ( ip : string , env : Env ) {
18+ const key = `ip_key:${ ip } ` ;
19+ const now = Date . now ( ) ;
20+ let value = await env . RATE_LIMIT . get ( key ) ;
21+ let data = { count : 0 , time : now } ;
22+
23+ if ( value ) {
24+ try {
25+ data = JSON . parse ( value ) ;
26+ } catch {
27+ data = { count : 0 , time : now } ;
28+ }
29+ }
30+
31+ if ( now - data . time > DURATION ) {
32+ data . count = 0 ;
33+ data . time = now ;
34+ }
35+
36+ data . count += 1 ;
37+ await env . RATE_LIMIT . put ( key , JSON . stringify ( data ) , { expirationTtl : 65 } ) ;
38+
39+ return data . count <= MAX_REQUESTS_ALLOWED ;
40+ }
1341async function handleTranslate ( request : Request , model : ReturnType < GoogleGenerativeAI [ 'getGenerativeModel' ] > ) {
1442 const { code, targetLanguage } = await request . json < { code : string ; targetLanguage : string } > ( ) ;
1543
@@ -73,11 +101,22 @@ export default {
73101 }
74102
75103 try {
104+ const ip = request . headers . get ( 'CF-Connecting-IP' ) || 'unknown' ;
105+ const allowed = await checkRateLimit ( ip , env ) ;
106+ if ( ! allowed ) {
107+ return new Response ( JSON . stringify ( { error : "Too many requests. Try again later." } ) , {
108+ status : 429 ,
109+ headers : { ...corsHeaders , 'Content-Type' : 'application/json' } ,
110+ } ) ;
111+ }
76112 const url = new URL ( request . url ) ;
77113 const path = url . pathname ;
78114 const genAI = new GoogleGenerativeAI ( env . GEMINI_API_KEY ) ;
79115 const model = genAI . getGenerativeModel ( { model : 'gemini-2.0-flash' } ) ;
80116
117+ if ( path === "/test-rate-limit" ) {
118+ return new Response ( JSON . stringify ( "Proceed !" ) )
119+ }
81120 if ( path === '/' || path === '/v1/translate' ) {
82121 return await handleTranslate ( request , model ) ;
83122 }
0 commit comments