@@ -13,6 +13,7 @@ import (
1313 "io"
1414 "os"
1515 "strings"
16+ "time"
1617
1718 "github.com/gin-gonic/gin"
1819 "github.com/google/uuid"
@@ -170,16 +171,18 @@ func (h *Handler) nightmare(c *gin.Context) {
170171 }})
171172 return
172173 }
173- proxyUrl := h .proxy .GetProxyIP ()
174- input_tokens := util .CountToken (original_request .Messages [0 ].Content )
175- secret := h .token .GetSecret ()
176- authHeader := c .GetHeader ("Authorization" )
177- if authHeader != "" {
178- customAccessToken := strings .Replace (authHeader , "Bearer " , "" , 1 )
179- if strings .HasPrefix (customAccessToken , "eyJhbGciOiJSUzI1NiI" ) {
180- secret = h .token .GenerateTempToken (customAccessToken )
181- }
174+ if len (original_request .Messages ) == 0 {
175+ c .JSON (400 , gin.H {"error" : gin.H {
176+ "message" : "Missing required parameter: messages" ,
177+ "type" : "invalid_request_error" ,
178+ "param" : "messages" ,
179+ "code" : "missing_required_parameter" ,
180+ }})
181+ return
182182 }
183+ proxyUrl := h .proxy .GetProxyIP ()
184+ input_tokens := countMessagesTokens (original_request .Messages )
185+ secret := h .secretFromAuthorization (c .GetHeader ("Authorization" ), original_requestHasFiles (original_request ), false )
183186 if secret == nil {
184187 c .JSON (400 , gin.H {"error" : "Not Account Found." })
185188 c .Abort ()
@@ -288,16 +291,9 @@ func (h *Handler) responses(c *gin.Context) {
288291 proxyUrl := h .proxy .GetProxyIP ()
289292 input_tokens := 0
290293 for _ , message := range original_request .Messages {
291- input_tokens += util .CountToken (message .Content )
292- }
293- secret := h .token .GetSecret ()
294- authHeader := c .GetHeader ("Authorization" )
295- if authHeader != "" {
296- customAccessToken := strings .Replace (authHeader , "Bearer " , "" , 1 )
297- if strings .HasPrefix (customAccessToken , "eyJhbGciOiJSUzI1NiI" ) {
298- secret = h .token .GenerateTempToken (customAccessToken )
299- }
294+ input_tokens += util .CountToken (message .Text ())
300295 }
296+ secret := h .secretFromAuthorization (c .GetHeader ("Authorization" ), original_requestHasFiles (original_request ), false )
301297 if secret == nil {
302298 c .JSON (400 , gin.H {"error" : "Not Account Found." })
303299 c .Abort ()
@@ -509,6 +505,77 @@ func (h *Handler) imageGenerations(c *gin.Context) {
509505 c .JSON (200 , officialtypes .NewImageGenerationResponse (data ))
510506}
511507
508+ func (h * Handler ) files (c * gin.Context ) {
509+ secret := h .secretFromAuthorization (c .GetHeader ("Authorization" ), true , true )
510+ if secret == nil || secret .Token == "" || secret .IsFree {
511+ c .JSON (400 , gin.H {"error" : gin.H {
512+ "message" : "Files API requires a logged-in ChatGPT access token." ,
513+ "type" : "invalid_request_error" ,
514+ "param" : nil ,
515+ "code" : "missing_access_token" ,
516+ }})
517+ return
518+ }
519+
520+ formFile , err := c .FormFile ("file" )
521+ if err != nil {
522+ c .JSON (400 , gin.H {"error" : gin.H {
523+ "message" : "Missing required multipart field: file" ,
524+ "type" : "invalid_request_error" ,
525+ "param" : "file" ,
526+ "code" : "missing_required_parameter" ,
527+ }})
528+ return
529+ }
530+ file , err := formFile .Open ()
531+ if err != nil {
532+ c .JSON (400 , gin.H {"error" : gin.H {
533+ "message" : err .Error (),
534+ "type" : "invalid_request_error" ,
535+ "param" : "file" ,
536+ "code" : "file_open_error" ,
537+ }})
538+ return
539+ }
540+ defer file .Close ()
541+ data , err := io .ReadAll (file )
542+ if err != nil {
543+ c .JSON (400 , gin.H {"error" : gin.H {
544+ "message" : err .Error (),
545+ "type" : "invalid_request_error" ,
546+ "param" : "file" ,
547+ "code" : "file_read_error" ,
548+ }})
549+ return
550+ }
551+ if len (data ) == 0 {
552+ c .JSON (400 , gin.H {"error" : gin.H {
553+ "message" : "Uploaded file is empty" ,
554+ "type" : "invalid_request_error" ,
555+ "param" : "file" ,
556+ "code" : "empty_file" ,
557+ }})
558+ return
559+ }
560+
561+ contentType := formFile .Header .Get ("Content-Type" )
562+ client := bogdanfinn .NewStdClient ()
563+ client .SetCookies ("https://chatgpt.com" , chatgpt .BasicCookies )
564+ uploaded , status , err := chatgpt .UploadFile (client , secret , h .proxy .GetProxyIP (), formFile .Filename , contentType , c .PostForm ("purpose" ), data )
565+ if err != nil {
566+ c .JSON (status , gin.H {"error" : gin.H {
567+ "message" : err .Error (),
568+ "type" : "file_upload_error" ,
569+ "param" : "file" ,
570+ "code" : "file_upload_error" ,
571+ }})
572+ return
573+ }
574+ uploaded .CreatedAt = time .Now ().Unix ()
575+ chatgpt .RegisterUploadedFile (uploaded )
576+ c .JSON (200 , uploaded )
577+ }
578+
512579func (h * Handler ) engines (c * gin.Context ) {
513580 type ResData struct {
514581 ID string `json:"id"`
@@ -539,6 +606,40 @@ func (h *Handler) engines(c *gin.Context) {
539606 })
540607}
541608
609+ func (h * Handler ) secretFromAuthorization (authHeader string , needsPaid bool , allowFallbackPaid bool ) * tokens.Secret {
610+ secret := h .token .GetSecret ()
611+ if needsPaid || allowFallbackPaid {
612+ secret = h .token .GetPaidSecret ()
613+ }
614+ if authHeader != "" {
615+ customAccessToken := strings .TrimSpace (strings .Replace (authHeader , "Bearer " , "" , 1 ))
616+ if strings .HasPrefix (customAccessToken , "eyJhbGciOiJSUzI1NiI" ) {
617+ secret = h .token .GenerateTempToken (customAccessToken )
618+ }
619+ }
620+ if needsPaid && (secret == nil || secret .Token == "" || secret .IsFree ) && ! allowFallbackPaid {
621+ return nil
622+ }
623+ return secret
624+ }
625+
626+ func countMessagesTokens (messages []officialtypes.APIMessage ) int {
627+ total := 0
628+ for _ , message := range messages {
629+ total += util .CountToken (message .Text ())
630+ }
631+ return total
632+ }
633+
634+ func original_requestHasFiles (request officialtypes.APIRequest ) bool {
635+ for _ , message := range request .Messages {
636+ if len (message .Files ()) > 0 {
637+ return true
638+ }
639+ }
640+ return false
641+ }
642+
542643var ttsFmtMap = map [string ]string {
543644 "mp3" : "mp3" ,
544645 "opus" : "opus" ,
0 commit comments