Skip to content
This repository has been archived by the owner on Aug 18, 2023. It is now read-only.

Commit

Permalink
Merge pull request #8 from muharamdani/feature/auto-relogin-and-more-…
Browse files Browse the repository at this point in the history
…modular-code

Feature | More modular code and add auto re-login feature
  • Loading branch information
muharamdani authored Mar 17, 2023
2 parents 8ef5946 + cd179d7 commit 2505ddb
Show file tree
Hide file tree
Showing 21 changed files with 858 additions and 325 deletions.
58 changes: 49 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
# Quora Poe
This is a CLI tool to call the Quora Poe API through GraphQL. It is a work in progress, and currently supports the following:
This is a tool to call the Quora Poe API through GraphQL. It is a work in progress, and currently supports the following:
- Auto login using temporary email, so you don't need to use your own email/phone number.
- Semi auto login using your own email/phone number, you need to enter the OTP manually.
- Manual login using your own email/phone number, you need to enter the OTP manually.
- Chat with 4 types of bots (Sage, Claude, ChatGPT, and Dragonfly).
- Stream responses support from the bot.
- Clear the chat history.
- Auto re-login after session expires (only for auto login).
- Module support, now you can use this tool as a module.

# Demo's
## CLI
<p>
<img alt="CLI demo" src="./demos/demo-converstation-cli.gif">
</p>

## Client module (after login)
<p>
<img alt="Client Demo after login" src="./demos/demo-client-auto-after-login.gif">
</p>

## Client module (before login)
<p>
<img alt="Client Demo before login" src="./demos/demo-client-auto-before-login.gif">
</p>

## Client module (auto re-login after session expires)
<p>
<img alt="Client Demo re-login after session expires" src="./demos/demo-client-auto-re-login.gif">
</p>

## Requirements
- NodeJS 16.0.0 or higher
Expand All @@ -19,19 +42,36 @@ npm install
```

## Usage

To start, run:

### Module
Please see file [`./src/client_auto.ts`](./src/client_auto.ts) or [`./src/client_manual.ts`](./src/client_manual.ts) for example.
Or you can try to run the following command:
```
npm start
node ./dist/client_auto.js
```
### CLI
```
npm run cli
```
If you don't want stream responses, you can change the `stream_response` variable in the `config.json` file to `false`.

## TODO List
- [ ] Make it modular, so it can be used as a library
- [ ] Add support for re-login after session expires
- [ ] Add support for get chat history
- [ ] Add support for delete message

## Notes
- Since I have to work on this project in my free time, I can't guarantee that I will be able to update this project frequently.
- I'm not have much experience with TypeScript, so if you have any suggestions, best practices, or anything, please let me know or create a pull request.
- I'm not publishing this tool to NPM yet. If you want to use this tool as a module, you can clone this repo and build it yourself.
- If you have any questions, please create an issue.

## Contributing
To contribute to this repo, fork it first, then create a new branch, and create a pull request.

## Disclaimer
This tool is not affiliated with Quora in any way. I am not responsible for any misuse of this tool.
Don't sue me.

Also, please don't use auto login feature to spam the bot, like creating a lot of accounts for any purpose. I don't want this temporary email service to be banned.

To contribute to this repo, fork first and create a pull request.
## License
[MIT](https://choosealicense.com/licenses/mit/)
28 changes: 27 additions & 1 deletion config.example.json
Original file line number Diff line number Diff line change
@@ -1 +1,27 @@
{"quora_formkey":"","quora_cookie":""}
{
"stream_response": true,
"quora_formkey": "",
"quora_cookie": "",
"channel_name": "",
"app_settings": {
"formkey": "",
"tchannelData": {
"minSeq": "",
"channel": "",
"channelHash": "",
"boxName": "",
"baseHost": "",
"targetUrl": "",
"enableWebsocket": true
}
},
"chat_ids": {
"a2": 0,
"capybara": 0,
"nutria": 0,
"chinchilla": 0
},
"auto_login": true,
"email": "",
"sid_token": ""
}
Binary file added demos/demo-client-auto-after-login.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demos/demo-client-auto-before-login.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demos/demo-client-auto-re-login.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demos/demo-converstation-cli.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions dist/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ChatBot from "./index.js";
const bot = new ChatBot();
await bot.startCli();
11 changes: 11 additions & 0 deletions dist/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ChatBot from "./index.js";
const bot = new ChatBot();
// Used to check if the formkey and cookie is available
const isFormkeyAvailable = await bot.getCredentials();
if (!isFormkeyAvailable) {
console.log("Formkey and cookie not available");
// Set the formkey, cookie and any other data needed and save it into config.json
await bot.setCredentials();
const chatId = await bot.getChatId("a2");
console.log(chatId);
}
26 changes: 26 additions & 0 deletions dist/client_auto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import ChatBot from "./index.js";
const bot = new ChatBot();
// Used to check if the formkey and cookie is available
const isFormkeyAvailable = await bot.getCredentials();
if (!isFormkeyAvailable) {
await bot.setCredentials();
await bot.subscribe(); // for websocket(stream response) purpose
await bot.login("auto");
}
const ai = "a2"; // bot list are in config.example.json, key "chat_ids"
// If you want to clear the chat context, you can use this
await bot.clearContext(ai);
// If you want to get the response (with stream), you can use this
// NOTE that you need to call this before you send the message
// await getUpdatedSettings(bot.config.channel_name, bot.config.quora_cookie);
// await bot.subscribe();
// const ws = await connectWs();
// If you want to send a message, you can use this
await bot.sendMsg(ai, "Hello, who are you?");
// If you want to get the response (without stream), you can use this
const response = await bot.getResponse(ai);
console.log(response);
// // If you want to get the response (with stream), you can use this
// process.stdout.write("Response: ");
// await listenWs(ws);
// console.log('\n');
39 changes: 39 additions & 0 deletions dist/client_manual.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import ChatBot from "./index.js";
const bot = new ChatBot();
// Used to check if the formkey and cookie is available
const isFormkeyAvailable = await bot.getCredentials();
if (!isFormkeyAvailable) {
console.log("Formkey and cookie not available");
// Set the formkey, cookie and any other data needed and save it into config.json
await bot.setCredentials();
const myEmail = "[email protected]";
const signInStatus = await bot.sendVerifCode(null, myEmail);
// After you get the verification code, you can use this step to log in
// then check signInStatus
let loginStatus = "invalid_verification_code";
while (loginStatus !== "success") {
if (signInStatus === 'user_with_confirmed_phone_number_not_found') {
loginStatus = await bot.signUpWithVerificationCode(myEmail, null, 123456); // 123456 is the verification code
}
else {
loginStatus = await bot.signInOrUp(myEmail, null, 123456); // 123456 is the verification code
}
}
}
const ai = "a2"; // bot list are in config.example.json, key "chat_ids"
// If you want to clear the chat context, you can use this
await bot.clearContext(ai);
// If you want to get the response (with stream), you can use this
// NOTE that you need to call this before you send the message
// await getUpdatedSettings(bot.config.channel_name, bot.config.quora_cookie);
// await bot.subscribe();
// const ws = await connectWs();
// If you want to send a message, you can use this
await bot.sendMsg(ai, "Hello, who are you?");
// If you want to get the response (without stream), you can use this
const response = await bot.getResponse(ai);
console.log(response);
// // If you want to get the response (with stream), you can use this
// process.stdout.write("Response: ");
// await listenWs(ws);
// console.log('\n');
2 changes: 1 addition & 1 deletion dist/credential.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const getUpdatedSettings = async (channelName, pbCookie) => {
const appSettings = await _setting.json(), { tchannelData: { minSeq: minSeq } } = appSettings;
const credentials = JSON.parse(readFileSync("config.json", "utf8"));
credentials.app_settings.tchannelData.minSeq = minSeq;
writeFile("config.json", JSON.stringify(credentials), function (err) {
writeFile("config.json", JSON.stringify(credentials, null, 4), function (err) {
if (err) {
console.log(err);
}
Expand Down
Loading

0 comments on commit 2505ddb

Please sign in to comment.