@@ -3,7 +3,8 @@ import prompts from "prompts";
33import ora from "ora" ;
44import * as dotenv from "dotenv" ;
55import { readFileSync , writeFile } from "fs" ;
6- import scrape from "./credential.js" ;
6+ import { scrape , getUpdatedSettings } from "./credential.js" ;
7+ import { listenWs , connectWs , disconnectWs } from "./websocket.js" ;
78import * as mail from "./mail.js" ;
89dotenv . config ( ) ;
910const spinner = ora ( {
@@ -24,28 +25,26 @@ class ChatBot {
2425 constructor ( ) {
2526 this . headers = {
2627 'Content-Type' : 'application/json' ,
27- 'User-Agent' : 'PostmanRuntime/7.31.1' ,
2828 'Accept' : '*/*' ,
2929 'Host' : 'poe.com' ,
3030 'Accept-Encoding' : 'gzip, deflate, br' ,
3131 'Connection' : 'keep-alive' ,
32+ 'Origin' : 'https://poe.com' ,
3233 } ;
3334 this . chatId = 0 ;
3435 this . bot = "" ;
3536 }
3637 async getCredentials ( ) {
3738 const credentials = JSON . parse ( readFileSync ( "config.json" , "utf8" ) ) ;
3839 const { quora_formkey, quora_cookie } = credentials ;
39- console . log ( "FROM GET CREDENTIALS" ) ;
40- console . log ( quora_formkey ) ;
41- console . log ( quora_cookie ) ;
4240 if ( quora_formkey . length > 0 && quora_cookie . length > 0 ) {
4341 formkey = quora_formkey ;
4442 pbCookie = quora_cookie ;
4543 // For websocket later feature
4644 channelName = credentials . channel_name ;
4745 appSettings = credentials . app_settings ;
4846 this . headers [ "poe-formkey" ] = formkey ;
47+ this . headers [ "poe-tchannel" ] = channelName ;
4948 this . headers [ "Cookie" ] = pbCookie ;
5049 }
5150 return quora_formkey . length > 0 && quora_cookie . length > 0 ;
@@ -61,20 +60,37 @@ class ChatBot {
6160 // set value
6261 formkey = result . appSettings . formkey ;
6362 pbCookie = result . pbCookie ;
64- console . log ( "FROM SET CREDENTIALS" ) ;
65- console . log ( formkey ) ;
66- console . log ( pbCookie ) ;
6763 // For websocket later feature
6864 channelName = result . channelName ;
6965 appSettings = result . appSettings ;
7066 this . headers [ "poe-formkey" ] = formkey ;
67+ this . headers [ "poe-tchannel" ] = channelName ;
7168 this . headers [ "Cookie" ] = pbCookie ;
7269 writeFile ( "config.json" , JSON . stringify ( credentials ) , function ( err ) {
7370 if ( err ) {
7471 console . log ( err ) ;
7572 }
7673 } ) ;
7774 }
75+ async subscribe ( ) {
76+ const query = {
77+ queryName : 'subscriptionsMutation' ,
78+ variables : {
79+ subscriptions : [
80+ {
81+ subscriptionName : 'messageAdded' ,
82+ query : 'subscription subscriptions_messageAdded_Subscription(\n $chatId: BigInt!\n) {\n messageAdded(chatId: $chatId) {\n id\n messageId\n creationTime\n state\n ...ChatMessage_message\n ...chatHelpers_isBotMessage\n }\n}\n\nfragment ChatMessageDownvotedButton_message on Message {\n ...MessageFeedbackReasonModal_message\n ...MessageFeedbackOtherModal_message\n}\n\nfragment ChatMessageDropdownMenu_message on Message {\n id\n messageId\n vote\n text\n ...chatHelpers_isBotMessage\n}\n\nfragment ChatMessageFeedbackButtons_message on Message {\n id\n messageId\n vote\n voteReason\n ...ChatMessageDownvotedButton_message\n}\n\nfragment ChatMessageOverflowButton_message on Message {\n text\n ...ChatMessageDropdownMenu_message\n ...chatHelpers_isBotMessage\n}\n\nfragment ChatMessageSuggestedReplies_SuggestedReplyButton_message on Message {\n messageId\n}\n\nfragment ChatMessageSuggestedReplies_message on Message {\n suggestedReplies\n ...ChatMessageSuggestedReplies_SuggestedReplyButton_message\n}\n\nfragment ChatMessage_message on Message {\n id\n messageId\n text\n author\n linkifiedText\n state\n ...ChatMessageSuggestedReplies_message\n ...ChatMessageFeedbackButtons_message\n ...ChatMessageOverflowButton_message\n ...chatHelpers_isHumanMessage\n ...chatHelpers_isBotMessage\n ...chatHelpers_isChatBreak\n ...chatHelpers_useTimeoutLevel\n ...MarkdownLinkInner_message\n}\n\nfragment MarkdownLinkInner_message on Message {\n messageId\n}\n\nfragment MessageFeedbackOtherModal_message on Message {\n id\n messageId\n}\n\nfragment MessageFeedbackReasonModal_message on Message {\n id\n messageId\n}\n\nfragment chatHelpers_isBotMessage on Message {\n ...chatHelpers_isHumanMessage\n ...chatHelpers_isChatBreak\n}\n\nfragment chatHelpers_isChatBreak on Message {\n author\n}\n\nfragment chatHelpers_isHumanMessage on Message {\n author\n}\n\nfragment chatHelpers_useTimeoutLevel on Message {\n id\n state\n text\n messageId\n}\n'
83+ } ,
84+ {
85+ subscriptionName : 'viewerStateUpdated' ,
86+ query : 'subscription subscriptions_viewerStateUpdated_Subscription {\n viewerStateUpdated {\n id\n ...ChatPageBotSwitcher_viewer\n }\n}\n\nfragment BotHeader_bot on Bot {\n displayName\n ...BotImage_bot\n}\n\nfragment BotImage_bot on Bot {\n profilePicture\n displayName\n}\n\nfragment BotLink_bot on Bot {\n displayName\n}\n\nfragment ChatPageBotSwitcher_viewer on Viewer {\n availableBots {\n id\n ...BotLink_bot\n ...BotHeader_bot\n }\n}\n'
87+ }
88+ ]
89+ } ,
90+ query : 'mutation subscriptionsMutation(\n $subscriptions: [AutoSubscriptionQuery!]!\n) {\n autoSubscribe(subscriptions: $subscriptions) {\n viewer {\n id\n }\n }\n}\n'
91+ } ;
92+ await this . makeRequest ( query ) ;
93+ }
7894 async start ( ) {
7995 const isFormkeyAvailable = await this . getCredentials ( ) ;
8096 if ( ! isFormkeyAvailable ) {
@@ -92,8 +108,12 @@ class ChatBot {
92108 process . exit ( 0 ) ;
93109 }
94110 await this . setCredentials ( ) ;
111+ await this . subscribe ( ) ;
95112 await this . login ( mode ) ;
96113 }
114+ await getUpdatedSettings ( channelName , pbCookie ) ;
115+ await this . subscribe ( ) ;
116+ const ws = await connectWs ( ) ;
97117 const { bot } = await prompts ( {
98118 type : "select" ,
99119 name : "bot" ,
@@ -111,6 +131,7 @@ class ChatBot {
111131 "\n!exit - exit the chat" +
112132 "\n!clear - clear chat history" +
113133 "\n!submit - submit prompt" ;
134+ await this . clearContext ( ) ;
114135 console . log ( helpMsg ) ;
115136 let submitedPrompt = "" ;
116137 while ( true ) {
@@ -124,7 +145,8 @@ class ChatBot {
124145 console . log ( helpMsg ) ;
125146 }
126147 else if ( prompt === "!exit" ) {
127- break ;
148+ await disconnectWs ( ws ) ;
149+ process . exit ( 0 ) ;
128150 }
129151 else if ( prompt === "!clear" ) {
130152 spinner . start ( "Clearing chat history..." ) ;
@@ -138,12 +160,11 @@ class ChatBot {
138160 console . log ( "No prompt to submit" ) ;
139161 continue ;
140162 }
141- spinner . start ( "Waiting for response..." ) ;
142163 await this . sendMsg ( submitedPrompt ) ;
143- let response = await this . getResponse ( ) ;
144- spinner . stop ( ) ;
164+ process . stdout . write ( "Response: " ) ;
165+ await listenWs ( ws ) ;
166+ console . log ( '\n' ) ;
145167 submitedPrompt = "" ;
146- console . log ( response ) ;
147168 }
148169 else {
149170 submitedPrompt += prompt + "\n" ;
@@ -163,8 +184,6 @@ class ChatBot {
163184 async login ( mode ) {
164185 if ( mode === "auto" ) {
165186 const { email, sid_token } = await mail . createNewEmail ( ) ;
166- console . log ( "EMAIL: " + email ) ;
167- console . log ( "SID_TOKEN: " + sid_token ) ;
168187 const status = await this . sendVerifCode ( null , email ) ;
169188 spinner . start ( "Waiting for OTP code..." ) ;
170189 const otp_code = await mail . getPoeOTPCode ( sid_token ) ;
@@ -332,6 +351,7 @@ class ChatBot {
332351 throw new Error ( "Could not send message" ) ;
333352 }
334353 }
354+ // Responce without stream
335355 async getResponse ( ) {
336356 let text ;
337357 let state ;
0 commit comments