mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	Port poe messaging to JS
This commit is contained in:
		
							
								
								
									
										29
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										29
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -24,7 +24,8 @@ | |||||||
|                 "png-chunks-encode": "^1.0.0", |                 "png-chunks-encode": "^1.0.0", | ||||||
|                 "png-chunks-extract": "^1.0.0", |                 "png-chunks-extract": "^1.0.0", | ||||||
|                 "rimraf": "^3.0.2", |                 "rimraf": "^3.0.2", | ||||||
|                 "sanitize-filename": "^1.6.3" |                 "sanitize-filename": "^1.6.3", | ||||||
|  |                 "ws": "^8.13.0" | ||||||
|             }, |             }, | ||||||
|             "bin": { |             "bin": { | ||||||
|                 "TavernAI": "server.js" |                 "TavernAI": "server.js" | ||||||
| @@ -1964,6 +1965,26 @@ | |||||||
|             "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", |             "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", | ||||||
|             "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" |             "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/ws": { | ||||||
|  |             "version": "8.13.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", | ||||||
|  |             "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", | ||||||
|  |             "engines": { | ||||||
|  |                 "node": ">=10.0.0" | ||||||
|  |             }, | ||||||
|  |             "peerDependencies": { | ||||||
|  |                 "bufferutil": "^4.0.1", | ||||||
|  |                 "utf-8-validate": ">=5.0.2" | ||||||
|  |             }, | ||||||
|  |             "peerDependenciesMeta": { | ||||||
|  |                 "bufferutil": { | ||||||
|  |                     "optional": true | ||||||
|  |                 }, | ||||||
|  |                 "utf-8-validate": { | ||||||
|  |                     "optional": true | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "node_modules/xhr": { |         "node_modules/xhr": { | ||||||
|             "version": "2.6.0", |             "version": "2.6.0", | ||||||
|             "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", |             "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", | ||||||
| @@ -3491,6 +3512,12 @@ | |||||||
|             "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", |             "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", | ||||||
|             "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" |             "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" | ||||||
|         }, |         }, | ||||||
|  |         "ws": { | ||||||
|  |             "version": "8.13.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", | ||||||
|  |             "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", | ||||||
|  |             "requires": {} | ||||||
|  |         }, | ||||||
|         "xhr": { |         "xhr": { | ||||||
|             "version": "2.6.0", |             "version": "2.6.0", | ||||||
|             "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", |             "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", | ||||||
|   | |||||||
| @@ -16,7 +16,8 @@ | |||||||
|         "png-chunks-encode": "^1.0.0", |         "png-chunks-encode": "^1.0.0", | ||||||
|         "png-chunks-extract": "^1.0.0", |         "png-chunks-extract": "^1.0.0", | ||||||
|         "rimraf": "^3.0.2", |         "rimraf": "^3.0.2", | ||||||
|         "sanitize-filename": "^1.6.3" |         "sanitize-filename": "^1.6.3", | ||||||
|  |         "ws": "^8.13.0" | ||||||
|     }, |     }, | ||||||
|     "name": "TavernAI", |     "name": "TavernAI", | ||||||
|     "version": "1.2.0", |     "version": "1.2.0", | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								poe-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								poe-test.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | const poe = require('./poe'); | ||||||
|  |  | ||||||
|  | async function test() { | ||||||
|  |     const client = new poe.Client(); | ||||||
|  |     await client.init('pb-cookie'); | ||||||
|  |      | ||||||
|  |     const bots = client.get_bot_names(); | ||||||
|  |     console.log(bots); | ||||||
|  |  | ||||||
|  |     await client.purge_conversation('a2', -1); | ||||||
|  |  | ||||||
|  |     let reply; | ||||||
|  |     for await (const mes of client.send_message('a2', 'Hello')) { | ||||||
|  |         reply = mes.text; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     console.log(reply); | ||||||
|  |     client.disconnect_ws(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | test(); | ||||||
							
								
								
									
										391
									
								
								poe.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										391
									
								
								poe.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,391 @@ | |||||||
|  | const WebSocket = require('ws'); | ||||||
|  | const axios = require('axios'); | ||||||
|  | const fs = require('fs'); | ||||||
|  | const path = require('path'); | ||||||
|  | const http = require('http'); | ||||||
|  | const https = require('https'); | ||||||
|  |  | ||||||
|  | const parent_path = path.resolve(__dirname); | ||||||
|  | const queries_path = path.join(parent_path, "poe_graphql"); | ||||||
|  | let queries = {}; | ||||||
|  |  | ||||||
|  | const logger = console; | ||||||
|  |  | ||||||
|  | const user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0"; | ||||||
|  |  | ||||||
|  | function load_queries() { | ||||||
|  |     const files = fs.readdirSync(queries_path); | ||||||
|  |     for (const filename of files) { | ||||||
|  |         const ext = path.extname(filename); | ||||||
|  |         if (ext !== '.graphql') { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         const queryName = path.basename(filename, ext); | ||||||
|  |         const query = fs.readFileSync(path.join(queries_path, filename), 'utf-8'); | ||||||
|  |         queries[queryName] = query; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function generate_payload(query_name, variables) { | ||||||
|  |     return { | ||||||
|  |         query: queries[query_name], | ||||||
|  |         variables: variables, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function request_with_retries(method, attempts = 10) { | ||||||
|  |     const url = ''; | ||||||
|  |     for (let i = 0; i < attempts; i++) { | ||||||
|  |         try { | ||||||
|  |             const response = await method(); | ||||||
|  |             if (response.status === 200) { | ||||||
|  |                 return response; | ||||||
|  |             } | ||||||
|  |             logger.warn(`Server returned a status code of ${response.status} while downloading ${url}. Retrying (${i + 1}/${attempts})...`); | ||||||
|  |         } | ||||||
|  |         catch (err) { | ||||||
|  |             console.log(err); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     throw new Error(`Failed to download ${url} too many times.`); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class Client { | ||||||
|  |     gql_url = "https://poe.com/api/gql_POST"; | ||||||
|  |     gql_recv_url = "https://poe.com/api/receive_POST"; | ||||||
|  |     home_url = "https://poe.com"; | ||||||
|  |     settings_url = "https://poe.com/api/settings"; | ||||||
|  |  | ||||||
|  |     formkey = ""; | ||||||
|  |     next_data = {}; | ||||||
|  |     bots = {}; | ||||||
|  |     active_messages = {}; | ||||||
|  |     message_queues = {}; | ||||||
|  |     bot_names = []; | ||||||
|  |     ws = null; | ||||||
|  |     ws_connected = false; | ||||||
|  |  | ||||||
|  |     async init(token, proxy = null) { | ||||||
|  |         this.proxy = proxy; | ||||||
|  |         this.session = axios.default.create({ | ||||||
|  |             timeout: 60000, | ||||||
|  |             httpAgent: new http.Agent({ keepAlive: true }), | ||||||
|  |             httpsAgent: new https.Agent({ keepAlive: true }), | ||||||
|  |         }); | ||||||
|  |         if (proxy) { | ||||||
|  |             this.session.defaults.proxy = { | ||||||
|  |                 "http": proxy, | ||||||
|  |                 "https": proxy, | ||||||
|  |             }; | ||||||
|  |             logger.info(`Proxy enabled: ${proxy}`); | ||||||
|  |         } | ||||||
|  |         const cookies = `p-b=${token}; Domain=poe.com`; | ||||||
|  |         this.headers = { | ||||||
|  |             "User-Agent": user_agent, | ||||||
|  |             "Referrer": "https://poe.com/", | ||||||
|  |             "Origin": "https://poe.com", | ||||||
|  |             "Cookie": cookies, | ||||||
|  |         }; | ||||||
|  |         this.ws_domain = `tch${Math.floor(Math.random() * 1e6)}`; | ||||||
|  |         this.session.defaults.headers.common = this.headers; | ||||||
|  |         this.next_data = await this.get_next_data(); | ||||||
|  |         this.channel = await this.get_channel_data(); | ||||||
|  |         await this.connect_ws(); | ||||||
|  |         this.bots = await this.get_bots(); | ||||||
|  |         this.bot_names = this.get_bot_names(); | ||||||
|  |         this.gql_headers = { | ||||||
|  |             "poe-formkey": this.formkey, | ||||||
|  |             "poe-tchannel": this.channel["channel"], | ||||||
|  |             ...this.headers, | ||||||
|  |         }; | ||||||
|  |         await this.subscribe(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async get_next_data() { | ||||||
|  |         logger.info('Downloading next_data...'); | ||||||
|  |  | ||||||
|  |         const r = await request_with_retries(() => this.session.get(this.home_url)); | ||||||
|  |         const jsonRegex = /<script id="__NEXT_DATA__" type="application\/json">(.+?)<\/script>/; | ||||||
|  |         const jsonText = jsonRegex.exec(r.data)[1]; | ||||||
|  |         const nextData = JSON.parse(jsonText); | ||||||
|  |  | ||||||
|  |         this.formkey = nextData.props.formkey; | ||||||
|  |         this.viewer = nextData.props.pageProps.payload.viewer; | ||||||
|  |  | ||||||
|  |         return nextData; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async get_bots() { | ||||||
|  |         const viewer = this.next_data.props.pageProps.payload.viewer; | ||||||
|  |         if (!viewer.availableBots) { | ||||||
|  |             throw new Error('Invalid token.'); | ||||||
|  |         } | ||||||
|  |         const botList = viewer.availableBots; | ||||||
|  |  | ||||||
|  |         const bots = {}; | ||||||
|  |         for (const bot of botList) { | ||||||
|  |             const url = `https://poe.com/_next/data/${this.next_data.buildId}/${bot.displayName.toLowerCase()}.json`; | ||||||
|  |             logger.info(`Downloading ${url}`); | ||||||
|  |  | ||||||
|  |             const r = await request_with_retries(() => this.session.get(url)); | ||||||
|  |  | ||||||
|  |             const chatData = r.data.pageProps.payload.chatOfBotDisplayName; | ||||||
|  |             bots[chatData.defaultBotObject.nickname] = chatData; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return bots; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     get_bot_names() { | ||||||
|  |         const botNames = {}; | ||||||
|  |         for (const botNickname in this.bots) { | ||||||
|  |             const botObj = this.bots[botNickname].defaultBotObject; | ||||||
|  |             botNames[botNickname] = botObj.displayName; | ||||||
|  |         } | ||||||
|  |         return botNames; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async get_channel_data(channel = null) { | ||||||
|  |         logger.info('Downloading channel data...'); | ||||||
|  |         const r = await request_with_retries(() => this.session.get(this.settings_url)); | ||||||
|  |         const data = r.data; | ||||||
|  |  | ||||||
|  |         this.formkey = data.formkey; | ||||||
|  |         return data.tchannelData; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     get_websocket_url(channel = null) { | ||||||
|  |         if (!channel) { | ||||||
|  |             channel = this.channel; | ||||||
|  |         } | ||||||
|  |         const query = `?min_seq=${channel.minSeq}&channel=${channel.channel}&hash=${channel.channelHash}`; | ||||||
|  |         return `wss://${this.ws_domain}.tch.${channel.baseHost}/up/${channel.boxName}/updates${query}`; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async send_query(queryName, variables) { | ||||||
|  |         for (let i = 0; i < 20; i++) { | ||||||
|  |             const payload = generate_payload(queryName, variables); | ||||||
|  |             const r = await request_with_retries(() => this.session.post(this.gql_url, payload, { headers: this.gql_headers })); | ||||||
|  |             if (!r.data.data) { | ||||||
|  |                 logger.warn(`${queryName} returned an error: ${data.errors[0].message} | Retrying (${i + 1}/20)`); | ||||||
|  |                 await new Promise((resolve) => setTimeout(resolve, 2000)); | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return r.data; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         throw new Error(`${queryName} failed too many times.`); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async subscribe() { | ||||||
|  |         logger.info("Subscribing to mutations") | ||||||
|  |         await this.send_query("SubscriptionsMutation", { | ||||||
|  |             "subscriptions": [ | ||||||
|  |                 { | ||||||
|  |                     "subscriptionName": "messageAdded", | ||||||
|  |                     "query": queries["MessageAddedSubscription"] | ||||||
|  |                 }, | ||||||
|  |                 { | ||||||
|  |                     "subscriptionName": "viewerStateUpdated", | ||||||
|  |                     "query": queries["ViewerStateUpdatedSubscription"] | ||||||
|  |                 } | ||||||
|  |             ] | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ws_run_thread() { | ||||||
|  |         this.ws = new WebSocket(this.get_websocket_url(), { | ||||||
|  |             headers: { | ||||||
|  |                 "User-Agent": user_agent | ||||||
|  |             }, | ||||||
|  |             rejectUnauthorized: false | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         this.ws.on("open", () => { | ||||||
|  |             this.on_ws_connect(this.ws); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         this.ws.on('message', (message) => { | ||||||
|  |             this.on_message(this.ws, message); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         this.ws.on('error', (error) => { | ||||||
|  |             this.on_ws_error(this.ws, error); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async connect_ws() { | ||||||
|  |         this.ws_connected = false; | ||||||
|  |         this.ws_run_thread(); | ||||||
|  |         while (!this.ws_connected) { | ||||||
|  |             await new Promise(resolve => setTimeout(() => { resolve() }, 10)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     disconnect_ws() { | ||||||
|  |         if (this.ws) { | ||||||
|  |             this.ws.close(); | ||||||
|  |         } | ||||||
|  |         this.ws_connected = false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     on_ws_connect(ws) { | ||||||
|  |         this.ws_connected = true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     on_ws_error(ws, error) { | ||||||
|  |         logger.warn(`Websocket returned error: ${error}`); | ||||||
|  |         this.disconnect_ws(); | ||||||
|  |         this.connect_ws(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     on_message(ws, msg) { | ||||||
|  |         const data = JSON.parse(msg); | ||||||
|  |         const message = JSON.parse(data["messages"][0])["payload"]["data"]["messageAdded"]; | ||||||
|  |  | ||||||
|  |         const copiedDict = Object.assign({}, this.active_messages); | ||||||
|  |         for (const [key, value] of Object.entries(copiedDict)) { | ||||||
|  |             //add the message to the appropriate queue | ||||||
|  |             if (value === message["messageId"] && key in this.message_queues) { | ||||||
|  |                 this.message_queues[key].push(message); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             //indicate that the response id is tied to the human message id | ||||||
|  |             else if (key !== "pending" && value === null && message["state"] !== "complete") { | ||||||
|  |                 this.active_messages[key] = message["messageId"]; | ||||||
|  |                 this.message_queues[key].push(message); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async *send_message(chatbot, message, with_chat_break = false, timeout = 20) { | ||||||
|  |         //if there is another active message, wait until it has finished sending | ||||||
|  |         while (Object.values(this.active_messages).includes(null)) { | ||||||
|  |             await new Promise(resolve => setTimeout(resolve, 10)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         //null indicates that a message is still in progress | ||||||
|  |         this.active_messages["pending"] = null; | ||||||
|  |  | ||||||
|  |         console.log(`Sending message to ${chatbot}: ${message}`); | ||||||
|  |  | ||||||
|  |         const messageData = await this.send_query("AddHumanMessageMutation", { | ||||||
|  |             "bot": chatbot, | ||||||
|  |             "query": message, | ||||||
|  |             "chatId": this.bots[chatbot]["chatId"], | ||||||
|  |             "source": null, | ||||||
|  |             "withChatBreak": with_chat_break | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         delete this.active_messages["pending"]; | ||||||
|  |  | ||||||
|  |         if (!messageData["data"]["messageCreateWithStatus"]["messageLimit"]["canSend"]) { | ||||||
|  |             throw new Error(`Daily limit reached for ${chatbot}.`); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let humanMessageId; | ||||||
|  |         try { | ||||||
|  |             const humanMessage = messageData["data"]["messageCreateWithStatus"]; | ||||||
|  |             humanMessageId = humanMessage["message"]["messageId"]; | ||||||
|  |         } catch (error) { | ||||||
|  |             throw new Error(`An unknown error occured. Raw response data: ${messageData}`); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         //indicate that the current message is waiting for a response | ||||||
|  |         this.active_messages[humanMessageId] = null; | ||||||
|  |         this.message_queues[humanMessageId] = []; | ||||||
|  |  | ||||||
|  |         let lastText = ""; | ||||||
|  |         let messageId; | ||||||
|  |         while (true) { | ||||||
|  |             try { | ||||||
|  |                 const message = this.message_queues[humanMessageId].shift(); | ||||||
|  |                 if (!message) { | ||||||
|  |                     await new Promise(resolve => setTimeout(() => resolve(), 1000)); | ||||||
|  |                     continue; | ||||||
|  |                     //throw new Error("Queue is empty"); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 //only break when the message is marked as complete | ||||||
|  |                 if (message["state"] === "complete") { | ||||||
|  |                     if (lastText && message["messageId"] === messageId) { | ||||||
|  |                         break; | ||||||
|  |                     } else { | ||||||
|  |                         continue; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 //update info about response | ||||||
|  |                 message["text_new"] = message["text"].substring(lastText.length); | ||||||
|  |                 lastText = message["text"]; | ||||||
|  |                 messageId = message["messageId"]; | ||||||
|  |  | ||||||
|  |                 yield message; | ||||||
|  |             } catch (error) { | ||||||
|  |                 delete this.active_messages[humanMessageId]; | ||||||
|  |                 delete this.message_queues[humanMessageId]; | ||||||
|  |                 throw new Error("Response timed out."); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         delete this.active_messages[humanMessageId]; | ||||||
|  |         delete this.message_queues[humanMessageId]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async send_chat_break(chatbot) { | ||||||
|  |         logger.info(`Sending chat break to ${chatbot}`); | ||||||
|  |         const result = await this.send_query("AddMessageBreakMutation", { | ||||||
|  |             "chatId": this.bots[chatbot]["chatId"] | ||||||
|  |         }); | ||||||
|  |         return result["data"]["messageBreakCreate"]["message"]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async get_message_history(chatbot, count = 25, cursor = null) { | ||||||
|  |         logger.info(`Downloading ${count} messages from ${chatbot}`); | ||||||
|  |         const result = await this.send_query("ChatListPaginationQuery", { | ||||||
|  |             "count": count, | ||||||
|  |             "cursor": cursor, | ||||||
|  |             "id": this.bots[chatbot]["id"] | ||||||
|  |         }); | ||||||
|  |         return result["data"]["node"]["messagesConnection"]["edges"]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async delete_message(message_ids) { | ||||||
|  |         logger.info(`Deleting messages: ${message_ids}`); | ||||||
|  |         if (!Array.isArray(message_ids)) { | ||||||
|  |             message_ids = [parseInt(message_ids)]; | ||||||
|  |         } | ||||||
|  |         const result = await this.send_query("DeleteMessageMutation", { | ||||||
|  |             "messageIds": message_ids | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async purge_conversation(chatbot, count = -1) { | ||||||
|  |         logger.info(`Purging messages from ${chatbot}`); | ||||||
|  |         let last_messages = (await this.get_message_history(chatbot, count = 50)).reverse(); | ||||||
|  |         while (last_messages.length) { | ||||||
|  |             const message_ids = []; | ||||||
|  |             for (const message of last_messages) { | ||||||
|  |                 if (count === 0) { | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 count--; | ||||||
|  |                 message_ids.push(message["node"]["messageId"]); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             await this.delete_message(message_ids); | ||||||
|  |  | ||||||
|  |             if (count === 0) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             last_messages = (await this.get_message_history(chatbot, count = 50)).reverse(); | ||||||
|  |         } | ||||||
|  |         logger.info("No more messages left to delete."); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | load_queries(); | ||||||
|  |  | ||||||
|  | module.exports = { Client }; | ||||||
							
								
								
									
										52
									
								
								poe_graphql/AddHumanMessageMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								poe_graphql/AddHumanMessageMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | mutation AddHumanMessageMutation( | ||||||
|  |     $chatId: BigInt! | ||||||
|  |     $bot: String! | ||||||
|  |     $query: String! | ||||||
|  |     $source: MessageSource | ||||||
|  |     $withChatBreak: Boolean! = false | ||||||
|  | ) { | ||||||
|  |     messageCreateWithStatus( | ||||||
|  |         chatId: $chatId | ||||||
|  |         bot: $bot | ||||||
|  |         query: $query | ||||||
|  |         source: $source | ||||||
|  |         withChatBreak: $withChatBreak | ||||||
|  |     ) { | ||||||
|  |         message { | ||||||
|  |             id | ||||||
|  |             __typename | ||||||
|  |             messageId | ||||||
|  |             text | ||||||
|  |             linkifiedText | ||||||
|  |             authorNickname | ||||||
|  |             state | ||||||
|  |             vote | ||||||
|  |             voteReason | ||||||
|  |             creationTime | ||||||
|  |             suggestedReplies | ||||||
|  |             chat { | ||||||
|  |                 id | ||||||
|  |                 shouldShowDisclaimer | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         messageLimit{ | ||||||
|  |           canSend | ||||||
|  |           numMessagesRemaining | ||||||
|  |           resetTime | ||||||
|  |           shouldShowReminder | ||||||
|  |         } | ||||||
|  |         chatBreak { | ||||||
|  |             id | ||||||
|  |             __typename | ||||||
|  |             messageId | ||||||
|  |             text | ||||||
|  |             linkifiedText | ||||||
|  |             authorNickname | ||||||
|  |             state | ||||||
|  |             vote | ||||||
|  |             voteReason | ||||||
|  |             creationTime | ||||||
|  |             suggestedReplies | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								poe_graphql/AddMessageBreakMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								poe_graphql/AddMessageBreakMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | mutation AddMessageBreakMutation($chatId: BigInt!) { | ||||||
|  |     messageBreakCreate(chatId: $chatId) { | ||||||
|  |         message { | ||||||
|  |             id | ||||||
|  |             __typename | ||||||
|  |             messageId | ||||||
|  |             text | ||||||
|  |             linkifiedText | ||||||
|  |             authorNickname | ||||||
|  |             state | ||||||
|  |             vote | ||||||
|  |             voteReason | ||||||
|  |             creationTime | ||||||
|  |             suggestedReplies | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								poe_graphql/AutoSubscriptionMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								poe_graphql/AutoSubscriptionMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | mutation AutoSubscriptionMutation($subscriptions: [AutoSubscriptionQuery!]!) { | ||||||
|  |     autoSubscribe(subscriptions: $subscriptions) { | ||||||
|  |         viewer { | ||||||
|  |             id | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								poe_graphql/BioFragment.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								poe_graphql/BioFragment.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | fragment BioFragment on Viewer { | ||||||
|  |     id | ||||||
|  |     poeUser { | ||||||
|  |         id | ||||||
|  |         uid | ||||||
|  |         bio | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										5
									
								
								poe_graphql/ChatAddedSubscription.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								poe_graphql/ChatAddedSubscription.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | subscription ChatAddedSubscription { | ||||||
|  | 	chatAdded { | ||||||
|  | 		...ChatFragment | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								poe_graphql/ChatFragment.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								poe_graphql/ChatFragment.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | fragment ChatFragment on Chat { | ||||||
|  |     id | ||||||
|  |     chatId | ||||||
|  |     defaultBotNickname | ||||||
|  |     shouldShowDisclaimer | ||||||
|  | } | ||||||
							
								
								
									
										316
									
								
								poe_graphql/ChatListPaginationQuery.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										316
									
								
								poe_graphql/ChatListPaginationQuery.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,316 @@ | |||||||
|  | query ChatListPaginationQuery( | ||||||
|  |   $count: Int = 5 | ||||||
|  |   $cursor: String | ||||||
|  |   $id: ID! | ||||||
|  | ) { | ||||||
|  |   node(id: $id) { | ||||||
|  |     __typename | ||||||
|  |     ...ChatPageMain_chat_1G22uz | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment BotImage_bot on Bot { | ||||||
|  |   image { | ||||||
|  |     __typename | ||||||
|  |     ... on LocalBotImage { | ||||||
|  |       localName | ||||||
|  |     } | ||||||
|  |     ... on UrlBotImage { | ||||||
|  |       url | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   displayName | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageDownvotedButton_message on Message { | ||||||
|  |   ...MessageFeedbackReasonModal_message | ||||||
|  |   ...MessageFeedbackOtherModal_message | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageDropdownMenu_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  |   vote | ||||||
|  |   text | ||||||
|  |   linkifiedText | ||||||
|  |   ...chatHelpers_isBotMessage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageFeedbackButtons_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  |   vote | ||||||
|  |   voteReason | ||||||
|  |   ...ChatMessageDownvotedButton_message | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageInputView_chat on Chat { | ||||||
|  |   id | ||||||
|  |   chatId | ||||||
|  |   defaultBotObject { | ||||||
|  |     nickname | ||||||
|  |     messageLimit { | ||||||
|  |       dailyBalance | ||||||
|  |       shouldShowRemainingMessageCount | ||||||
|  |     } | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  |   shouldShowDisclaimer | ||||||
|  |   ...chatHelpers_useSendMessage_chat | ||||||
|  |   ...chatHelpers_useSendChatBreak_chat | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageInputView_edges on MessageEdge { | ||||||
|  |   node { | ||||||
|  |     ...chatHelpers_isChatBreak | ||||||
|  |     ...chatHelpers_isHumanMessage | ||||||
|  |     state | ||||||
|  |     text | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageOverflowButton_message on Message { | ||||||
|  |   text | ||||||
|  |   ...ChatMessageDropdownMenu_message | ||||||
|  |   ...chatHelpers_isBotMessage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageSuggestedReplies_SuggestedReplyButton_chat on Chat { | ||||||
|  |   ...chatHelpers_useSendMessage_chat | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageSuggestedReplies_SuggestedReplyButton_message on Message { | ||||||
|  |   messageId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageSuggestedReplies_chat on Chat { | ||||||
|  |   ...ChatWelcomeView_chat | ||||||
|  |   ...ChatMessageSuggestedReplies_SuggestedReplyButton_chat | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageSuggestedReplies_message on Message { | ||||||
|  |   suggestedReplies | ||||||
|  |   ...ChatMessageSuggestedReplies_SuggestedReplyButton_message | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessage_chat on Chat { | ||||||
|  |   defaultBotObject { | ||||||
|  |     ...ChatPageDisclaimer_bot | ||||||
|  |     messageLimit { | ||||||
|  |       ...ChatPageRateLimitedBanner_messageLimit | ||||||
|  |     } | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  |   ...ChatMessageSuggestedReplies_chat | ||||||
|  |   ...ChatWelcomeView_chat | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessage_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  |   text | ||||||
|  |   author | ||||||
|  |   linkifiedText | ||||||
|  |   state | ||||||
|  |   ...ChatMessageSuggestedReplies_message | ||||||
|  |   ...ChatMessageFeedbackButtons_message | ||||||
|  |   ...ChatMessageOverflowButton_message | ||||||
|  |   ...chatHelpers_isHumanMessage | ||||||
|  |   ...chatHelpers_isBotMessage | ||||||
|  |   ...chatHelpers_isChatBreak | ||||||
|  |   ...chatHelpers_useTimeoutLevel | ||||||
|  |   ...MarkdownLinkInner_message | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessagesView_chat on Chat { | ||||||
|  |   ...ChatMessage_chat | ||||||
|  |   ...ChatWelcomeView_chat | ||||||
|  |   defaultBotObject { | ||||||
|  |     messageLimit { | ||||||
|  |       ...ChatPageRateLimitedBanner_messageLimit | ||||||
|  |     } | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessagesView_edges on MessageEdge { | ||||||
|  |   node { | ||||||
|  |     id | ||||||
|  |     messageId | ||||||
|  |     creationTime | ||||||
|  |     ...ChatMessage_message | ||||||
|  |     ...chatHelpers_isBotMessage | ||||||
|  |     ...chatHelpers_isHumanMessage | ||||||
|  |     ...chatHelpers_isChatBreak | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatPageDeleteFooter_chat on Chat { | ||||||
|  |   ...MessageDeleteConfirmationModal_chat | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatPageDisclaimer_bot on Bot { | ||||||
|  |   disclaimer | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatPageMain_chat_1G22uz on Chat { | ||||||
|  |   id | ||||||
|  |   chatId | ||||||
|  |   ...ChatMessageInputView_chat | ||||||
|  |   ...ChatPageShareFooter_chat | ||||||
|  |   ...ChatPageDeleteFooter_chat | ||||||
|  |   ...ChatMessagesView_chat | ||||||
|  |   ...MarkdownLinkInner_chat | ||||||
|  |   ...chatHelpers_useUpdateStaleChat_chat | ||||||
|  |   ...ChatSubscriptionPaywallContextWrapper_chat | ||||||
|  |   messagesConnection(last: $count, before: $cursor) { | ||||||
|  |     edges { | ||||||
|  |       ...ChatMessagesView_edges | ||||||
|  |       ...ChatMessageInputView_edges | ||||||
|  |       ...MarkdownLinkInner_edges | ||||||
|  |       node { | ||||||
|  |         ...chatHelpers_useUpdateStaleChat_message | ||||||
|  |         id | ||||||
|  |         __typename | ||||||
|  |       } | ||||||
|  |       cursor | ||||||
|  |       id | ||||||
|  |     } | ||||||
|  |     pageInfo { | ||||||
|  |       hasPreviousPage | ||||||
|  |       startCursor | ||||||
|  |     } | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatPageRateLimitedBanner_messageLimit on MessageLimit { | ||||||
|  |   numMessagesRemaining | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatPageShareFooter_chat on Chat { | ||||||
|  |   chatId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatSubscriptionPaywallContextWrapper_chat on Chat { | ||||||
|  |   defaultBotObject { | ||||||
|  |     messageLimit { | ||||||
|  |       numMessagesRemaining | ||||||
|  |       shouldShowRemainingMessageCount | ||||||
|  |     } | ||||||
|  |     ...SubscriptionPaywallModal_bot | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatWelcomeView_ChatWelcomeButton_chat on Chat { | ||||||
|  |   ...chatHelpers_useSendMessage_chat | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatWelcomeView_chat on Chat { | ||||||
|  |   ...ChatWelcomeView_ChatWelcomeButton_chat | ||||||
|  |   defaultBotObject { | ||||||
|  |     displayName | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment MarkdownLinkInner_chat on Chat { | ||||||
|  |   id | ||||||
|  |   chatId | ||||||
|  |   defaultBotObject { | ||||||
|  |     nickname | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  |   ...chatHelpers_useSendMessage_chat | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment MarkdownLinkInner_edges on MessageEdge { | ||||||
|  |   node { | ||||||
|  |     state | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment MarkdownLinkInner_message on Message { | ||||||
|  |   messageId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment MessageDeleteConfirmationModal_chat on Chat { | ||||||
|  |   id | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment MessageFeedbackOtherModal_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment MessageFeedbackReasonModal_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment SubscriptionPaywallModal_bot on Bot { | ||||||
|  |   displayName | ||||||
|  |   messageLimit { | ||||||
|  |     dailyLimit | ||||||
|  |     numMessagesRemaining | ||||||
|  |     shouldShowRemainingMessageCount | ||||||
|  |     resetTime | ||||||
|  |   } | ||||||
|  |   ...BotImage_bot | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_isBotMessage on Message { | ||||||
|  |   ...chatHelpers_isHumanMessage | ||||||
|  |   ...chatHelpers_isChatBreak | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_isChatBreak on Message { | ||||||
|  |   author | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_isHumanMessage on Message { | ||||||
|  |   author | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_useSendChatBreak_chat on Chat { | ||||||
|  |   id | ||||||
|  |   chatId | ||||||
|  |   defaultBotObject { | ||||||
|  |     nickname | ||||||
|  |     introduction | ||||||
|  |     model | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  |   shouldShowDisclaimer | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_useSendMessage_chat on Chat { | ||||||
|  |   id | ||||||
|  |   chatId | ||||||
|  |   defaultBotObject { | ||||||
|  |     nickname | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  |   shouldShowDisclaimer | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_useTimeoutLevel on Message { | ||||||
|  |   id | ||||||
|  |   state | ||||||
|  |   text | ||||||
|  |   messageId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_useUpdateStaleChat_chat on Chat { | ||||||
|  |   chatId | ||||||
|  |   ...chatHelpers_useSendChatBreak_chat | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_useUpdateStaleChat_message on Message { | ||||||
|  |   creationTime | ||||||
|  |   ...chatHelpers_isChatBreak | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								poe_graphql/ChatPaginationQuery.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								poe_graphql/ChatPaginationQuery.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | query ChatPaginationQuery($bot: String!, $before: String, $last: Int! = 10) { | ||||||
|  |     chatOfBot(bot: $bot) { | ||||||
|  |         id | ||||||
|  |         __typename | ||||||
|  |         messagesConnection(before: $before, last: $last) { | ||||||
|  |             pageInfo { | ||||||
|  |                 hasPreviousPage | ||||||
|  |             } | ||||||
|  |             edges { | ||||||
|  |                 node { | ||||||
|  |                     id | ||||||
|  |                     __typename | ||||||
|  |                     messageId | ||||||
|  |                     text | ||||||
|  |                     linkifiedText | ||||||
|  |                     authorNickname | ||||||
|  |                     state | ||||||
|  |                     vote | ||||||
|  |                     voteReason | ||||||
|  |                     creationTime | ||||||
|  |                     suggestedReplies | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								poe_graphql/ChatViewQuery.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								poe_graphql/ChatViewQuery.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | query ChatViewQuery($bot: String!) { | ||||||
|  |     chatOfBot(bot: $bot) { | ||||||
|  |         id | ||||||
|  |         chatId | ||||||
|  |         defaultBotNickname | ||||||
|  |         shouldShowDisclaimer | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								poe_graphql/DeleteHumanMessagesMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								poe_graphql/DeleteHumanMessagesMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | mutation DeleteHumanMessagesMutation($messageIds: [BigInt!]!) { | ||||||
|  |     messagesDelete(messageIds: $messageIds) { | ||||||
|  |         viewer { | ||||||
|  |             id | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								poe_graphql/DeleteMessageMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								poe_graphql/DeleteMessageMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | mutation deleteMessageMutation( | ||||||
|  |   $messageIds: [BigInt!]! | ||||||
|  | ) { | ||||||
|  |   messagesDelete(messageIds: $messageIds) { | ||||||
|  |     edgeIds | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								poe_graphql/HandleFragment.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								poe_graphql/HandleFragment.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | fragment HandleFragment on Viewer { | ||||||
|  |     id | ||||||
|  |     poeUser { | ||||||
|  |         id | ||||||
|  |         uid | ||||||
|  |         handle | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								poe_graphql/LoginWithVerificationCodeMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								poe_graphql/LoginWithVerificationCodeMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | mutation LoginWithVerificationCodeMutation( | ||||||
|  |     $verificationCode: String! | ||||||
|  |     $emailAddress: String | ||||||
|  |     $phoneNumber: String | ||||||
|  | ) { | ||||||
|  |     loginWithVerificationCode( | ||||||
|  |         verificationCode: $verificationCode | ||||||
|  |         emailAddress: $emailAddress | ||||||
|  |         phoneNumber: $phoneNumber | ||||||
|  |     ) { | ||||||
|  |         status | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										100
									
								
								poe_graphql/MessageAddedSubscription.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								poe_graphql/MessageAddedSubscription.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | |||||||
|  | subscription messageAdded ( | ||||||
|  |   $chatId: BigInt! | ||||||
|  | ) { | ||||||
|  |   messageAdded(chatId: $chatId) { | ||||||
|  |     id | ||||||
|  |     messageId | ||||||
|  |     creationTime | ||||||
|  |     state | ||||||
|  |     ...ChatMessage_message | ||||||
|  |     ...chatHelpers_isBotMessage | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageDownvotedButton_message on Message { | ||||||
|  |   ...MessageFeedbackReasonModal_message | ||||||
|  |   ...MessageFeedbackOtherModal_message | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageDropdownMenu_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  |   vote | ||||||
|  |   text | ||||||
|  |   linkifiedText | ||||||
|  |   ...chatHelpers_isBotMessage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageFeedbackButtons_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  |   vote | ||||||
|  |   voteReason | ||||||
|  |   ...ChatMessageDownvotedButton_message | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageOverflowButton_message on Message { | ||||||
|  |   text | ||||||
|  |   ...ChatMessageDropdownMenu_message | ||||||
|  |   ...chatHelpers_isBotMessage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageSuggestedReplies_SuggestedReplyButton_message on Message { | ||||||
|  |   messageId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessageSuggestedReplies_message on Message { | ||||||
|  |   suggestedReplies | ||||||
|  |   ...ChatMessageSuggestedReplies_SuggestedReplyButton_message | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatMessage_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  |   text | ||||||
|  |   author | ||||||
|  |   linkifiedText | ||||||
|  |   state | ||||||
|  |   ...ChatMessageSuggestedReplies_message | ||||||
|  |   ...ChatMessageFeedbackButtons_message | ||||||
|  |   ...ChatMessageOverflowButton_message | ||||||
|  |   ...chatHelpers_isHumanMessage | ||||||
|  |   ...chatHelpers_isBotMessage | ||||||
|  |   ...chatHelpers_isChatBreak | ||||||
|  |   ...chatHelpers_useTimeoutLevel | ||||||
|  |   ...MarkdownLinkInner_message | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment MarkdownLinkInner_message on Message { | ||||||
|  |   messageId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment MessageFeedbackOtherModal_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment MessageFeedbackReasonModal_message on Message { | ||||||
|  |   id | ||||||
|  |   messageId | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_isBotMessage on Message { | ||||||
|  |   ...chatHelpers_isHumanMessage | ||||||
|  |   ...chatHelpers_isChatBreak | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_isChatBreak on Message { | ||||||
|  |   author | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_isHumanMessage on Message { | ||||||
|  |   author | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment chatHelpers_useTimeoutLevel on Message { | ||||||
|  |   id | ||||||
|  |   state | ||||||
|  |   text | ||||||
|  |   messageId | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								poe_graphql/MessageDeletedSubscription.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								poe_graphql/MessageDeletedSubscription.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | subscription MessageDeletedSubscription($chatId: BigInt!) { | ||||||
|  |     messageDeleted(chatId: $chatId) { | ||||||
|  |         id | ||||||
|  |         messageId | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								poe_graphql/MessageFragment.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								poe_graphql/MessageFragment.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | fragment MessageFragment on Message { | ||||||
|  |     id | ||||||
|  |     __typename | ||||||
|  |     messageId | ||||||
|  |     text | ||||||
|  |     linkifiedText | ||||||
|  |     authorNickname | ||||||
|  |     state | ||||||
|  |     vote | ||||||
|  |     voteReason | ||||||
|  |     creationTime | ||||||
|  |     suggestedReplies | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								poe_graphql/MessageRemoveVoteMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								poe_graphql/MessageRemoveVoteMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | mutation MessageRemoveVoteMutation($messageId: BigInt!) { | ||||||
|  | 	messageRemoveVote(messageId: $messageId) { | ||||||
|  | 		message { | ||||||
|  | 			...MessageFragment | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								poe_graphql/MessageSetVoteMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								poe_graphql/MessageSetVoteMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | mutation MessageSetVoteMutation($messageId: BigInt!, $voteType: VoteType!, $reason: String) { | ||||||
|  | 	messageSetVote(messageId: $messageId, voteType: $voteType, reason: $reason) { | ||||||
|  | 		message { | ||||||
|  | 			...MessageFragment | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								poe_graphql/SendVerificationCodeForLoginMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								poe_graphql/SendVerificationCodeForLoginMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | mutation SendVerificationCodeForLoginMutation( | ||||||
|  |     $emailAddress: String | ||||||
|  |     $phoneNumber: String | ||||||
|  | ) { | ||||||
|  |     sendVerificationCode( | ||||||
|  |         verificationReason: login | ||||||
|  |         emailAddress: $emailAddress | ||||||
|  |         phoneNumber: $phoneNumber | ||||||
|  |     ) { | ||||||
|  |         status | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								poe_graphql/ShareMessagesMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								poe_graphql/ShareMessagesMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | mutation ShareMessagesMutation( | ||||||
|  |     $chatId: BigInt! | ||||||
|  |     $messageIds: [BigInt!]! | ||||||
|  |     $comment: String | ||||||
|  | ) { | ||||||
|  |     messagesShare(chatId: $chatId, messageIds: $messageIds, comment: $comment) { | ||||||
|  |         shareCode | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								poe_graphql/SignupWithVerificationCodeMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								poe_graphql/SignupWithVerificationCodeMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | mutation SignupWithVerificationCodeMutation( | ||||||
|  |     $verificationCode: String! | ||||||
|  |     $emailAddress: String | ||||||
|  |     $phoneNumber: String | ||||||
|  | ) { | ||||||
|  |     signupWithVerificationCode( | ||||||
|  |         verificationCode: $verificationCode | ||||||
|  |         emailAddress: $emailAddress | ||||||
|  |         phoneNumber: $phoneNumber | ||||||
|  |     ) { | ||||||
|  |         status | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								poe_graphql/StaleChatUpdateMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								poe_graphql/StaleChatUpdateMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | mutation StaleChatUpdateMutation($chatId: BigInt!) { | ||||||
|  |     staleChatUpdate(chatId: $chatId) { | ||||||
|  |         message { | ||||||
|  |             ...MessageFragment | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								poe_graphql/SubscriptionsMutation.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								poe_graphql/SubscriptionsMutation.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | mutation subscriptionsMutation( | ||||||
|  |   $subscriptions: [AutoSubscriptionQuery!]! | ||||||
|  | ) { | ||||||
|  |   autoSubscribe(subscriptions: $subscriptions) { | ||||||
|  |     viewer { | ||||||
|  |       id | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								poe_graphql/SummarizePlainPostQuery.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								poe_graphql/SummarizePlainPostQuery.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | query SummarizePlainPostQuery($comment: String!) { | ||||||
|  |     summarizePlainPost(comment: $comment) | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								poe_graphql/SummarizeQuotePostQuery.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								poe_graphql/SummarizeQuotePostQuery.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | query SummarizeQuotePostQuery($comment: String, $quotedPostId: BigInt!) { | ||||||
|  |     summarizeQuotePost(comment: $comment, quotedPostId: $quotedPostId) | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								poe_graphql/SummarizeSharePostQuery.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								poe_graphql/SummarizeSharePostQuery.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | query SummarizeSharePostQuery($comment: String!, $chatId: BigInt!, $messageIds: [BigInt!]!) { | ||||||
|  |     summarizeSharePost(comment: $comment, chatId: $chatId, messageIds: $messageIds) | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								poe_graphql/UserSnippetFragment.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								poe_graphql/UserSnippetFragment.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | fragment UserSnippetFragment on PoeUser { | ||||||
|  |     id | ||||||
|  |     uid | ||||||
|  |     bio | ||||||
|  |     handle | ||||||
|  |     fullName | ||||||
|  |     viewerIsFollowing | ||||||
|  |     isPoeOnlyUser | ||||||
|  |     profilePhotoURLTiny: profilePhotoUrl(size: tiny) | ||||||
|  |     profilePhotoURLSmall: profilePhotoUrl(size: small) | ||||||
|  |     profilePhotoURLMedium: profilePhotoUrl(size: medium) | ||||||
|  |     profilePhotoURLLarge: profilePhotoUrl(size: large) | ||||||
|  |     isFollowable | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								poe_graphql/ViewerInfoQuery.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								poe_graphql/ViewerInfoQuery.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | query ViewerInfoQuery { | ||||||
|  |     viewer { | ||||||
|  |         id | ||||||
|  |         uid | ||||||
|  |         ...ViewerStateFragment | ||||||
|  |         ...BioFragment | ||||||
|  |         ...HandleFragment | ||||||
|  |         hasCompletedMultiplayerNux | ||||||
|  |         poeUser { | ||||||
|  |             id | ||||||
|  |             ...UserSnippetFragment | ||||||
|  |         } | ||||||
|  |         messageLimit{ | ||||||
|  |             canSend | ||||||
|  |             numMessagesRemaining | ||||||
|  |             resetTime | ||||||
|  |             shouldShowReminder | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								poe_graphql/ViewerStateFragment.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								poe_graphql/ViewerStateFragment.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | fragment ViewerStateFragment on Viewer { | ||||||
|  |     id | ||||||
|  |     __typename | ||||||
|  |     iosMinSupportedVersion: integerGate(gateName: "poe_ios_min_supported_version") | ||||||
|  |     iosMinEncouragedVersion: integerGate( | ||||||
|  |         gateName: "poe_ios_min_encouraged_version" | ||||||
|  |     ) | ||||||
|  |     macosMinSupportedVersion: integerGate( | ||||||
|  |         gateName: "poe_macos_min_supported_version" | ||||||
|  |     ) | ||||||
|  |     macosMinEncouragedVersion: integerGate( | ||||||
|  |         gateName: "poe_macos_min_encouraged_version" | ||||||
|  |     ) | ||||||
|  |     showPoeDebugPanel: booleanGate(gateName: "poe_show_debug_panel") | ||||||
|  |     enableCommunityFeed: booleanGate(gateName: "enable_poe_shares_feed") | ||||||
|  |     linkifyText: booleanGate(gateName: "poe_linkify_response") | ||||||
|  |     enableSuggestedReplies: booleanGate(gateName: "poe_suggested_replies") | ||||||
|  |     removeInviteLimit: booleanGate(gateName: "poe_remove_invite_limit") | ||||||
|  |     enableInAppPurchases: booleanGate(gateName: "poe_enable_in_app_purchases") | ||||||
|  |     availableBots { | ||||||
|  |         nickname | ||||||
|  |         displayName | ||||||
|  |         profilePicture | ||||||
|  |         isDown | ||||||
|  |         disclaimer | ||||||
|  |         subtitle | ||||||
|  |         poweredBy | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										43
									
								
								poe_graphql/ViewerStateUpdatedSubscription.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								poe_graphql/ViewerStateUpdatedSubscription.graphql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | subscription viewerStateUpdated { | ||||||
|  |   viewerStateUpdated { | ||||||
|  |     id | ||||||
|  |     ...ChatPageBotSwitcher_viewer | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment BotHeader_bot on Bot { | ||||||
|  |   displayName | ||||||
|  |   messageLimit { | ||||||
|  |     dailyLimit | ||||||
|  |   } | ||||||
|  |   ...BotImage_bot | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment BotImage_bot on Bot { | ||||||
|  |   image { | ||||||
|  |     __typename | ||||||
|  |     ... on LocalBotImage { | ||||||
|  |       localName | ||||||
|  |     } | ||||||
|  |     ... on UrlBotImage { | ||||||
|  |       url | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   displayName | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment BotLink_bot on Bot { | ||||||
|  |   displayName | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ChatPageBotSwitcher_viewer on Viewer { | ||||||
|  |   availableBots { | ||||||
|  |     id | ||||||
|  |     messageLimit { | ||||||
|  |       dailyLimit | ||||||
|  |     } | ||||||
|  |     ...BotLink_bot | ||||||
|  |     ...BotHeader_bot | ||||||
|  |   } | ||||||
|  |   allowUserCreatedBots: booleanGate(gateName: "enable_user_created_bots") | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user