From ae1e4644496ddea026e62e0ed5fefbdabba88609 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 29 Jun 2023 22:09:58 +0800 Subject: [PATCH] add shorten --- README.md | 1 + example/shorten.ts | 29 +++++++++++++++++++++++++++++ src/command.ts | 13 +++++++++++++ src/midjourne.api.ts | 4 ++++ src/midjourney.ts | 12 ++++++++++++ src/utls/index.ts | 11 +++++++++++ src/ws.message.ts | 28 +++++++++++++++++++++++----- 7 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 example/shorten.ts diff --git a/README.md b/README.md index 88dc5bd..4b8d60b 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ npx tsx example/imagine-ws.ts - [x] `/info` - [x] `/fast ` and `/relax ` - [x] `/describe` +- [x] [`/shorten`](https://github.com/erictik/midjourney-client/blob/main/example/shorten.ts) - [x] `/settings` `reset` - [x] verify human - [x] [proxy](https://github.com/erictik/midjourney-discord/blob/main/examples/proxy.ts) diff --git a/example/shorten.ts b/example/shorten.ts new file mode 100644 index 0000000..64acd5a --- /dev/null +++ b/example/shorten.ts @@ -0,0 +1,29 @@ +import "dotenv/config"; +import { Midjourney } from "../src"; +/** + * + * a simple example of using the shorten api + * ``` + * npx tsx example/shorten.ts + * ``` + */ +async function main() { + const client = new Midjourney({ + ServerId: process.env.SERVER_ID, + ChannelId: process.env.CHANNEL_ID, + SalaiToken: process.env.SALAI_TOKEN, + Debug: true, + Ws: true, + }); + await client.Connect(); + const Shorten = await client.Shorten( + "Peeking out from the bushes, masterpiece, octane rendering, focus, realistic photography, colorful background, detailed, intricate details, rich colors, realistic style" + ); + console.log(Shorten); + client.Close(); +} +main().catch((err) => { + console.log("finished"); + console.error(err); + process.exit(1); +}); diff --git a/src/command.ts b/src/command.ts index ed34d5a..65bf51b 100644 --- a/src/command.ts +++ b/src/command.ts @@ -2,6 +2,7 @@ import { DiscordImage, MJConfig } from "./interfaces"; type CommandName = | "imagine" + | "shorten" | "describe" | "info" | "fast" @@ -15,6 +16,7 @@ export class Command { info: undefined, fast: undefined, relax: undefined, + shorten: undefined, settings: undefined, }; @@ -63,6 +65,17 @@ export class Command { ]); return this.data2Paylod(data, nonce); } + + async shortenPayload(prompt: string, nonce?: string) { + const data = await this.commandData("shorten", [ + { + type: 3, + name: "prompt", + value: prompt, + }, + ]); + return this.data2Paylod(data, nonce); + } async infoPayload(nonce?: string) { const data = await this.commandData("info"); return this.data2Paylod(data, nonce); diff --git a/src/midjourne.api.ts b/src/midjourne.api.ts index 13e77ca..f4ca88a 100644 --- a/src/midjourne.api.ts +++ b/src/midjourne.api.ts @@ -55,6 +55,10 @@ export class MidjourneyApi extends Command { const payload = await this.imaginePayload(prompt, nonce); return this.safeIteractions(payload); } + async ShortenApi(prompt: string, nonce: string = nextNonce()) { + const payload = await this.shortenPayload(prompt, nonce); + return this.safeIteractions(payload); + } async VariationApi({ index, msgId, diff --git a/src/midjourney.ts b/src/midjourney.ts index 6931670..3139a24 100644 --- a/src/midjourney.ts +++ b/src/midjourney.ts @@ -135,6 +135,18 @@ export class Midjourney extends MidjourneyMessage { return null; } + async Shorten(prompt: string) { + const nonce = nextNonce(); + const httpStatus = await this.MJApi.ShortenApi(prompt, nonce); + if (httpStatus !== 204) { + throw new Error(`ShortenApi failed with status ${httpStatus}`); + } + if (this.wsClient) { + return this.wsClient.waitShorten(nonce); + } + return null; + } + async Variation({ index, msgId, diff --git a/src/utls/index.ts b/src/utls/index.ts index 7c892e2..e2613c7 100644 --- a/src/utls/index.ts +++ b/src/utls/index.ts @@ -15,6 +15,17 @@ const snowflake = new Snowyflake({ export const nextNonce = (): string => snowflake.nextId().toString(); +export const formatPrompts = (prompts: string) => { + const regex = /(\d️⃣ .+)/g; + const matches = prompts.match(regex); + if (matches) { + const shortenedPrompts = matches.map((match) => match.trim()); + return shortenedPrompts; + } else { + console.log("No matches found."); + } +}; + export const formatOptions = (components: any) => { var data: MJOptions[] = []; for (var i = 0; i < components.length; i++) { diff --git a/src/ws.message.ts b/src/ws.message.ts index c12da90..234ac0c 100644 --- a/src/ws.message.ts +++ b/src/ws.message.ts @@ -10,7 +10,7 @@ import { } from "./interfaces"; import { MidjourneyApi } from "./midjourne.api"; -import { formatOptions } from "./utls"; +import { formatOptions, formatPrompts } from "./utls"; import { VerifyHuman } from "./verify.human"; import WebSocket from "isomorphic-ws"; export class WsMessage { @@ -155,11 +155,18 @@ export class WsMessage { this.emit("settings", message); return; case "describe": - this.emitDescribe(id, { + this.emitMJ(id, { descriptions: embeds?.[0]?.description.split("\n\n"), options: formatOptions(components), }); break; + case "shorten": + this.emitMJ(id, { + description: embeds?.[0]?.description, + prompts: formatPrompts(embeds?.[0]?.description as string), + options: formatOptions(components), + }); + break; case "info": this.emit("info", embeds?.[0]?.description); return; @@ -346,7 +353,7 @@ export class WsMessage { private emitImage(type: string, message: WsEventMsg) { this.emit(type, message); } - private emitDescribe(id: string, data: any) { + private emitMJ(id: string, data: any) { const event = this.getEventById(id); if (!event) return; this.emit(event.nonce, data); @@ -383,7 +390,7 @@ export class WsMessage { }; this.event.push({ event: "settings", callback: once }); } - onceDescribe(nonce: string, callback: (data: any) => void) { + onceMJ(nonce: string, callback: (data: any) => void) { const once = (message: any) => { this.remove(nonce, once); this.removeWaitMjEvent(nonce); @@ -433,7 +440,18 @@ export class WsMessage { options: MJOptions[]; descriptions: string[]; } | null>((resolve) => { - this.onceDescribe(nonce, (message) => { + this.onceMJ(nonce, (message) => { + resolve(message); + }); + }); + } + async waitShorten(nonce: string) { + return new Promise<{ + options: MJOptions[]; + prompts: string[]; + description: string; + } | null>((resolve) => { + this.onceMJ(nonce, (message) => { resolve(message); }); });