Merge pull request #42 from matrixgpt/rich-text

Add Markdown support for ChatGPT
This commit is contained in:
bertybuttface 2023-01-08 20:50:58 +00:00 committed by GitHub
commit 7a4941a679
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 10 deletions

View File

@ -17,6 +17,7 @@
"dependencies": { "dependencies": {
"chatgpt": "^3.3.10", "chatgpt": "^3.3.10",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",
"markdown-it": "^13.0.1",
"matrix-bot-sdk": "^0.6.3", "matrix-bot-sdk": "^0.6.3",
"puppeteer": "^19.4.1", "puppeteer": "^19.4.1",
"typescript": "^4.9.4", "typescript": "^4.9.4",

View File

@ -44,7 +44,7 @@ export default class CommandHandler {
if (MATRIX_BLACKLIST.split(" ").find(b => event.sender.endsWith(b))) return; // Ignore if on blacklist if set if (MATRIX_BLACKLIST.split(" ").find(b => event.sender.endsWith(b))) return; // Ignore if on blacklist if set
} }
if ((MATRIX_WHITELIST !== undefined) && MATRIX_WHITELIST){ if ((MATRIX_WHITELIST !== undefined) && MATRIX_WHITELIST){
if (!MATRIX_WHITELIST.split(" ").find(w => event.sender.endsWith(w))) return; // Ignore if not on whitelist if set if (!MATRIX_WHITELIST.split(" ").find(w => event.sender.endsWith(w))) return; // Ignore if not on whitelist if set
} }
const rootEventId: string = (relatesTo !== undefined && relatesTo.event_id !== undefined) ? relatesTo.event_id : event.event_id; const rootEventId: string = (relatesTo !== undefined && relatesTo.event_id !== undefined) ? relatesTo.event_id : event.event_id;
const storedValue: string = await this.client.storageProvider.readValue('gpt-' + rootEventId) const storedValue: string = await this.client.storageProvider.readValue('gpt-' + rootEventId)
@ -88,7 +88,7 @@ export default class CommandHandler {
result = await this.chatGPT.sendMessage(question, {timeoutMs: CHATGPT_TIMEOUT}); result = await this.chatGPT.sendMessage(question, {timeoutMs: CHATGPT_TIMEOUT});
} }
await Promise.all([this.client.setTyping(roomId, false, 500), sendThreadReply(this.client, `${result.response}`, roomId, rootEventId)]); await Promise.all([this.client.setTyping(roomId, false, 500), sendThreadReply(this.client, roomId, rootEventId,`${result.response}`, true)]);
await this.client.storageProvider.storeValue('gpt-' + rootEventId, JSON.stringify({ await this.client.storageProvider.storeValue('gpt-' + rootEventId, JSON.stringify({
conversationId: result.conversationId, conversationId: result.conversationId,

View File

@ -1,6 +1,9 @@
import Markdown from 'markdown-it';
import { MatrixClient } from "matrix-bot-sdk"; import { MatrixClient } from "matrix-bot-sdk";
import { MessageEvent } from "./interfaces.js"; import { MessageEvent } from "./interfaces.js";
const md = Markdown();
export function parseMatrixUsernamePretty(matrix_username: string): string { export function parseMatrixUsernamePretty(matrix_username: string): string {
if (matrix_username.includes(":") === false || matrix_username.includes("@") === false) { if (matrix_username.includes(":") === false || matrix_username.includes("@") === false) {
return matrix_username; return matrix_username;
@ -19,23 +22,49 @@ export async function sendError(client: MatrixClient, text: string, roomId: stri
/** /**
* Send a thread reply. * Send a thread reply.
* @param client Matrix client * @param {MatrixClient} client Matrix client
* @param param1 Object containing text, root_event_id and roomId. root_event_id is the event_id * @param {string} roomId the room ID the event being replied to resides in
* of the message the thread "replying" to. * @param {string} rootEventId the root event of the thread
* @param {string} text the plain text to reply with
* @param {boolean} rich should the plain text be rendered to html using markdown?
*/ */
export async function sendThreadReply(client: MatrixClient, text: string, roomId: string, root_event_id: string): Promise<void> { export async function sendThreadReply(client: MatrixClient, roomId: string, rootEventId: string, text: string, rich:boolean = false): Promise<void> {
const content = {
const contentCommon = {
body: text, body: text,
msgtype: "m.text", msgtype: "m.text",
"org.matrix.msc1767.text": text,
"m.relates_to": { "m.relates_to": {
event_id: root_event_id, event_id: rootEventId,
is_falling_back: true, is_falling_back: true,
"m.in_reply_to": { "m.in_reply_to": {
"event_id": root_event_id "event_id": rootEventId
}, },
rel_type: "m.thread" rel_type: "m.thread"
} }
} }
const contentTextOnly = {
"org.matrix.msc1767.text": text,
}
const renderedText = md.render(text)
const contentRichOnly = {
format: "org.matrix.custom.html",
formatted_body: renderedText,
"org.matrix.msc1767.message": [
{
"body": text,
"mimetype": "text/plain"
},
{
"body": renderedText,
"mimetype": "text/html"
}
]
}
const content = rich ? { ...contentCommon, ...contentRichOnly } : { ...contentCommon, ...contentTextOnly };
await client.sendEvent(roomId, "m.room.message", content); await client.sendEvent(roomId, "m.room.message", content);
} }