Skip to content

Commit

Permalink
feat: 默认使用user-wss模式; redis value序列化为json; ...
Browse files Browse the repository at this point in the history
  • Loading branch information
zhukai committed Jun 8, 2023
1 parent 537cc22 commit de53ac5
Show file tree
Hide file tree
Showing 30 changed files with 221 additions and 136 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ config/application.yml

.git
.gitignore
build-*.sh
docker
docs
README.md
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

代理 MidJourney 的discord频道,实现api形式调用AI绘图

[![GitHub release](https://img.shields.io/static/v1?label=release&message=v2.1.6&color=blue)](https://www.github.com/novicezk/midjourney-proxy)
[![GitHub release](https://img.shields.io/static/v1?label=release&message=v2.2&color=blue)](https://www.github.com/novicezk/midjourney-proxy)
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)

## 现有功能
Expand All @@ -14,7 +14,7 @@
- [x] 支持中文 prompt 翻译,需配置百度翻译或 gpt
- [x] prompt 敏感词判断,支持覆盖调整
- [x] 任务队列,默认队列10,并发3。可参考 [MidJourney订阅级别](https://docs.midjourney.com/docs/plans) 调整mj.queue
- [x] 可选 user-token 连接 wss,以获取错误信息和完整功能
- [x] user-token 连接 wss,可以获取错误信息和完整功能
- [x] 支持 discord域名(server、cdn、wss)反代,配置 mj.ng-discord

## 后续计划
Expand All @@ -28,12 +28,12 @@
1. 科学上网
2. docker环境
3. 注册 MidJourney,创建自己的频道,参考 https://docs.midjourney.com/docs/quick-start
4. 添加自己的机器人: [流程说明](./docs/discord-bot.md)
5. user-wss方式,可不添加自己的机器人,但仍需参考流程的第4、5步,获取用户Token、服务器ID、频道ID
4. 获取用户Token、服务器ID、频道ID:[获取方式](./docs/discord-params.md)

## 风险须知
1. 作图频繁等行为,触发midjourney验证码后,需尽快人工验证
2. user-wss方式可以获取midjourney的错误信息、支持图片变换进度,但可能会增加账号风险
2. 默认使用user-wss方式,可以获取midjourney的错误信息、图片变换进度等,但可能会增加账号风险
3. 支持设置mj.discord.user-wss为false,使用bot-token连接wss,需添加自定义机器人:[流程说明](./docs/discord-bot.md)

## 快速启动
1. /xxx/xxx/config目录下创建 application.yml(mj配置项)、banned-words.txt(可选,覆盖默认的敏感词文件);参考src/main/resources下的文件
Expand All @@ -43,7 +43,7 @@ docker run -d --name midjourney-proxy \
-p 8080:8080 \
-v /xxx/xxx/config:/home/spring/config \
--restart=always \
novicezk/midjourney-proxy:2.1.6
novicezk/midjourney-proxy:2.2
```
3. 访问 `http://ip:port/mj` 查看API文档

Expand All @@ -54,9 +54,8 @@ docker run -d --name midjourney-proxy \
-e mj.discord.guild-id=xxx \
-e mj.discord.channel-id=xxx \
-e mj.discord.user-token=xxx \
-e mj.discord.bot-token=xxx \
--restart=always \
novicezk/midjourney-proxy:2.1.6
novicezk/midjourney-proxy:2.2
```

## 注意事项
Expand All @@ -70,7 +69,7 @@ docker run -d --name midjourney-proxy \
- mj.discord.guild-id:discord服务器ID
- mj.discord.channel-id:discord频道ID
- mj.discord.user-token:discord用户Token
- mj.discord.user-wss:是否使用user-token连接wss,默认false(使用bot-token)
- mj.discord.user-wss:是否使用user-token连接wss,默认true
- mj.discord.user-agent:调用discord接口、连接wss时的user-agent,默认使用作者的,建议从浏览器network复制替换掉
- mj.discord.bot-token:自定义机器人Token,user-wss=false时必填
- 更多配置查看 [Wiki / 配置项](https://github.com/novicezk/midjourney-proxy/wiki/%E9%85%8D%E7%BD%AE%E9%A1%B9)
Expand Down
14 changes: 2 additions & 12 deletions docs/discord-bot.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,8 @@ https://discord.com/developers/applications

勾上这两个选项,点击 `Save Changes`

### 4. 获取用户Token
进入频道,打开network随便发个消息,这里的 authorization 即用户Token,后续设置到 `mj.discord.user-token`

![User Token](img_8.png)

### 5. 获取服务器ID、频道ID

频道的url里取出 服务器ID、频道ID,后续设置到配置项
![Guild Channel ID](img_9.png)

### 6. 检查机器人
在频道中确认是否存在mj机器人和新创建的机器人,注意mj机器人名称为"Midjourney Bot",不一致时需要改启动参数 `mj.discord.mj-bot-name`
### 4. 检查机器人
在频道中确认是否存在mj机器人和新创建的机器人

![Check Bot](img_10.png)

Expand Down
11 changes: 11 additions & 0 deletions docs/discord-params.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## 获取discord配置参数

### 1. 获取用户Token
进入频道,打开network,刷新页面,找到 `messages` 的请求,这里的 authorization 即用户Token,后续设置到 `mj.discord.user-token`

![User Token](img_8.png)

### 2. 获取服务器ID、频道ID

频道的url里取出 服务器ID、频道ID,后续设置到配置项
![Guild Channel ID](img_9.png)
Binary file modified docs/img_8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<groupId>com.github.novicezk</groupId>
<artifactId>midjourney-proxy</artifactId>
<version>2.1.6</version>
<version>2.2</version>

<properties>
<hutool.version>5.8.18</hutool.version>
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/com/github/novicezk/midjourney/Constants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.github.novicezk.midjourney;

import lombok.experimental.UtilityClass;

@UtilityClass
public final class Constants {
// 任务扩展属性 start
public static final String TASK_PROPERTY_NOTIFY_HOOK = "notifyHook";
public static final String TASK_PROPERTY_FINAL_PROMPT = "finalPrompt";
public static final String TASK_PROPERTY_RELATED_TASK_ID = "relatedTaskId";
public static final String TASK_PROPERTY_MESSAGE_ID = "messageId";
public static final String TASK_PROPERTY_PROGRESS_MESSAGE_ID = "progressMessageId";
public static final String TASK_PROPERTY_FLAGS = "flags";
public static final String TASK_PROPERTY_MESSAGE_HASH = "messageHash";
// 任务扩展属性 end
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ public static class DiscordConfig {
*/
private String userToken;
/**
* 是否使用user_token连接wss,默认false(使用bot_token).
* 是否使用user_token连接wss,默认启用.
*/
private boolean userWss = false;
private boolean userWss = true;
/**
* 调用discord接口、连接wss时的user-agent.
*/
Expand All @@ -74,10 +74,6 @@ public static class DiscordConfig {
* 你的机器人token.
*/
private String botToken;
/**
* Midjourney机器人的名称.
*/
private String mjBotName = "Midjourney Bot";
}

@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.RandomUtil;
import com.github.novicezk.midjourney.Constants;
import com.github.novicezk.midjourney.ProxyProperties;
import com.github.novicezk.midjourney.ReturnCode;
import com.github.novicezk.midjourney.dto.BaseSubmitDTO;
Expand Down Expand Up @@ -81,7 +82,7 @@ public SubmitResultVO imagine(@RequestBody SubmitImagineDTO imagineDTO) {
}
}
task.setPromptEn(promptEn);
task.setFinalPrompt("[" + task.getId() + "] " + promptEn);
task.setProperty(Constants.TASK_PROPERTY_FINAL_PROMPT, "[" + task.getId() + "] " + promptEn);
task.setDescription("/imagine " + imagineDTO.getPrompt());
return this.taskService.submitImagine(task, dataUrl);
}
Expand Down Expand Up @@ -138,13 +139,17 @@ public SubmitResultVO change(@RequestBody SubmitChangeDTO changeDTO) {
task.setAction(changeDTO.getAction());
task.setPrompt(targetTask.getPrompt());
task.setPromptEn(targetTask.getPromptEn());
task.setFinalPrompt(targetTask.getFinalPrompt());
task.setRelatedTaskId(ConvertUtils.findTaskIdByFinalPrompt(targetTask.getFinalPrompt()));
task.setProperty(Constants.TASK_PROPERTY_FINAL_PROMPT, targetTask.getProperty(Constants.TASK_PROPERTY_FINAL_PROMPT));
String relatedTaskId = ConvertUtils.findTaskIdByFinalPrompt(targetTask.getPropertyGeneric(Constants.TASK_PROPERTY_FINAL_PROMPT));
task.setProperty(Constants.TASK_PROPERTY_RELATED_TASK_ID, relatedTaskId);
task.setDescription(description);
int messageFlags = targetTask.getPropertyGeneric(Constants.TASK_PROPERTY_FLAGS);
String messageId = targetTask.getPropertyGeneric(Constants.TASK_PROPERTY_MESSAGE_ID);
String messageHash = targetTask.getPropertyGeneric(Constants.TASK_PROPERTY_MESSAGE_HASH);
if (TaskAction.UPSCALE.equals(changeDTO.getAction())) {
return this.taskService.submitUpscale(task, targetTask.getMessageId(), targetTask.getMessageHash(), changeDTO.getIndex());
return this.taskService.submitUpscale(task, messageId, messageHash, changeDTO.getIndex(), messageFlags);
} else if (TaskAction.VARIATION.equals(changeDTO.getAction())) {
return this.taskService.submitVariation(task, targetTask.getMessageId(), targetTask.getMessageHash(), changeDTO.getIndex());
return this.taskService.submitVariation(task, messageId, messageHash, changeDTO.getIndex(), messageFlags);
} else {
return SubmitResultVO.fail(ReturnCode.VALIDATION_ERROR, "不支持的操作: " + changeDTO.getAction());
}
Expand Down Expand Up @@ -198,7 +203,8 @@ private Task newTask(BaseSubmitDTO base) {
task.setId(RandomUtil.randomNumbers(16));
task.setSubmitTime(System.currentTimeMillis());
task.setState(base.getState());
task.setNotifyHook(CharSequenceUtil.isBlank(base.getNotifyHook()) ? this.properties.getNotifyHook() : base.getNotifyHook());
String notifyHook = CharSequenceUtil.isBlank(base.getNotifyHook()) ? this.properties.getNotifyHook() : base.getNotifyHook();
task.setProperty(Constants.TASK_PROPERTY_NOTIFY_HOOK, notifyHook);
return task;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ public interface DiscordService {

Message<Void> imagine(String prompt);

Message<Void> upscale(String messageId, int index, String messageHash);
Message<Void> upscale(String messageId, int index, String messageHash, int messageFlags);

Message<Void> variation(String messageId, int index, String messageHash);
Message<Void> variation(String messageId, int index, String messageHash, int messageFlags);

Message<Void> reroll(String messageId, String messageHash);
Message<Void> reroll(String messageId, String messageHash, int messageFlags);

Message<Void> describe(String finalFileName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,31 +82,34 @@ public Message<Void> imagine(String prompt) {
}

@Override
public Message<Void> upscale(String messageId, int index, String messageHash) {
public Message<Void> upscale(String messageId, int index, String messageHash, int messageFlags) {
String paramsStr = this.upscaleParamsJson.replace("$guild_id", this.discordGuildId)
.replace("$channel_id", this.discordChannelId)
.replace("$message_id", messageId)
.replace("$index", String.valueOf(index))
.replace("$message_hash", messageHash);
paramsStr = new JSONObject(paramsStr).put("message_flags", messageFlags).toString();
return postJsonAndCheckStatus(paramsStr);
}

@Override
public Message<Void> variation(String messageId, int index, String messageHash) {
public Message<Void> variation(String messageId, int index, String messageHash, int messageFlags) {
String paramsStr = this.variationParamsJson.replace("$guild_id", this.discordGuildId)
.replace("$channel_id", this.discordChannelId)
.replace("$message_id", messageId)
.replace("$index", String.valueOf(index))
.replace("$message_hash", messageHash);
paramsStr = new JSONObject(paramsStr).put("message_flags", messageFlags).toString();
return postJsonAndCheckStatus(paramsStr);
}

@Override
public Message<Void> reroll(String messageId, String messageHash) {
public Message<Void> reroll(String messageId, String messageHash, int messageFlags) {
String paramsStr = this.rerollParamsJson.replace("$guild_id", this.discordGuildId)
.replace("$channel_id", this.discordChannelId)
.replace("$message_id", messageId)
.replace("$message_hash", messageHash);
paramsStr = new JSONObject(paramsStr).put("message_flags", messageFlags).toString();
return postJsonAndCheckStatus(paramsStr);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import cn.hutool.core.text.CharSequenceUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.novicezk.midjourney.Constants;
import com.github.novicezk.midjourney.support.Task;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -21,7 +22,7 @@ public class NotifyServiceImpl implements NotifyService {

@Override
public void notifyTaskChange(Task task) {
String notifyHook = task.getNotifyHook();
String notifyHook = task.getPropertyGeneric(Constants.TASK_PROPERTY_NOTIFY_HOOK);
if (CharSequenceUtil.isBlank(notifyHook)) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ public interface TaskService {

SubmitResultVO submitImagine(Task task, DataUrl dataUrl);

SubmitResultVO submitUpscale(Task task, String targetMessageId, String targetMessageHash, int index);
SubmitResultVO submitUpscale(Task task, String targetMessageId, String targetMessageHash, int index, int messageFlags);

SubmitResultVO submitVariation(Task task, String targetMessageId, String targetMessageHash, int index);
SubmitResultVO submitVariation(Task task, String targetMessageId, String targetMessageHash, int index, int messageFlags);

SubmitResultVO submitDescribe(Task task, DataUrl dataUrl);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.novicezk.midjourney.service;

import com.github.novicezk.midjourney.Constants;
import com.github.novicezk.midjourney.ReturnCode;
import com.github.novicezk.midjourney.result.Message;
import com.github.novicezk.midjourney.result.SubmitResultVO;
Expand Down Expand Up @@ -38,22 +39,22 @@ public SubmitResultVO submitImagine(Task task, DataUrl dataUrl) {
}
task.setPrompt(sendImageResult.getResult() + " " + task.getPrompt());
task.setPromptEn(sendImageResult.getResult() + " " + task.getPromptEn());
task.setFinalPrompt("[" + task.getId() + "] " + task.getPromptEn());
task.setProperty(Constants.TASK_PROPERTY_FINAL_PROMPT, "[" + task.getId() + "] " + task.getPromptEn());
task.setDescription("/imagine " + task.getPrompt());
this.taskStoreService.save(task);
}
return this.discordService.imagine(task.getFinalPrompt());
return this.discordService.imagine(task.getPropertyGeneric(Constants.TASK_PROPERTY_FINAL_PROMPT));
});
}

@Override
public SubmitResultVO submitUpscale(Task task, String targetMessageId, String targetMessageHash, int index) {
return this.taskQueueHelper.submitTask(task, () -> this.discordService.upscale(targetMessageId, index, targetMessageHash));
public SubmitResultVO submitUpscale(Task task, String targetMessageId, String targetMessageHash, int index, int messageFlags) {
return this.taskQueueHelper.submitTask(task, () -> this.discordService.upscale(targetMessageId, index, targetMessageHash, messageFlags));
}

@Override
public SubmitResultVO submitVariation(Task task, String targetMessageId, String targetMessageHash, int index) {
return this.taskQueueHelper.submitTask(task, () -> this.discordService.variation(targetMessageId, index, targetMessageHash));
public SubmitResultVO submitVariation(Task task, String targetMessageId, String targetMessageHash, int index, int messageFlags) {
return this.taskQueueHelper.submitTask(task, () -> this.discordService.variation(targetMessageId, index, targetMessageHash, messageFlags));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import java.util.stream.Collectors;

public class RedisTaskStoreServiceImpl implements TaskStoreService {
private static final String KEY_PREFIX = "mj-task::";
private static final String KEY_PREFIX = "mj-task-store::";

private final Duration timeout;
private final RedisTemplate<String, Task> redisTemplate;
Expand Down
Loading

0 comments on commit de53ac5

Please sign in to comment.