rawandahmad698 / PyChatGPT

⚡️ Python client for the unofficial ChatGPT API with auto token regeneration, conversation tracking, proxy support and more.
MIT License
4.22k stars 447 forks source link

Log in if signed up with google account? #3

Open ThatDocBoi opened 1 year ago

ThatDocBoi commented 1 year ago

I can't find a place to enter my google auth cookie, would it be possible to implement this feature? Thanks.

rawandahmad698 commented 1 year ago

Hi, currently Google sign in is not supported, best to create an account with email & password. I'll look into it on future considerations

2659170494 commented 1 year ago

Hi, currently Google sign in is not supported, best to create an account with email & password. I'll look into it on future considerations

After logging in with Google, Google will return a callback link to openai( auth0.openai.com/login/callback?state=$state&code=$code&scope=email+profile+https://www.googleapis.com/auth/userinfo.profile+openid+https://www.googleapis.com/auth/userinfo.email&authuser=0&prompt=none)

The login is completed after two 302 jumps in the returned connection(https://auth0.openai.com/authorize/resume?state=$state)(https://chat.openai.com/api/auth/callback/auth0?code=$code&state=$state), perhaps you can decompile from this link or try to get the key from it and import it to PyChatGpt login?

reycn commented 1 year ago

Hi, currently Google sign in is not supported, best to create an account with email & password. I'll look into it on future considerations

After logging in with Google, Google will return a callback link to openai( auth0.openai.com/login/callback?state=$state&code=$code&scope=email+profile+https://www.googleapis.com/auth/userinfo.profile+openid+https://www.googleapis.com/auth/userinfo.email&authuser=0&prompt=none)

The login is completed after two 302 jumps in the returned connection(https://auth0.openai.com/authorize/resume?state=$state)(https://chat.openai.com/api/auth/callback/auth0?code=$code&state=$state), perhaps you can decompile from this link or try to get the key from it and import it to PyChatGpt login?

Google is very good at anti-scrawling so my suggestion is not to waste time on this.

prakhar897 commented 1 year ago

If it helps, I'm able to bypass this by using auth token directly. But I've written my code in JS.

import { v4 as uuidv4 } from "uuid";
import ExpiryMap from "expiry-map";

const KEY_ACCESS_TOKEN = "accessToken";

const cache = new ExpiryMap(10 * 1000);

async function getAccessToken() {
    if (cache.get(KEY_ACCESS_TOKEN)) {
        return cache.get(KEY_ACCESS_TOKEN)
      }
      const resp = await fetch('https://chat.openai.com/api/auth/session')
      if (resp.status === 403) {
        throw new Error('CLOUDFLARE')
      }
      const data = await resp.json().catch(() => ({}))
      if (!data.accessToken) {
        throw new Error('UNAUTHORIZED')
      }
      cache.set(KEY_ACCESS_TOKEN, data.accessToken)
      return data.accessToken;
}

async function getAnswer(question, callback) {
    const accessToken = await getAccessToken();
    await fetchSSE("https://chat.openai.com/backend-api/conversation", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${accessToken}`,
        },
        body: JSON.stringify({
            action: "next",
            messages: [
                {
                    id: uuidv4(),
                    role: "user",
                    content: {
                        content_type: "text",
                        parts: [question],
                    },
                },
            ],
            model: "text-davinci-002-render",
            parent_message_id: uuidv4(),
        }),
        onMessage(message) {
            //console.log("sse message", message);

            if (message === "[DONE]") {
                return;
            }

            try {
                const data = JSON.parse(message);
                var text = data.message?.content?.parts?.[0];
                if(data != undefined && data.detail != undefined && data.detail.message != undefined && data.detail.message == `We're currently processing too many requests. Please try again later.`){        
                    text = `ChatGPT is currently processing too many requests. Please try again later.`;
                }
                if (text) {
                    callback(text);
                }
            } catch (error) { }
        },
    });
}

export async function fetchSSE(resource, options) {
  const { onMessage, ...fetchOptions } = options;
  const resp = await fetch(resource, fetchOptions);
  const parser = createParser((event) => {
    if (event.type === "event") {
      onMessage(event.data);
    } 
  });
  for await (const chunk of streamAsyncIterable(resp.body)) {  
    const str = new TextDecoder().decode(chunk);
    if(str === `{"detail":{"message":"We're currently processing too many requests. Please try again later."}}`){
      onMessage(str);
    }
    parser.feed(str);
  }
}

export async function* streamAsyncIterable(stream) {
    const reader = stream.getReader();
    try {
      while (true) {
        const { done, value } = await reader.read();
        if (done) {
          return;
        }
        yield value;
      }
    } finally {
      reader.releaseLock();
    }
  }