fix: initial login flow bugs

pull/3/head
Travis Fischer 2022-12-03 02:46:57 -06:00
rodzic ddd9545731
commit eaa4357a6c
5 zmienionych plików z 73 dodań i 50 usunięć

Wyświetl plik

@ -36,7 +36,7 @@
#### Defined in
[chatgpt-api.ts:20](https://github.com/transitive-bullshit/chatgpt-api/blob/82a5232/src/chatgpt-api.ts#L20)
[chatgpt-api.ts:20](https://github.com/transitive-bullshit/chatgpt-api/blob/ddd9545/src/chatgpt-api.ts#L20)
## Methods
@ -50,7 +50,7 @@
#### Defined in
[chatgpt-api.ts:175](https://github.com/transitive-bullshit/chatgpt-api/blob/82a5232/src/chatgpt-api.ts#L175)
[chatgpt-api.ts:186](https://github.com/transitive-bullshit/chatgpt-api/blob/ddd9545/src/chatgpt-api.ts#L186)
___
@ -64,7 +64,7 @@ ___
#### Defined in
[chatgpt-api.ts:88](https://github.com/transitive-bullshit/chatgpt-api/blob/82a5232/src/chatgpt-api.ts#L88)
[chatgpt-api.ts:94](https://github.com/transitive-bullshit/chatgpt-api/blob/ddd9545/src/chatgpt-api.ts#L94)
___
@ -78,7 +78,7 @@ ___
#### Defined in
[chatgpt-api.ts:93](https://github.com/transitive-bullshit/chatgpt-api/blob/82a5232/src/chatgpt-api.ts#L93)
[chatgpt-api.ts:104](https://github.com/transitive-bullshit/chatgpt-api/blob/ddd9545/src/chatgpt-api.ts#L104)
___
@ -92,7 +92,7 @@ ___
#### Defined in
[chatgpt-api.ts:113](https://github.com/transitive-bullshit/chatgpt-api/blob/82a5232/src/chatgpt-api.ts#L113)
[chatgpt-api.ts:124](https://github.com/transitive-bullshit/chatgpt-api/blob/ddd9545/src/chatgpt-api.ts#L124)
___
@ -106,7 +106,7 @@ ___
#### Defined in
[chatgpt-api.ts:103](https://github.com/transitive-bullshit/chatgpt-api/blob/82a5232/src/chatgpt-api.ts#L103)
[chatgpt-api.ts:114](https://github.com/transitive-bullshit/chatgpt-api/blob/ddd9545/src/chatgpt-api.ts#L114)
___
@ -127,7 +127,7 @@ ___
#### Defined in
[chatgpt-api.ts:48](https://github.com/transitive-bullshit/chatgpt-api/blob/82a5232/src/chatgpt-api.ts#L48)
[chatgpt-api.ts:48](https://github.com/transitive-bullshit/chatgpt-api/blob/ddd9545/src/chatgpt-api.ts#L48)
___
@ -147,4 +147,4 @@ ___
#### Defined in
[chatgpt-api.ts:151](https://github.com/transitive-bullshit/chatgpt-api/blob/82a5232/src/chatgpt-api.ts#L151)
[chatgpt-api.ts:162](https://github.com/transitive-bullshit/chatgpt-api/blob/ddd9545/src/chatgpt-api.ts#L162)

Wyświetl plik

@ -2,30 +2,42 @@ chatgpt / [Exports](modules.md)
# ChatGPT API <!-- omit in toc -->
> Node.js TS wrapper around [ChatGPT](https://openai.com/blog/chatgpt/). Uses headless Chrome until the official API is released.
> Node.js wrapper around [ChatGPT](https://openai.com/blog/chatgpt/). Uses headless Chrome until the official API is released.
[![NPM](https://img.shields.io/npm/v/chatgpt.svg)](https://www.npmjs.com/package/chatgpt) [![Build Status](https://github.com/transitive-bullshit/chatgpt-api/actions/workflows/test.yml/badge.svg)](https://github.com/transitive-bullshit/chatgpt-api/actions/workflows/test.yml) [![MIT License](https://img.shields.io/badge/license-MIT-blue)](https://github.com/transitive-bullshit/chatgpt-api/blob/main/license) [![Prettier Code Formatting](https://img.shields.io/badge/code_style-prettier-brightgreen.svg)](https://prettier.io)
- [Intro](#intro)
- [Auth](#auth)
- [How it works](#how-it-works)
- [Install](#install)
- [Usage](#usage)
- [Example](#example)
- [Docs](#docs)
- [Todo](#todo)
- [Related](#related)
- [License](#license)
## Intro
This package is a Node.js TypeScript wrapper around [ChatGPT](https://openai.com/blog/chatgpt) by [OpenAI](https://openai.com).
This package is a Node.js wrapper around [ChatGPT](https://openai.com/blog/chatgpt) by [OpenAI](https://openai.com). TS batteries included. ✨
You can use it to start experimenting with ChatGPT by integrating it into websites, chatbots, etc...
You can use it to start building projects powered by ChatGPT like chatbots, websites, etc...
## Auth
## How it works
It uses headless Chromium via [Playwright](https://playwright.dev) under the hood, so **you still need to have access to ChatGPT**, but it makes it much easier to access programatically.
We use headless Chromium via [Playwright](https://playwright.dev) to automate the webapp, so **you still need to have access to ChatGPT**. It just makes building API-like integrations much easier.
Chromium is opened in non-headless mode by default, which is important because the first time you run `ChatGPTAPI`.init, you'll need to log in manually. Chromium is launched with a persistent context, so you shouldn't need to keep re-logging in after the first time.
Chromium will be opened in non-headless mode by default, which is important because the first time you run `ChatGPTAPI.init()`, you'll need to log in manually. We launch Chromium with a persistent context, however, so you shouldn't need to keep re-logging in after the first time. When you log in the first time, _make sure that you also dismiss the welcome modal_.
> **Note**
> We'll replace headless chrome with the official API once it's released.
## Install
```bash
npm install --save chatgpt
# or
yarn add chatgpt
# or
pnpm add chatgpt
```
## Usage
@ -35,10 +47,10 @@ import { ChatGPTAPI } from 'chatgpt'
async function example() {
const api = new ChatGPTAPI()
// open chromium and wait until the user has logged in
// open chromium and wait until you've logged in
await api.init({ auth: 'blocking' })
// send a message and wait for a complete response, then parse it as markdown
// send a message and wait for the response
const response = await api.sendMessage(
'Write a python version of bubble sort. Do not include example usage.'
)
@ -70,17 +82,18 @@ def bubble_sort(lst):
return lst
```
The default functionality is to parse ChatGPT responses as markdown using [html-to-md](https://github.com/stonehank/html-to-md). I've found the markdown parsing to work really well during my testing, but if you'd rather output plaintext, you can use:
By default, ChatGPT responses are parsed as markdown using [html-to-md](https://github.com/stonehank/html-to-md). I've found that this works really well during my testing, but if you'd rather output plaintext, you can use:
```ts
const api = new ChatGPTAPI({ markdown: false })
```
## Example
A full [example](./src/example.ts) is included for testing purposes:
A full example is included for testing purposes:
```
```bash
# clone repo
# install node deps
# then run
npx tsx src/example.ts
```
@ -88,15 +101,10 @@ npx tsx src/example.ts
See the [auto-generated docs](./docs/classes/ChatGPTAPI.md) for more info on methods parameters.
## Todo
- [ ] Add message and conversation IDs
- [ ] Add support for streaming responses
- [ ] Add basic unit tests
## Related
- Inspired by this [Go module](https://github.com/danielgross/whatsapp-gpt) by [Daniel Gross](https://github.com/danielgross)
- [Python port](https://github.com/taranjeet/chatgpt-api)
## License

Wyświetl plik

@ -22,7 +22,7 @@ You can use it to start building projects powered by ChatGPT like chatbots, webs
We use headless Chromium via [Playwright](https://playwright.dev) to automate the webapp, so **you still need to have access to ChatGPT**. It just makes building API-like integrations much easier.
Chromium will be opened in non-headless mode by default, which is important because the first time you run `ChatGPTAPI.init()`, you'll need to log in manually. We launch Chromium with a persistent context, however, so you shouldn't need to keep re-logging in after the first time.
Chromium will be opened in non-headless mode by default, which is important because the first time you run `ChatGPTAPI.init()`, you'll need to log in manually. We launch Chromium with a persistent context, however, so you shouldn't need to keep re-logging in after the first time. When you log in the first time, _make sure that you also dismiss the welcome modal_.
> **Note**
> We'll replace headless chrome with the official API once it's released.

Wyświetl plik

@ -58,14 +58,17 @@ export class ChatGPTAPI {
// dismiss welcome modal
do {
const modalSelector = '[data-headlessui-state="open"]'
if (!(await this._page.isVisible(modalSelector, { timeout: 500 }))) {
if (!(await this._page.$(modalSelector))) {
break
}
const modal = await this._page.locator(modalSelector)
if (modal) {
await modal.locator('button').last().click()
} else {
try {
await this._page.click(`${modalSelector} button:last-child`, {
timeout: 1000
})
} catch (err) {
// "next" button not found in welcome modal
break
}
} while (true)
@ -77,7 +80,10 @@ export class ChatGPTAPI {
break
}
console.log('Please sign in to ChatGPT')
console.log(
'Please sign in to ChatGPT using the Chromium browser window and dismiss the welcome modal...'
)
await delay(1000)
} while (true)
}
@ -86,8 +92,13 @@ export class ChatGPTAPI {
}
async getIsSignedIn() {
const inputBox = await this._getInputBox()
return !!inputBox
try {
const inputBox = await this._getInputBox()
return !!inputBox
} catch (err) {
// can happen when navigating during login
return false
}
}
async getLastMessage(): Promise<string | null> {
@ -154,8 +165,8 @@ export class ChatGPTAPI {
const lastMessage = await this.getLastMessage()
await inputBox.click()
await inputBox.fill(message)
await inputBox.click({ force: true })
await inputBox.fill(message, { force: true })
await inputBox.press('Enter')
do {

Wyświetl plik

@ -16,17 +16,21 @@ async function main() {
// Wait until the user signs in via the chromium browser
await oraPromise(
new Promise<void>(async (resolve, reject) => {
try {
await delay(1000)
const isSignedIn = await api.getIsSignedIn()
if (isSignedIn) {
return resolve()
do {
try {
await delay(1000)
const isSignedIn = await api.getIsSignedIn()
if (isSignedIn) {
return resolve()
}
} catch (err) {
return reject(err)
}
} catch (err) {
return reject(err)
}
} while (true)
}),
'Please sign in to ChatGPT'
'Please sign in to ChatGPT and dismiss the welcome modal'
)
}