【代码评审】AI:移除老版本的 MJ 接入
This commit is contained in:
parent
75a91a2c46
commit
88142ed74c
|
@ -1,123 +0,0 @@
|
|||
package cn.iocoder.yudao.module.ai.service.image.midjourneyHandler;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyOperationsVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO;
|
||||
import cn.iocoder.yudao.module.ai.dal.mysql.image.AiImageMapper;
|
||||
import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyMessage;
|
||||
import org.springframework.ai.models.midjourney.constants.MidjourneyGennerateStatusEnum;
|
||||
import org.springframework.ai.models.midjourney.webSocket.MidjourneyMessageHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* yudao message handler
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/29 14:34
|
||||
* @since 1.0
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class YuDaoMidjourneyMessageHandler implements MidjourneyMessageHandler {
|
||||
|
||||
private final AiImageMapper aiImageMapper;
|
||||
|
||||
@Override
|
||||
public void messageHandler(MidjourneyMessage midjourneyMessage) {
|
||||
log.info("yudao-midjourney-midjourney-message-handler {}", JSON.toJSONString(midjourneyMessage));
|
||||
if (midjourneyMessage.getContent() != null) {
|
||||
log.info("进度id {} 状态 {} 进度 {}",
|
||||
midjourneyMessage.getNonce(),
|
||||
midjourneyMessage.getGenerateStatus(),
|
||||
midjourneyMessage.getContent().getProgress());
|
||||
}
|
||||
//
|
||||
updateImage(midjourneyMessage);
|
||||
}
|
||||
|
||||
private void updateImage(MidjourneyMessage midjourneyMessage) {
|
||||
// Nonce 不存在不更新
|
||||
if (StrUtil.isBlank(midjourneyMessage.getNonce())) {
|
||||
return;
|
||||
}
|
||||
// 根据 Embeds 来判断是否异常
|
||||
if (CollUtil.isEmpty(midjourneyMessage.getEmbeds())) {
|
||||
successHandler(midjourneyMessage);
|
||||
} else {
|
||||
errorHandler(midjourneyMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private void errorHandler(MidjourneyMessage midjourneyMessage) {
|
||||
// image 编号
|
||||
Long nonceId = Long.valueOf(midjourneyMessage.getNonce());
|
||||
// 获取 error message
|
||||
String errorMessage = getErrorMessage(midjourneyMessage);
|
||||
aiImageMapper.updateByMjNonce(nonceId,
|
||||
new AiImageDO()
|
||||
.setErrorMessage(errorMessage)
|
||||
.setStatus(AiImageStatusEnum.FAIL.getStatus())
|
||||
);
|
||||
}
|
||||
|
||||
private String getErrorMessage(MidjourneyMessage midjourneyMessage) {
|
||||
StringBuilder errorMessage = new StringBuilder();
|
||||
for (MidjourneyMessage.Embed embed : midjourneyMessage.getEmbeds()) {
|
||||
errorMessage.append(embed.getDescription());
|
||||
}
|
||||
return errorMessage.toString();
|
||||
}
|
||||
|
||||
private void successHandler(MidjourneyMessage midjourneyMessage) {
|
||||
// 获取id
|
||||
Long nonceId = Long.valueOf(midjourneyMessage.getNonce());
|
||||
// TODO @芋艿 这个地方有问题,不能根据 nonce来更新,不返回这个信息(别人获取了 image-xxx-xx 后面一段hash,由于没有mj账号测试,暂不清楚。)
|
||||
// 获取生成 url
|
||||
String imageUrl = null;
|
||||
if (CollUtil.isNotEmpty(midjourneyMessage.getAttachments())) {
|
||||
imageUrl = midjourneyMessage.getAttachments().get(0).getUrl();
|
||||
}
|
||||
// 转换状态
|
||||
AiImageStatusEnum drawingStatusEnum = null;
|
||||
String generateStatus = midjourneyMessage.getGenerateStatus();
|
||||
if (MidjourneyGennerateStatusEnum.COMPLETED.getStatus().equals(generateStatus)) {
|
||||
drawingStatusEnum = AiImageStatusEnum.SUCCESS;
|
||||
} else if (MidjourneyGennerateStatusEnum.IN_PROGRESS.getStatus().equals(generateStatus)) {
|
||||
drawingStatusEnum = AiImageStatusEnum.IN_PROGRESS;
|
||||
}
|
||||
// else if (MidjourneyGennerateStatusEnum.WAITING.getStatus().equals(generateStatus)) {
|
||||
// drawingStatusEnum = AiImageStatusEnum.WAITING;
|
||||
// }
|
||||
// 获取 midjourneyOperations
|
||||
List<AiImageMidjourneyOperationsVO> midjourneyOperations = getMidjourneyOperationsList(midjourneyMessage);
|
||||
// 更新数据库
|
||||
aiImageMapper.updateByMjNonce(nonceId,
|
||||
new AiImageDO()
|
||||
.setStatus(drawingStatusEnum == null ? null : drawingStatusEnum.getStatus())
|
||||
// .setMjNonceId(midjourneyMessage.getId())
|
||||
// .setMjOperations(JsonUtils.toJsonString(midjourneyOperations))
|
||||
);
|
||||
}
|
||||
|
||||
private List<AiImageMidjourneyOperationsVO> getMidjourneyOperationsList(MidjourneyMessage midjourneyMessage) {
|
||||
// // 为空直接返回
|
||||
// if (CollUtil.isEmpty(midjourneyMessage.getComponents())) {
|
||||
// return Collections.emptyList();
|
||||
// }
|
||||
// // 将 component 转成 AiImageMidjourneyOperationsVO
|
||||
// return midjourneyMessage.getComponents().stream()
|
||||
// .map(componentType -> componentType.getComponents().stream()
|
||||
// .map(AiImageConvert.INSTANCE::convertAiImageMidjourneyOperationsVO)
|
||||
// .collect(Collectors.toList()))
|
||||
// .toList().stream().flatMap(List::stream).toList();
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
//package cn.iocoder.yudao.module.ai.mapper.typeHandler;
|
||||
//
|
||||
//import cn.hutool.core.util.StrUtil;
|
||||
//import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
|
||||
//import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
//import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
|
||||
//import org.apache.ibatis.type.BaseTypeHandler;
|
||||
//import org.apache.ibatis.type.JdbcType;
|
||||
//import org.apache.ibatis.type.MappedTypes;
|
||||
//
|
||||
//import java.sql.CallableStatement;
|
||||
//import java.sql.PreparedStatement;
|
||||
//import java.sql.ResultSet;
|
||||
//import java.sql.SQLException;
|
||||
//
|
||||
///**
|
||||
// * chat modal config
|
||||
// *
|
||||
// * @author fansili
|
||||
// * @time 2024/5/6 11:18
|
||||
// * @since 1.0
|
||||
// */
|
||||
//@MappedTypes(value = AiChatModalDO.Config.class)
|
||||
//public class AiChatModelConfigTypeHandler extends BaseTypeHandler<AiChatModalDO.Config> {
|
||||
//
|
||||
// @Override
|
||||
// public void setNonNullParameter(PreparedStatement ps, int i, AiChatModalDO.Config parameter, JdbcType jdbcType) throws SQLException {
|
||||
// // 将 MyCustomType 转换为数据库类型并设置到 PreparedStatement 中
|
||||
// if (parameter == null) {
|
||||
// ps.setString(i, "");
|
||||
// } else {
|
||||
// ps.setString(i, JsonUtils.toJsonString(parameter));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public AiChatModalDO.Config getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
// // 从 ResultSet 中获取数据库类型并转换为 MyCustomType
|
||||
// String str = rs.getString(columnName);
|
||||
// if (StrUtil.isBlank(str)) {
|
||||
// return null;
|
||||
// }
|
||||
// AiChatModalDO.Config config = JsonUtils.parseObject(str, AiChatModalDO.Config.class);
|
||||
// // 获取平台
|
||||
// AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(config.getModelPlatform());
|
||||
// if (AiPlatformEnum.CHAT_PLATFORM_LIST.contains(platformEnum)) {
|
||||
// return JsonUtils.parseObject(str, AiChatModalDO.ChatConfig.class);
|
||||
// } else if (AiPlatformEnum.OPEN_AI_DALL == platformEnum) {
|
||||
// return JsonUtils.parseObject(str, AiChatModalDO.OpenAiImageConfig.class);
|
||||
// } else if (AiPlatformEnum.MIDJOURNEY == platformEnum) {
|
||||
// return JsonUtils.parseObject(str, AiChatModalDO.MidjourneyConfig.class);
|
||||
// }
|
||||
// throw new IllegalArgumentException("ai模型中config不能转换! json: " + str);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public AiChatModalDO.Config getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
// // 从 ResultSet 中获取数据库类型并转换为 MyCustomType
|
||||
// String str = rs.getString(columnIndex);
|
||||
// if (StrUtil.isBlank(str)) {
|
||||
// return null;
|
||||
// }
|
||||
// return JsonUtils.parseObject(str, AiChatModalDO.Config.class);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public AiChatModalDO.Config getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
// // 从 CallableStatement 中获取数据库类型并转换为 MyCustomType
|
||||
// String str = cs.getString(columnIndex);
|
||||
// if (StrUtil.isBlank(str)) {
|
||||
// return null;
|
||||
// }
|
||||
// return JsonUtils.parseObject(str, AiChatModalDO.Config.class);
|
||||
// }
|
||||
//}
|
|
@ -1,27 +0,0 @@
|
|||
|
||||
### 登录 详细使用 https://www.jetbrains.com/help/idea/testing-restful-web-services.html、https://www.cnblogs.com/crazymakercircle/p/14317222.html
|
||||
|
||||
|
||||
### 对话 - list
|
||||
GET {{baseUrl}}/admin-api/ai/chat/conversation/list
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
### 对话 - 创建对话
|
||||
POST {{baseUrl}}/admin-api/ai/chat/conversation/create
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"roleId": "9"
|
||||
}
|
||||
|
||||
### 对话 - id获取
|
||||
GET {{baseUrl}}/admin-api/ai/chat/conversation/get?id=1781604279872581647
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
### 对话 - 删除
|
||||
DELETE {{baseUrl}}/admin-api/ai/chat/conversation/delete?id=1781604279872581647
|
||||
Authorization: {{token}}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
### chat call
|
||||
GET {{baseUrl}}/admin-api/ai/chat/model/list
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
### chat call
|
||||
PUT {{baseUrl}}/admin-api/ai/chat/model/add
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"keyId": "1",
|
||||
"name": "小红书Ai写作大模型4.0",
|
||||
"model": "ERNIE 4.0",
|
||||
"platform": "yiyan",
|
||||
"sort": 100
|
||||
}
|
||||
|
||||
### chat call
|
||||
POST {{baseUrl}}/admin-api/ai/chat/model/update
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"id": 9,
|
||||
"keyId": "1",
|
||||
"name": "小红书Ai写作大模型3.5 8k",
|
||||
"model": "ERNIE-3.5-8K",
|
||||
"platform": "yiyan",
|
||||
"sort": 100
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
|
||||
### chat角色 - list
|
||||
GET {{baseUrl}}/admin-api/ai/chat/role/list?pageNo=1&pageSize=20&search=
|
||||
Authorization: {{token}}
|
||||
|
||||
### chat add
|
||||
PUT {{baseUrl}}/admin-api/ai/chat/role/add
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"modelId": 9,
|
||||
"name": "小红书写作v1",
|
||||
"avatar": "http://baidu.com",
|
||||
"category": "writing",
|
||||
"description": "采用gpt3.5模型,拥有小红书优质作者写作经验。",
|
||||
"systemMessage": "你是一名优秀的小红书人文、风光作者,你热爱旅游,每去往一个城市你都会用美妙的文字抒写着这座城市的大街小巷,描述着这座城市的美好。",
|
||||
"publicStatus": 0,
|
||||
"sort": 0
|
||||
}
|
||||
|
||||
|
||||
### chat update
|
||||
POST {{baseUrl}}/admin-api/ai/chat/role/update
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"id": 8,
|
||||
"modelId": 9,
|
||||
"name": "小红书写作v2",
|
||||
"avatar": "http://baidu.com",
|
||||
"category": "writing",
|
||||
"description": "采用gpt3.5模型,拥有小红书优质作者写作经验。",
|
||||
"systemMessage": "你是一名优秀的小红书人文、风光作者,你热爱旅游,每去往一个城市你都会用美妙的文字抒写着这座城市的大街小巷,描述着这座城市的美好。",
|
||||
"publicStatus": 0,
|
||||
"sort": 0,
|
||||
"status": 0
|
||||
}
|
||||
|
||||
### chat update
|
||||
POST {{baseUrl}}/admin-api/ai/chat/role/update-public-status
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"id": "8",
|
||||
"publicStatus": true
|
||||
}
|
||||
|
||||
|
||||
### chat update
|
||||
DELETE {{baseUrl}}/admin-api/ai/chat/role/delete?id=8
|
||||
Authorization: {{token}}
|
||||
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"global": {
|
||||
"token": "--"
|
||||
},
|
||||
"dev": {
|
||||
"baseUrl": "http://127.0.0.1:48080",
|
||||
"token": "Bearer 66346cc899e243b081321bd1336a257a"
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
|
||||
### 登录
|
||||
|
||||
POST {{baseUrl}}/admin-api/system/auth/login
|
||||
Content-Type: application/json
|
||||
tenant-id: 1
|
||||
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "123456",
|
||||
"captchaVerification": "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==",
|
||||
"socialCode": "1024",
|
||||
"socialState": "9b2ffbc1-7425-4155-9894-9d5c08541d62",
|
||||
"socialCodeValid": true
|
||||
}
|
||||
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package cn.iocoder.yudao.framework.ai.config;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.iocoder.yudao.framework.ai.core.factory.AiClientFactory;
|
||||
import cn.iocoder.yudao.framework.ai.core.factory.AiClientFactoryImpl;
|
||||
import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
|
||||
|
@ -15,24 +14,10 @@ import cn.iocoder.yudao.framework.ai.core.model.yiyan.YiYanChatClient;
|
|||
import cn.iocoder.yudao.framework.ai.core.model.yiyan.YiYanChatOptions;
|
||||
import cn.iocoder.yudao.framework.ai.core.model.yiyan.api.YiYanApi;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyConfig;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyMessage;
|
||||
import org.springframework.ai.models.midjourney.api.MidjourneyInteractionsApi;
|
||||
import org.springframework.ai.models.midjourney.webSocket.MidjourneyMessageHandler;
|
||||
import org.springframework.ai.models.midjourney.webSocket.MidjourneyWebSocketStarter;
|
||||
import org.springframework.ai.models.midjourney.webSocket.listener.MidjourneyMessageListener;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 芋道 AI 自动配置
|
||||
|
@ -111,63 +96,10 @@ public class YudaoAiAutoConfiguration {
|
|||
);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = MidjourneyMessageHandler.class)
|
||||
public MidjourneyMessageHandler defaultMidjourneyMessageHandler() {
|
||||
// 如果没有实现 MidjourneyMessageHandler 默认注入一个
|
||||
return new MidjourneyMessageHandler() {
|
||||
@Override
|
||||
public void messageHandler(MidjourneyMessage midjourneyMessage) {
|
||||
log.info("default midjourney message: {}", midjourneyMessage);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "yudao.ai.midjourney.enable", havingValue = "true")
|
||||
public MidjourneyWebSocketStarter midjourneyWebSocketStarter(ApplicationContext applicationContext,
|
||||
MidjourneyMessageHandler midjourneyMessageHandler,
|
||||
YudaoAiProperties yudaoAiProperties) {
|
||||
// 获取 midjourneyProperties
|
||||
YudaoAiProperties.MidjourneyProperties midjourneyProperties = yudaoAiProperties.getMidjourney();
|
||||
// 获取 midjourneyConfig
|
||||
MidjourneyConfig midjourneyConfig = getMidjourneyConfig(applicationContext, midjourneyProperties);
|
||||
// 创建 socket messageListener
|
||||
MidjourneyMessageListener messageListener = new MidjourneyMessageListener(midjourneyConfig, midjourneyMessageHandler);
|
||||
// 创建 MidjourneyWebSocketStarter
|
||||
return new MidjourneyWebSocketStarter(midjourneyProperties.getWssUrl(), null, midjourneyConfig, messageListener);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "yudao.ai.midjourney.enable", havingValue = "true")
|
||||
public MidjourneyInteractionsApi midjourneyInteractionsApi(ApplicationContext applicationContext, YudaoAiProperties yudaoAiProperties) {
|
||||
// 获取 midjourneyConfig
|
||||
MidjourneyConfig midjourneyConfig = getMidjourneyConfig(applicationContext, yudaoAiProperties.getMidjourney());
|
||||
// 创建 MidjourneyInteractionsApi
|
||||
return new MidjourneyInteractionsApi(midjourneyConfig);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "yudao.ai.suno.enable", havingValue = "true")
|
||||
public SunoApi sunoApi(YudaoAiProperties yudaoAiProperties) {
|
||||
return new SunoApi(yudaoAiProperties.getSuno().getBaseUrl());
|
||||
}
|
||||
|
||||
private static @NotNull MidjourneyConfig getMidjourneyConfig(ApplicationContext applicationContext,
|
||||
YudaoAiProperties.MidjourneyProperties midjourneyProperties) {
|
||||
Map<String, String> requestTemplates = new HashMap<>();
|
||||
try {
|
||||
Resource[] resources = applicationContext.getResources("classpath:http-body/*.json");
|
||||
for (var resource : resources) {
|
||||
String filename = resource.getFilename();
|
||||
String params = IoUtil.readUtf8(resource.getInputStream());
|
||||
requestTemplates.put(filename.substring(0, filename.length() - 5), params);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("Midjourney json模板初始化出错! " + e.getMessage());
|
||||
}
|
||||
// 创建 midjourneyConfig
|
||||
return new MidjourneyConfig(midjourneyProperties.getToken(),
|
||||
midjourneyProperties.getGuildId(), midjourneyProperties.getChannelId(), requestTemplates);
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Midjourney 配置
|
||||
*
|
||||
* author: fansili
|
||||
* time: 2024/4/3 17:10
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MidjourneyConfig {
|
||||
|
||||
/**
|
||||
* token信息
|
||||
*
|
||||
* tip: 登录discard F12找 messages 接口
|
||||
*/
|
||||
private String token;
|
||||
/**
|
||||
* 服务器id
|
||||
*/
|
||||
private String guildId;
|
||||
/**
|
||||
* 频道id
|
||||
*/
|
||||
private String channelId;
|
||||
|
||||
//
|
||||
// api 接口
|
||||
|
||||
/**
|
||||
* 服务地址
|
||||
*/
|
||||
private String serverUrl = "https://discord.com/";
|
||||
/**
|
||||
* 发送命令
|
||||
*/
|
||||
private String apiInteractions = "api/v9/interactions";
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private String apiAttachments = "/api/v9/channels/%s/attachments";
|
||||
/**
|
||||
* 文件上传
|
||||
*/
|
||||
private String apiAttachmentsUpload = "https://discord-attachments-uploads-prd.storage.googleapis.com/";
|
||||
|
||||
//
|
||||
// 浏览器配置
|
||||
|
||||
private String userAage = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36";
|
||||
|
||||
//
|
||||
// 请求 json 文件
|
||||
|
||||
|
||||
private Map<String, String> requestTemplates;
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
private String sessionId;
|
||||
|
||||
public MidjourneyConfig(String token, String guildId, String channelId, Map<String, String> requestTemplates) {
|
||||
this.token = token;
|
||||
this.guildId = guildId;
|
||||
this.channelId = channelId;
|
||||
this.requestTemplates = requestTemplates;
|
||||
|
||||
// 生成 session id
|
||||
sessionId = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,173 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney;
|
||||
|
||||
import org.springframework.ai.models.midjourney.constants.MidjourneyGennerateStatusEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MidjourneyMessage {
|
||||
|
||||
/**
|
||||
* id是一个重要的字段,在同时生成多个的时候,可以区分生成信息
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 提交id(nonce 可能会不存在,系统提示的时候,这个为空)
|
||||
*/
|
||||
private String nonce;
|
||||
/**
|
||||
* 现在已知:
|
||||
* 0:我们发送的消息,和指令
|
||||
* 20: mj生成图片发送过程中
|
||||
* 19: 选择了某一张图片后的通知
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* content
|
||||
*/
|
||||
private Content content;
|
||||
/**
|
||||
* 图片生成完成才有
|
||||
*/
|
||||
private List<ComponentType> components;
|
||||
/**
|
||||
* 生成过程中如果有,预展示图片,这里会有
|
||||
*/
|
||||
private List<Attachment> attachments;
|
||||
/**
|
||||
* 原始数据(discard 返回的原始数据)
|
||||
*/
|
||||
private String rawData;
|
||||
/**
|
||||
* 生成状态(用于区分生成状态)
|
||||
* 1、等待
|
||||
* 2、进行中
|
||||
* 3、完成
|
||||
* {@link MidjourneyGennerateStatusEnum}
|
||||
*/
|
||||
private String generateStatus;
|
||||
/**
|
||||
* 一般用于提示信息
|
||||
* - 错误
|
||||
* - 并发队列满了
|
||||
* - 账号违规了、敏感词
|
||||
* - 账号被封
|
||||
*/
|
||||
private List<Embed> embeds;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class ComponentType {
|
||||
|
||||
private int type;
|
||||
|
||||
private List<Component> components;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Component {
|
||||
/**
|
||||
* 自定义ID,用于唯一标识特定交互动作及其上下文信息。
|
||||
*/
|
||||
private String customId;
|
||||
|
||||
/**
|
||||
* 样式编号,用于确定按钮的样式外观。
|
||||
* 在某些应用中,例如Discord,2可能表示一种特定的颜色或形状的按钮。
|
||||
*/
|
||||
private int style;
|
||||
|
||||
/**
|
||||
* 按钮的标签文本,用户可见的内容。
|
||||
*/
|
||||
private String label;
|
||||
|
||||
/**
|
||||
* 组件类型,此处为2可能表示这是一种特定类型的交互组件,
|
||||
* 如在Discord API中,类型2对应的是一个可点击的按钮组件。
|
||||
*/
|
||||
private int type;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Attachment {
|
||||
// 文件名
|
||||
private String filename;
|
||||
|
||||
// 附件大小(字节)
|
||||
private int size;
|
||||
|
||||
// 内容类型(例如:image/webp)
|
||||
private String contentType;
|
||||
|
||||
// 图像宽度(像素)
|
||||
private int width;
|
||||
|
||||
// 占位符版本号
|
||||
private int placeholderVersion;
|
||||
|
||||
// 代理URL,用于访问附件资源
|
||||
private String proxyUrl;
|
||||
|
||||
// 占位符标识符
|
||||
private String placeholder;
|
||||
|
||||
// 附件ID
|
||||
private String id;
|
||||
|
||||
// 直接访问附件资源的URL
|
||||
private String url;
|
||||
|
||||
// 图像高度(像素)
|
||||
private int height;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Content {
|
||||
private String prompt;
|
||||
private String progress;
|
||||
private String status;
|
||||
}
|
||||
|
||||
/**
|
||||
* embed 用于警告、提示、错误
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Embed {
|
||||
|
||||
// 内容扫描版本号
|
||||
private int contentScanVersion;
|
||||
|
||||
// 颜色值,这里用Java的Color类来表示,注意实际使用中可能需要自定义方法来从int转换为Color对象
|
||||
private String color;
|
||||
|
||||
// 页脚信息,包含文本
|
||||
private Footer footer;
|
||||
|
||||
// 描述信息
|
||||
private String description;
|
||||
|
||||
// 消息类型,这里是富文本类型(这个区分不同提示类型)
|
||||
private String type;
|
||||
|
||||
// 标题
|
||||
private String title;
|
||||
|
||||
// Footer类,作为嵌套类存在,用来表示footer部分的JSON对象
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Footer {
|
||||
// 页脚文本
|
||||
private String text;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.api;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyConfig;
|
||||
import org.springframework.ai.models.midjourney.constants.MidjourneyConstants;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
// TODO @fansili:按照 spring ai 的封装习惯,这个类是不是 MidjourneyApi
|
||||
|
||||
/**
|
||||
* 图片生成
|
||||
*
|
||||
* author: fansili
|
||||
* time: 2024/4/3 17:36
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class MidjourneyInteractions {
|
||||
|
||||
// TODO done @fansili:静态变量,放在最前面哈;
|
||||
/**
|
||||
* header - referer 头信息
|
||||
*/
|
||||
private static final String HEADER_REFERER = "https://discord.com/channels/%s/%s";
|
||||
/**
|
||||
* mj配置文件
|
||||
*/
|
||||
protected final MidjourneyConfig midjourneyConfig;
|
||||
|
||||
protected MidjourneyInteractions(MidjourneyConfig midjourneyConfig) {
|
||||
this.midjourneyConfig = midjourneyConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取headers - application json
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected HttpHeaders getHeadersOfAppJson() {
|
||||
// 设置header值
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
|
||||
httpHeaders.set("Authorization", midjourneyConfig.getToken());
|
||||
httpHeaders.set("User-Agent", midjourneyConfig.getUserAage());
|
||||
httpHeaders.set("Cookie", MidjourneyConstants.HTTP_COOKIE);
|
||||
httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId()));
|
||||
return httpHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取headers - http form data
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected HttpHeaders getHeadersOfFormData() {
|
||||
// 设置header值
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
httpHeaders.set("Authorization", midjourneyConfig.getToken());
|
||||
httpHeaders.set("User-Agent", midjourneyConfig.getUserAage());
|
||||
httpHeaders.set("Cookie", MidjourneyConstants.HTTP_COOKIE);
|
||||
httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId()));
|
||||
return httpHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 - 默认参数
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getDefaultParams() {
|
||||
HashMap<String, String> requestParams = Maps.newHashMap();
|
||||
// TODO done @fansili:感觉参数的组装,可以搞成一个公用的方法;就是 config + 入参的感觉;
|
||||
requestParams.put("guild_id", midjourneyConfig.getGuildId());
|
||||
requestParams.put("channel_id", midjourneyConfig.getChannelId());
|
||||
requestParams.put("session_id", midjourneyConfig.getSessionId());
|
||||
requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); // TODO @fansili:建议用 uuid 之类的;nextId 跨进程未必合适哈;
|
||||
return requestParams;
|
||||
}
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.api;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyConfig;
|
||||
import org.springframework.ai.models.midjourney.api.req.AttachmentsReq;
|
||||
import org.springframework.ai.models.midjourney.api.req.DescribeReq;
|
||||
import org.springframework.ai.models.midjourney.api.req.ReRollReq;
|
||||
import org.springframework.ai.models.midjourney.api.res.UploadAttachmentsRes;
|
||||
import org.springframework.ai.models.midjourney.util.MidjourneyUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
// TODO @fansili:按照 spring ai 的封装习惯,这个类是不是 MidjourneyApi
|
||||
/**
|
||||
* 图片生成
|
||||
*
|
||||
* author: fansili
|
||||
* time: 2024/4/3 17:36
|
||||
*/
|
||||
@Slf4j
|
||||
public class MidjourneyInteractionsApi extends MidjourneyInteractions {
|
||||
|
||||
private final String url;
|
||||
private final RestTemplate restTemplate = new RestTemplate(); // TODO @fansili:优先级低:后续搞到统一的管理
|
||||
|
||||
public MidjourneyInteractionsApi(MidjourneyConfig midjourneyConfig) {
|
||||
super(midjourneyConfig);
|
||||
this.url = midjourneyConfig.getServerUrl().concat(midjourneyConfig.getApiInteractions());
|
||||
}
|
||||
|
||||
public Boolean imagine(String nonce, String prompt) {
|
||||
// 获取请求模板
|
||||
String requestTemplate = midjourneyConfig.getRequestTemplates().get("imagine");
|
||||
// 设置参数
|
||||
HashMap<String, String> requestParams = getDefaultParams();
|
||||
requestParams.put("nonce", nonce);
|
||||
requestParams.put("prompt", prompt);
|
||||
// 解析 template 参数占位符
|
||||
String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams);
|
||||
// 获取 header
|
||||
HttpHeaders httpHeaders = getHeadersOfAppJson();
|
||||
// 发送请求
|
||||
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, httpHeaders);
|
||||
String res = restTemplate.postForObject(url, requestEntity, String.class);
|
||||
// 这个 res 只要不返回值,就是成功!
|
||||
// TODO @fansili:可以直接 if (StrUtil.isBlank(res))
|
||||
if (StrUtil.isBlank(res)) {
|
||||
return true;
|
||||
} else {
|
||||
log.error("请求失败! 请求参数:{} 返回结果! {}", requestBody, res);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// TODO done @fansili:方法和方法之间,空一行哈;
|
||||
|
||||
|
||||
public Boolean reRoll(ReRollReq reRoll) {
|
||||
// 获取请求模板
|
||||
String requestTemplate = midjourneyConfig.getRequestTemplates().get("reroll");
|
||||
// 设置参数
|
||||
HashMap<String, String> requestParams = getDefaultParams();
|
||||
requestParams.put("custom_id", reRoll.getCustomId());
|
||||
requestParams.put("message_id", reRoll.getMessageId());
|
||||
// 获取 header
|
||||
HttpHeaders httpHeaders = getHeadersOfAppJson();
|
||||
// 设置参数
|
||||
String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams);
|
||||
// 发送请求
|
||||
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, httpHeaders);
|
||||
String res = restTemplate.postForObject(url, requestEntity, String.class);
|
||||
// 这个 res 只要不返回值,就是成功!
|
||||
boolean isSuccess = StrUtil.isBlank(res);
|
||||
if (isSuccess) {
|
||||
return true;
|
||||
}
|
||||
log.error("请求失败! 请求参数:{} 返回结果! {}", requestBody, res);
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
// TODO @fansili:搞成私有方法,可能会好点;
|
||||
public UploadAttachmentsRes uploadAttachments(AttachmentsReq attachments) {
|
||||
// file
|
||||
JSONObject fileObj = new JSONObject();
|
||||
fileObj.put("id", "0");
|
||||
fileObj.put("filename", attachments.getFileSystemResource().getFilename());
|
||||
// TODO @fansili:这块用 lombok 哪个异常处理,简化下代码;
|
||||
try {
|
||||
fileObj.put("file_size", attachments.getFileSystemResource().contentLength());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// 创建用于存放表单数据的MultiValueMap
|
||||
MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>();
|
||||
multipartRequest.put("files", Lists.newArrayList(fileObj));
|
||||
// 设置header值
|
||||
HttpHeaders httpHeaders = getHeadersOfAppJson();
|
||||
// 创建HttpEntity对象,包含表单数据和头部信息
|
||||
HttpEntity<MultiValueMap<String, Object>> multiValueMapHttpEntity = new HttpEntity<>(multipartRequest, httpHeaders);
|
||||
// 发送POST请求并接收响应
|
||||
String uri = String.format(midjourneyConfig.getApiAttachments(), midjourneyConfig.getChannelId());
|
||||
String response = restTemplate.postForObject(midjourneyConfig.getServerUrl().concat(uri), multiValueMapHttpEntity, String.class);
|
||||
UploadAttachmentsRes uploadAttachmentsRes = JSON.parseObject(response, UploadAttachmentsRes.class);
|
||||
|
||||
//
|
||||
// 上传文件
|
||||
String uploadUrl = uploadAttachmentsRes.getAttachments().get(0).getUploadUrl();
|
||||
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
HttpEntity<FileSystemResource> fileSystemResourceHttpEntity = new HttpEntity<>(attachments.getFileSystemResource(), httpHeaders);
|
||||
ResponseEntity<String> exchange = restTemplate.exchange(uploadUrl, HttpMethod.PUT, fileSystemResourceHttpEntity, String.class);
|
||||
String uploadRes = exchange.getBody();
|
||||
return uploadAttachmentsRes;
|
||||
}
|
||||
|
||||
public Boolean describe(DescribeReq describe) {
|
||||
// 获取请求模板
|
||||
String requestTemplate = midjourneyConfig.getRequestTemplates().get("describe");
|
||||
// 设置参数
|
||||
HashMap<String, String> requestParams = getDefaultParams();
|
||||
requestParams.put("file_name", describe.getFileName());
|
||||
requestParams.put("final_file_name", describe.getFinalFileName());
|
||||
// 设置 header
|
||||
HttpHeaders httpHeaders = getHeadersOfFormData();
|
||||
String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams);
|
||||
// 创建表单数据
|
||||
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
|
||||
formData.add("payload_json", requestBody);
|
||||
// 发送请求
|
||||
HttpEntity<MultiValueMap<String, String>> multiValueMapHttpEntity = new HttpEntity<>(formData, httpHeaders);
|
||||
String res = restTemplate.postForObject(url, multiValueMapHttpEntity, String.class);
|
||||
// 这个 res 只要不返回值,就是成功!
|
||||
boolean isSuccess = StrUtil.isBlank(res);
|
||||
if (isSuccess) {
|
||||
return true;
|
||||
}
|
||||
log.error("请求失败! 请求参数:{} 返回结果! {}", requestBody, res);
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.api.req;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
|
||||
/**
|
||||
* 附件
|
||||
* <p>
|
||||
* author: fansili
|
||||
* time: 2024/4/7 17:18
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AttachmentsReq {
|
||||
|
||||
/**
|
||||
* 创建文件系统资源对象
|
||||
*/
|
||||
private FileSystemResource fileSystemResource;
|
||||
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.api.req;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* describe
|
||||
*
|
||||
* author: fansili
|
||||
* time: 2024/4/7 12:30
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DescribeReq {
|
||||
|
||||
/**
|
||||
* 文件名字
|
||||
*/
|
||||
private String fileName;
|
||||
/**
|
||||
* UploadAttachmentsRes 里面的 finalFileName
|
||||
*/
|
||||
private String finalFileName;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.api.req;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* author: fansili
|
||||
* time: 2024/4/6 21:33
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ReRollReq {
|
||||
|
||||
/**
|
||||
* socket 消息里面收到的 messageId
|
||||
*/
|
||||
private String messageId;
|
||||
/**
|
||||
* socket 消息里面的,操作按钮id(MJ::JOB::upsample::3::2aeefbef-43e2-4057-bcf1-43b5f39ab6f7)
|
||||
*/
|
||||
private String customId;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.api.res;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 上传附件 - res
|
||||
*
|
||||
* author: fansili
|
||||
* time: 2024/4/8 13:32
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UploadAttachmentsRes {
|
||||
|
||||
private List<Attachment> attachments;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Attachment {
|
||||
/**
|
||||
* 附件的ID。
|
||||
*/
|
||||
private int id;
|
||||
/**
|
||||
* 附件的上传URL。
|
||||
*/
|
||||
private String uploadUrl;
|
||||
/**
|
||||
* 上传到服务器的文件名。
|
||||
*/
|
||||
private String uploadFilename;
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.constants;
|
||||
|
||||
public final class MidjourneyConstants {
|
||||
|
||||
/**
|
||||
* 消息 - 编号
|
||||
*/
|
||||
public static final String MSG_ID = "id";
|
||||
/**
|
||||
* 用于区分操作唯一性
|
||||
*/
|
||||
public static final String MSG_NONCE = "nonce";
|
||||
/**
|
||||
* 消息 - 类型
|
||||
* 现在已知:
|
||||
* 0:我们发送的消息,和指令
|
||||
* 20: mj生成图片发送过程中
|
||||
* 19: 选择了某一张图片后的通知
|
||||
*/
|
||||
public static final String MSG_TYPE = "type";
|
||||
/**
|
||||
* 平道id
|
||||
*/
|
||||
public static final String MSG_CHANNEL_ID = "channel_id";
|
||||
/**
|
||||
* 内容
|
||||
*
|
||||
* "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (32%) (fast, stealth)",
|
||||
*/
|
||||
public static final String MSG_CONTENT = "content";
|
||||
/**
|
||||
* 组件(图片生成好之后才有)
|
||||
*/
|
||||
public static final String MSG_COMPONENTS = "components";
|
||||
/**
|
||||
* 附件(生成中比较模糊的图片)
|
||||
*/
|
||||
public static final String MSG_ATTACHMENTS = "attachments";
|
||||
/**
|
||||
* 一般用于提示
|
||||
*/
|
||||
public static final String MSG_EMBEDS = "embeds";
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
public static final String HTTP_COOKIE = "__dcfduid=6ca536c0e3fa11eeb7cbe34c31b49caf; __sdcfduid=6ca536c1e3fa11eeb7cbe34c31b49caf52cce5ffd8983d2a052cf6aba75fe5fe566f2c265902e283ce30dbf98b8c9c93; _gcl_au=1.1.245923998.1710853617; _ga=GA1.1.111061823.1710853617; __cfruid=6385bb3f48345a006b25992db7dcf984e395736d-1712124666; _cfuvid=O09la5ms0ypNptiG0iD8A6BKWlTxz1LG0WR7qRStD7o-1712124666575-0.0.1.1-604800000; locale=zh-CN; cf_clearance=l_YGod1_SUtYxpDVeZXiX7DLLPl1DYrquZe8WVltvYs-1712124668-1.0.1.1-Hl2.fToel23EpF2HCu9J20rB4D7OhhCzoajPSdo.9Up.wPxhvq22DP9RHzEBKuIUlKyH.kJLxXJfAt2N.LD5WQ; OptanonConsent=isIABGlobal=false&datestamp=Wed+Apr+03+2024+14%3A11%3A15+GMT%2B0800+(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4)&version=6.33.0&hosts=&landingPath=https%3A%2F%2Fdiscord.com%2F&groups=C0001%3A1%2CC0002%3A1%2CC0003%3A1; _ga_Q149DFWHT7=GS1.1.1712124668.4.1.1712124679.0.0.0";
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.constants;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
// TODO done @fansili:1)Mj 缩写,还是搞成全称。。虽然长一点,但是感觉会相对清晰一些哈;2)lombok 相关的注解,可以用用哈;3)value 改 status;
|
||||
/**
|
||||
* mj 生成状态
|
||||
*
|
||||
* author: fansili
|
||||
* time: 2024/4/6 21:07
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MidjourneyGennerateStatusEnum {
|
||||
|
||||
WAITING("waiting", "等待..."),
|
||||
IN_PROGRESS("in_progress", "进行中"),
|
||||
COMPLETED("completed", "完成"),
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private String status;
|
||||
/**
|
||||
* 状态信息
|
||||
*/
|
||||
private String message;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.constants;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* MJ 命令
|
||||
*/
|
||||
@Getter
|
||||
public enum MidjourneyInteractionsEnum {
|
||||
|
||||
IMAGINE("imagine", "生成图片"),
|
||||
DESCRIBE("describe", "生成描述"),
|
||||
FAST("fast", "快速生成"),
|
||||
SETTINGS("settings", "设置"),
|
||||
ASK("ask", "提问"),
|
||||
BLEND("blend", "融合"),
|
||||
|
||||
;
|
||||
|
||||
MidjourneyInteractionsEnum(String value, String message) {
|
||||
this.value =value;
|
||||
this.message =message;
|
||||
}
|
||||
|
||||
private String value;
|
||||
private String message;
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.constants;
|
||||
|
||||
|
||||
public enum MidjourneyMessageTypeEnum {
|
||||
/**
|
||||
* 创建.
|
||||
*/
|
||||
CREATE,
|
||||
/**
|
||||
* 修改.
|
||||
*/
|
||||
UPDATE,
|
||||
/**
|
||||
* 删除.
|
||||
*/
|
||||
DELETE;
|
||||
|
||||
public static MidjourneyMessageTypeEnum of(String type) {
|
||||
return switch (type) {
|
||||
case "MESSAGE_CREATE" -> CREATE;
|
||||
case "MESSAGE_UPDATE" -> UPDATE;
|
||||
case "MESSAGE_DELETE" -> DELETE;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.constants;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@UtilityClass
|
||||
public final class MidjourneyNotifyCode {
|
||||
/**
|
||||
* 成功.
|
||||
*/
|
||||
public static final int SUCCESS = 1;
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.util;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyMessage;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* mj util
|
||||
*
|
||||
* author: fansili
|
||||
* time: 2024/4/6 19:00
|
||||
*/
|
||||
public class MidjourneyUtil {
|
||||
/**
|
||||
* content正则匹配prompt和进度.
|
||||
*/
|
||||
public static final String CONTENT_REGEX = ".*?\\*\\*(.*?)\\*\\*.+<@\\d+> \\((.*?)\\)";
|
||||
public static final String CONTENT_PROGRESS_REGEX = "\\(([^)]*)\\)";
|
||||
|
||||
/**
|
||||
* 解析 content 参数
|
||||
*
|
||||
* @param content
|
||||
* @return
|
||||
*/
|
||||
public static MidjourneyMessage.Content parseContent(String content) {
|
||||
// 有三种格式。
|
||||
// 南极应该是什么样子?
|
||||
// "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (32%) (fast, stealth)",
|
||||
// "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (fast, stealth)"
|
||||
// Upscaling image #3 with **A girl from China, creator of ancient Chinese clothing, dances on the square** - <@975372485971312700> (Waiting to start)
|
||||
MidjourneyMessage.Content mjContent = new MidjourneyMessage.Content();
|
||||
if (CharSequenceUtil.isBlank(content)) {
|
||||
return null;
|
||||
}
|
||||
if (!content.contains("<@")) {
|
||||
return mjContent.setPrompt(content);
|
||||
}
|
||||
int rawIndex = content.indexOf("<@") - 3;
|
||||
String prompt = content.substring(0, rawIndex).trim();
|
||||
String contentTail = content.substring(rawIndex).trim();
|
||||
// 检查是否存在进度条
|
||||
Pattern pattern = Pattern.compile(CONTENT_PROGRESS_REGEX);
|
||||
Matcher matcher = pattern.matcher(contentTail);
|
||||
|
||||
if (contentTail.contains("%")) {
|
||||
if (matcher.find()) {
|
||||
// 获取第一个(也是此处唯一的)捕获组的内容
|
||||
String progress = matcher.group(1);
|
||||
mjContent.setProgress(progress);
|
||||
}
|
||||
if (matcher.find()) {
|
||||
String status = matcher.group(1);
|
||||
mjContent.setStatus(status);
|
||||
}
|
||||
} else {
|
||||
if (matcher.find()) {
|
||||
// 获取第一个(也是此处唯一的)捕获组的内容
|
||||
String status = matcher.group(1);
|
||||
mjContent.setStatus(status);
|
||||
}
|
||||
}
|
||||
mjContent.setPrompt(prompt);
|
||||
// tip:contentArray
|
||||
return mjContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 params
|
||||
*
|
||||
* @param requestTemplate
|
||||
* @param requestParams
|
||||
* @return
|
||||
*/
|
||||
public static String parseTemplate(String requestTemplate, Map<String, String> requestParams) {
|
||||
for (Map.Entry<String, String> entry : requestParams.entrySet()) {
|
||||
requestTemplate = requestTemplate.replace("$".concat(entry.getKey()), entry.getValue());
|
||||
}
|
||||
return requestTemplate;
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.webSocket;
|
||||
|
||||
|
||||
public interface FailureCallback {
|
||||
void onFailure(int code, String reason);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.webSocket;
|
||||
|
||||
import org.springframework.ai.models.midjourney.MidjourneyMessage;
|
||||
|
||||
/**
|
||||
* message handler
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/29 14:29
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface MidjourneyMessageHandler {
|
||||
|
||||
void messageHandler(MidjourneyMessage midjourneyMessage);
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.webSocket;
|
||||
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyConfig;
|
||||
import org.springframework.ai.models.midjourney.constants.MidjourneyNotifyCode;
|
||||
import org.springframework.ai.models.midjourney.webSocket.handler.MidjourneyWebSocketHandler;
|
||||
import org.springframework.ai.models.midjourney.webSocket.listener.MidjourneyMessageListener;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.tomcat.websocket.Constants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
import org.springframework.util.concurrent.ListenableFutureCallback;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.WebSocketHttpHeaders;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
// TODO @fansili:mj 这块 websocket 有点小复杂,虽然代码量 400 多行;感觉可以考虑,有没第三方 sdk,通过它透明接入 mj
|
||||
@Slf4j
|
||||
public class MidjourneyWebSocketStarter implements WebSocketStarter {
|
||||
/**
|
||||
* 链接重试次数
|
||||
*/
|
||||
private static final int CONNECT_RETRY_LIMIT = 5;
|
||||
/**
|
||||
* mj 配置文件
|
||||
*/
|
||||
private final MidjourneyConfig midjourneyConfig;
|
||||
/**
|
||||
* mj 监听(所有message 都会 callback到这里)
|
||||
*/
|
||||
private final MidjourneyMessageListener userMessageListener;
|
||||
/**
|
||||
* wss 服务器
|
||||
*/
|
||||
private final String wssServer;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private final String resumeWss;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private ResumeData resumeData = null;
|
||||
/**
|
||||
* 是否运行成功
|
||||
*/
|
||||
private boolean running = false;
|
||||
/**
|
||||
* 链接成功的 session
|
||||
*/
|
||||
private WebSocketSession webSocketSession = null;
|
||||
private WssNotify wssNotify = null;
|
||||
|
||||
public MidjourneyWebSocketStarter(String wssServer,
|
||||
String resumeWss,
|
||||
MidjourneyConfig midjourneyConfig,
|
||||
MidjourneyMessageListener userMessageListener) {
|
||||
this.wssServer = wssServer;
|
||||
this.resumeWss = resumeWss;
|
||||
this.midjourneyConfig = midjourneyConfig;
|
||||
this.userMessageListener = userMessageListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(WssNotify wssNotify) {
|
||||
this.wssNotify = wssNotify;
|
||||
start(false);
|
||||
}
|
||||
|
||||
private void start(boolean reconnect) {
|
||||
// 设置header
|
||||
WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
|
||||
headers.add("Accept-Encoding", "gzip, deflate, br");
|
||||
headers.add("Accept-Language", "zh-CN,zh;q=0.9");
|
||||
headers.add("Cache-Control", "no-cache");
|
||||
headers.add("Pragma", "no-cache");
|
||||
headers.add("Sec-Websocket-Extensions", "permessage-deflate; client_max_window_bits");
|
||||
headers.add("User-Agent", this.midjourneyConfig.getUserAage());
|
||||
// 创建 mjHeader
|
||||
MidjourneyWebSocketHandler mjWebSocketHandler = new MidjourneyWebSocketHandler(
|
||||
this.midjourneyConfig, this.userMessageListener, this::onSocketSuccess, this::onSocketFailure);
|
||||
//
|
||||
String gatewayUrl;
|
||||
if (reconnect) {
|
||||
gatewayUrl = getGatewayServer(this.resumeData.getResumeGatewayUrl()) + "/?encoding=json&v=9&compress=zlib-stream";
|
||||
mjWebSocketHandler.setSessionId(this.resumeData.getSessionId());
|
||||
mjWebSocketHandler.setSequence(this.resumeData.getSequence());
|
||||
mjWebSocketHandler.setResumeGatewayUrl(this.resumeData.getResumeGatewayUrl());
|
||||
} else {
|
||||
gatewayUrl = getGatewayServer(null) + "/?encoding=json&v=9&compress=zlib-stream";
|
||||
}
|
||||
// 创建 StandardWebSocketClient
|
||||
StandardWebSocketClient webSocketClient = new StandardWebSocketClient();
|
||||
// 设置 io timeout 时间
|
||||
webSocketClient.getUserProperties().put(Constants.IO_TIMEOUT_MS_PROPERTY, "10000");
|
||||
//
|
||||
ListenableFuture<WebSocketSession> socketSessionFuture = webSocketClient.doHandshake(mjWebSocketHandler, headers, URI.create(gatewayUrl));
|
||||
// 添加 callback 进行回调
|
||||
socketSessionFuture.addCallback(new ListenableFutureCallback<>() {
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable e) {
|
||||
onSocketFailure(MidjourneyWebSocketHandler.CLOSE_CODE_EXCEPTION, e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(WebSocketSession session) {
|
||||
MidjourneyWebSocketStarter.this.webSocketSession = session;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onSocketSuccess(String sessionId, Object sequence, String resumeGatewayUrl) {
|
||||
this.resumeData = new ResumeData(sessionId, sequence, resumeGatewayUrl);
|
||||
this.running = true;
|
||||
notifyWssLock(MidjourneyNotifyCode.SUCCESS, "");
|
||||
}
|
||||
|
||||
private void onSocketFailure(int code, String reason) {
|
||||
// 1001异常可以忽略
|
||||
if (code == 1001) {
|
||||
return;
|
||||
}
|
||||
// 关闭 socket
|
||||
closeSocketSessionWhenIsOpen();
|
||||
// 没有运行通知
|
||||
if (!this.running) {
|
||||
notifyWssLock(code, reason);
|
||||
return;
|
||||
}
|
||||
// 已经运行先设置为false,发起
|
||||
this.running = false;
|
||||
if (code >= 4000) {
|
||||
log.warn("[wss-{}] Can't reconnect! Account disabled. Closed by {}({}).", this.midjourneyConfig.getChannelId(), code, reason);
|
||||
} else if (code == 2001) {
|
||||
log.warn("[wss-{}] Closed by {}({}). Try reconnect...", this.midjourneyConfig.getChannelId(), code, reason);
|
||||
tryReconnect();
|
||||
} else {
|
||||
log.warn("[wss-{}] Closed by {}({}). Try new connection...", this.midjourneyConfig.getChannelId(), code, reason);
|
||||
tryNewConnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重连
|
||||
*/
|
||||
private void tryReconnect() {
|
||||
try {
|
||||
tryStart(true);
|
||||
} catch (Exception e) {
|
||||
log.warn("[wss-{}] Reconnect fail: {}, Try new connection...", this.midjourneyConfig.getChannelId(), e.getMessage());
|
||||
ThreadUtil.sleep(1000);
|
||||
tryNewConnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void tryNewConnect() {
|
||||
// 链接重试次数5
|
||||
for (int i = 1; i <= CONNECT_RETRY_LIMIT; i++) {
|
||||
try {
|
||||
tryStart(false);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
log.warn("[wss-{}] New connect fail ({}): {}", this.midjourneyConfig.getChannelId(), i, e.getMessage());
|
||||
ThreadUtil.sleep(5000);
|
||||
}
|
||||
}
|
||||
log.error("[wss-{}] Account disabled", this.midjourneyConfig.getChannelId());
|
||||
}
|
||||
|
||||
public void tryStart(boolean reconnect) {
|
||||
start(reconnect);
|
||||
}
|
||||
|
||||
private void notifyWssLock(int code, String reason) {
|
||||
System.err.println("notifyWssLock: " + code + " - " + reason);
|
||||
if (wssNotify != null) {
|
||||
wssNotify.notify(code, reason);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭 socket session
|
||||
*/
|
||||
private void closeSocketSessionWhenIsOpen() {
|
||||
try {
|
||||
if (this.webSocketSession != null && this.webSocketSession.isOpen()) {
|
||||
this.webSocketSession.close(CloseStatus.GOING_AWAY);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
private String getGatewayServer(String resumeGatewayUrl) {
|
||||
if (CharSequenceUtil.isNotBlank(resumeGatewayUrl)) {
|
||||
return CharSequenceUtil.isBlank(this.resumeWss) ? resumeGatewayUrl : this.resumeWss;
|
||||
}
|
||||
return this.wssServer;
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class ResumeData {
|
||||
|
||||
public ResumeData(String sessionId, Object sequence, String resumeGatewayUrl) {
|
||||
this.sessionId = sessionId;
|
||||
this.sequence = sequence;
|
||||
this.resumeGatewayUrl = resumeGatewayUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* socket session
|
||||
*/
|
||||
private final String sessionId;
|
||||
private final Object sequence;
|
||||
private final String resumeGatewayUrl;
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.webSocket;
|
||||
|
||||
|
||||
public interface SuccessCallback {
|
||||
|
||||
void onSuccess(String sessionId, Object sequence, String resumeGatewayUrl);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.webSocket;
|
||||
|
||||
|
||||
public interface WebSocketStarter {
|
||||
|
||||
void start(WssNotify wssNotify) throws Exception;
|
||||
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.webSocket;
|
||||
|
||||
/**
|
||||
* 通知信息
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/29 14:21
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface WssNotify {
|
||||
|
||||
void notify(int code, String message);
|
||||
}
|
|
@ -1,281 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.webSocket.handler;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.http.useragent.UserAgentUtil;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyConfig;
|
||||
import org.springframework.ai.models.midjourney.webSocket.FailureCallback;
|
||||
import org.springframework.ai.models.midjourney.webSocket.SuccessCallback;
|
||||
import org.springframework.ai.models.midjourney.webSocket.listener.MidjourneyMessageListener;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.utils.data.DataArray;
|
||||
import net.dv8tion.jda.api.utils.data.DataObject;
|
||||
import net.dv8tion.jda.api.utils.data.DataType;
|
||||
import net.dv8tion.jda.internal.requests.WebSocketCode;
|
||||
import net.dv8tion.jda.internal.utils.compress.Decompressor;
|
||||
import net.dv8tion.jda.internal.utils.compress.ZlibDecompressor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.web.socket.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
public class MidjourneyWebSocketHandler implements WebSocketHandler {
|
||||
/**
|
||||
* close 错误码:重连
|
||||
*/
|
||||
public static final int CLOSE_CODE_RECONNECT = 2001;
|
||||
/**
|
||||
* close 错误码:无效、作废
|
||||
*/
|
||||
public static final int CLOSE_CODE_INVALIDATE = 1009;
|
||||
/**
|
||||
* close 错误码:异常
|
||||
*/
|
||||
public static final int CLOSE_CODE_EXCEPTION = 1011;
|
||||
/**
|
||||
* mj配置文件
|
||||
*/
|
||||
private final MidjourneyConfig midjourneyConfig;
|
||||
/**
|
||||
* mj 消息监听
|
||||
*/
|
||||
private final MidjourneyMessageListener userMessageListener;
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
private final SuccessCallback successCallback;
|
||||
/**
|
||||
* 失败回调
|
||||
*/
|
||||
private final FailureCallback failureCallback;
|
||||
/**
|
||||
* 心跳执行器
|
||||
*/
|
||||
private final ScheduledExecutorService heartExecutor;
|
||||
/**
|
||||
* auth数据
|
||||
*/
|
||||
private final DataObject authData;
|
||||
|
||||
@Setter
|
||||
private String sessionId = null;
|
||||
@Setter
|
||||
private Object sequence = null;
|
||||
@Setter
|
||||
private String resumeGatewayUrl = null;
|
||||
|
||||
private long interval = 41250;
|
||||
private boolean heartbeatAck = false;
|
||||
|
||||
private Future<?> heartbeatInterval;
|
||||
private Future<?> heartbeatTimeout;
|
||||
|
||||
/**
|
||||
* 处理 message 消息的 Decompressor
|
||||
*/
|
||||
private final Decompressor decompressor = new ZlibDecompressor(2048);
|
||||
|
||||
public MidjourneyWebSocketHandler(MidjourneyConfig account,
|
||||
MidjourneyMessageListener userMessageListener,
|
||||
SuccessCallback successCallback,
|
||||
FailureCallback failureCallback) {
|
||||
this.midjourneyConfig = account;
|
||||
this.userMessageListener = userMessageListener;
|
||||
this.successCallback = successCallback;
|
||||
this.failureCallback = failureCallback;
|
||||
this.heartExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
this.authData = createAuthData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(@NotNull WebSocketSession session) throws Exception {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(@NotNull WebSocketSession session, @NotNull Throwable e) throws Exception {
|
||||
log.error("[wss-{}] Transport error", this.midjourneyConfig.getChannelId(), e);
|
||||
// 通知链接异常
|
||||
onFailure(CLOSE_CODE_EXCEPTION, "transport error");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(@NotNull WebSocketSession session, @NotNull CloseStatus closeStatus) throws Exception {
|
||||
// 链接关闭
|
||||
onFailure(closeStatus.getCode(), closeStatus.getReason());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPartialMessages() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(@NotNull WebSocketSession session, WebSocketMessage<?> message) throws Exception {
|
||||
// 获取 message 消息
|
||||
ByteBuffer buffer = (ByteBuffer) message.getPayload();
|
||||
// 解析 message
|
||||
byte[] decompressed = decompressor.decompress(buffer.array());
|
||||
if (decompressed == null) {
|
||||
return;
|
||||
}
|
||||
// 转换 json
|
||||
String json = new String(decompressed, StandardCharsets.UTF_8);
|
||||
// 转换 jda 自带的 dataObject(和json object 差不多)
|
||||
DataObject data = DataObject.fromJson(json);
|
||||
// 获取消息类型
|
||||
int opCode = data.getInt("op");
|
||||
switch (opCode) {
|
||||
case WebSocketCode.HEARTBEAT -> handleHeartbeat(session);
|
||||
case WebSocketCode.HEARTBEAT_ACK -> {
|
||||
this.heartbeatAck = true;
|
||||
clearHeartbeatTimeout();
|
||||
}
|
||||
case WebSocketCode.HELLO -> {
|
||||
handleHello(session, data);
|
||||
doResumeOrIdentify(session);
|
||||
}
|
||||
case WebSocketCode.RESUME -> onSuccess();
|
||||
case WebSocketCode.RECONNECT -> onFailure(CLOSE_CODE_RECONNECT, "receive server reconnect");
|
||||
case WebSocketCode.INVALIDATE_SESSION -> onFailure(CLOSE_CODE_INVALIDATE, "receive session invalid");
|
||||
case WebSocketCode.DISPATCH -> handleDispatch(data);
|
||||
default -> log.debug("[wss-{}] Receive unknown code: {}.", midjourneyConfig.getChannelId(), data);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDispatch(DataObject raw) {
|
||||
this.sequence = raw.opt("s").orElse(null);
|
||||
if (!raw.isType("d", DataType.OBJECT)) {
|
||||
return;
|
||||
}
|
||||
DataObject content = raw.getObject("d");
|
||||
String t = raw.getString("t", null);
|
||||
if ("READY".equals(t)) {
|
||||
this.sessionId = content.getString("session_id");
|
||||
this.resumeGatewayUrl = content.getString("resume_gateway_url");
|
||||
onSuccess();
|
||||
} else if ("RESUMED".equals(t)) {
|
||||
onSuccess();
|
||||
} else {
|
||||
try {
|
||||
this.userMessageListener.onMessage(raw);
|
||||
} catch (Exception e) {
|
||||
log.error("[wss-{}] Handle message error", this.midjourneyConfig.getChannelId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleHeartbeat(WebSocketSession session) {
|
||||
sendMessage(session, WebSocketCode.HEARTBEAT, this.sequence);
|
||||
this.heartbeatTimeout = ThreadUtil.execAsync(() -> {
|
||||
ThreadUtil.sleep(this.interval);
|
||||
onFailure(CLOSE_CODE_RECONNECT, "heartbeat has not ack");
|
||||
});
|
||||
}
|
||||
|
||||
private void handleHello(WebSocketSession session, DataObject data) {
|
||||
clearHeartbeatInterval();
|
||||
this.interval = data.getObject("d").getLong("heartbeat_interval");
|
||||
this.heartbeatAck = true;
|
||||
this.heartbeatInterval = this.heartExecutor.scheduleAtFixedRate(() -> {
|
||||
if (this.heartbeatAck) {
|
||||
this.heartbeatAck = false;
|
||||
sendMessage(session, WebSocketCode.HEARTBEAT, this.sequence);
|
||||
} else {
|
||||
onFailure(CLOSE_CODE_RECONNECT, "heartbeat has not ack interval");
|
||||
}
|
||||
}, (long) Math.floor(RandomUtil.randomDouble(0, 1) * this.interval), this.interval, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void doResumeOrIdentify(WebSocketSession session) {
|
||||
if (CharSequenceUtil.isBlank(this.sessionId)) {
|
||||
sendMessage(session, WebSocketCode.IDENTIFY, this.authData);
|
||||
} else {
|
||||
var data = DataObject.empty().put("token", this.midjourneyConfig.getToken())
|
||||
.put("session_id", this.sessionId).put("seq", this.sequence);
|
||||
sendMessage(session, WebSocketCode.RESUME, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessage(WebSocketSession session, int op, Object d) {
|
||||
var data = DataObject.empty().put("op", op).put("d", d);
|
||||
try {
|
||||
session.sendMessage(new TextMessage(data.toString()));
|
||||
} catch (IOException e) {
|
||||
log.error("[wss-{}] Send message error", this.midjourneyConfig.getChannelId(), e);
|
||||
onFailure(CLOSE_CODE_EXCEPTION, "send message error");
|
||||
}
|
||||
}
|
||||
|
||||
private void onSuccess() {
|
||||
ThreadUtil.execute(() -> this.successCallback.onSuccess(this.sessionId, this.sequence, this.resumeGatewayUrl));
|
||||
}
|
||||
|
||||
private void onFailure(int code, String reason) {
|
||||
clearHeartbeatTimeout();
|
||||
clearHeartbeatInterval();
|
||||
ThreadUtil.execute(() -> this.failureCallback.onFailure(code, reason));
|
||||
}
|
||||
|
||||
private void clearHeartbeatTimeout() {
|
||||
if (this.heartbeatTimeout != null) {
|
||||
this.heartbeatTimeout.cancel(true);
|
||||
this.heartbeatTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void clearHeartbeatInterval() {
|
||||
if (this.heartbeatInterval != null) {
|
||||
this.heartbeatInterval.cancel(true);
|
||||
this.heartbeatInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
private DataObject createAuthData() {
|
||||
UserAgent userAgent = UserAgentUtil.parse(this.midjourneyConfig.getUserAage());
|
||||
DataObject connectionProperties = DataObject.empty()
|
||||
.put("browser", userAgent.getBrowser().getName())
|
||||
.put("browser_user_agent", this.midjourneyConfig.getUserAage())
|
||||
.put("browser_version", userAgent.getVersion())
|
||||
.put("client_build_number", 222963)
|
||||
.put("client_event_source", null)
|
||||
.put("device", "")
|
||||
.put("os", userAgent.getOs().getName())
|
||||
.put("referer", "https://www.midjourney.com")
|
||||
.put("referrer_current", "")
|
||||
.put("referring_domain", "www.midjourney.com")
|
||||
.put("referring_domain_current", "")
|
||||
.put("release_channel", "stable")
|
||||
.put("system_locale", "zh-CN");
|
||||
DataObject presence = DataObject.empty()
|
||||
.put("activities", DataArray.empty())
|
||||
.put("afk", false)
|
||||
.put("since", 0)
|
||||
.put("status", "online");
|
||||
DataObject clientState = DataObject.empty()
|
||||
.put("api_code_version", 0)
|
||||
.put("guild_versions", DataObject.empty())
|
||||
.put("highest_last_message_id", "0")
|
||||
.put("private_channels_version", "0")
|
||||
.put("read_state_version", 0)
|
||||
.put("user_guild_settings_version", -1)
|
||||
.put("user_settings_version", -1);
|
||||
return DataObject.empty()
|
||||
.put("capabilities", 16381)
|
||||
.put("client_state", clientState)
|
||||
.put("compress", false)
|
||||
.put("presence", presence)
|
||||
.put("properties", connectionProperties)
|
||||
.put("token", this.midjourneyConfig.getToken());
|
||||
}
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
package org.springframework.ai.models.midjourney.webSocket.listener;
|
||||
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyConfig;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyMessage;
|
||||
import org.springframework.ai.models.midjourney.constants.MidjourneyConstants;
|
||||
import org.springframework.ai.models.midjourney.constants.MidjourneyGennerateStatusEnum;
|
||||
import org.springframework.ai.models.midjourney.constants.MidjourneyMessageTypeEnum;
|
||||
import org.springframework.ai.models.midjourney.util.MidjourneyUtil;
|
||||
import org.springframework.ai.models.midjourney.webSocket.MidjourneyMessageHandler;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.utils.data.DataObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class MidjourneyMessageListener {
|
||||
|
||||
private MidjourneyConfig midjourneyConfig;
|
||||
private MidjourneyMessageHandler midjourneyMessageHandler = null;
|
||||
|
||||
public MidjourneyMessageListener(MidjourneyConfig midjourneyConfig) {
|
||||
this.midjourneyConfig = midjourneyConfig;
|
||||
}
|
||||
|
||||
public MidjourneyMessageListener(MidjourneyConfig midjourneyConfig,
|
||||
MidjourneyMessageHandler midjourneyMessageHandler) {
|
||||
this.midjourneyConfig = midjourneyConfig;
|
||||
this.midjourneyMessageHandler = midjourneyMessageHandler;
|
||||
}
|
||||
|
||||
public void onMessage(DataObject raw) {
|
||||
MidjourneyMessageTypeEnum messageType = MidjourneyMessageTypeEnum.of(raw.getString("t"));
|
||||
if (messageType == null || MidjourneyMessageTypeEnum.DELETE == messageType) {
|
||||
return;
|
||||
}
|
||||
DataObject data = raw.getObject("d");
|
||||
if (ignoreAndLogMessage(data, messageType)) {
|
||||
return;
|
||||
}
|
||||
log.info("socket message: {}", raw);
|
||||
// 转换几个重要的信息
|
||||
MidjourneyMessage mjMessage = new MidjourneyMessage();
|
||||
mjMessage.setId(getString(data, MidjourneyConstants.MSG_ID, ""));
|
||||
mjMessage.setNonce(getString(data, MidjourneyConstants.MSG_NONCE, ""));
|
||||
mjMessage.setType(data.getInt(MidjourneyConstants.MSG_TYPE));
|
||||
mjMessage.setRawData(StrUtil.str(raw.toJson(), "UTF-8"));
|
||||
mjMessage.setContent(MidjourneyUtil.parseContent(data.getString(MidjourneyConstants.MSG_CONTENT)));
|
||||
// 转换 components
|
||||
if (!data.getArray(MidjourneyConstants.MSG_COMPONENTS).isEmpty()) {
|
||||
String componentsJson = StrUtil.str(data.getArray(MidjourneyConstants.MSG_COMPONENTS).toJson(), "UTF-8");
|
||||
List<MidjourneyMessage.ComponentType> components = JsonUtils.parseArray(componentsJson, MidjourneyMessage.ComponentType.class);
|
||||
mjMessage.setComponents(components);
|
||||
}
|
||||
// 转换附件
|
||||
if (!data.getArray(MidjourneyConstants.MSG_ATTACHMENTS).isEmpty()) {
|
||||
String attachmentsJson = StrUtil.str(data.getArray(MidjourneyConstants.MSG_ATTACHMENTS).toJson(), "UTF-8");
|
||||
List<MidjourneyMessage.Attachment> attachments = JsonUtils.parseArray(attachmentsJson, MidjourneyMessage.Attachment.class);
|
||||
mjMessage.setAttachments(attachments);
|
||||
}
|
||||
// 转换 embeds 提示信息
|
||||
if (!data.getArray(MidjourneyConstants.MSG_EMBEDS).isEmpty()) {
|
||||
String embedJson = StrUtil.str(data.getArray(MidjourneyConstants.MSG_EMBEDS).toJson(), "UTF-8");
|
||||
List<MidjourneyMessage.Embed> embeds = JsonUtils.parseArray(embedJson, MidjourneyMessage.Embed.class);
|
||||
mjMessage.setEmbeds(embeds);
|
||||
}
|
||||
// 转换状态
|
||||
convertGenerateStatus(mjMessage);
|
||||
// message handler 调用
|
||||
if (midjourneyMessageHandler != null) {
|
||||
midjourneyMessageHandler.messageHandler(mjMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private String getString(DataObject data, String key, String defaultValue) {
|
||||
if (!data.hasKey(key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return data.getString(key);
|
||||
}
|
||||
|
||||
private void convertGenerateStatus(MidjourneyMessage mjMessage) {
|
||||
//
|
||||
// tip:提示、警告、异常 content是没有内容的
|
||||
// tip: 一般错误信息在 Embeds 只要 Embeds有值,content就没信息。
|
||||
if (CollUtil.isNotEmpty(mjMessage.getEmbeds())) {
|
||||
return;
|
||||
}
|
||||
if (mjMessage.getType() == 20 && mjMessage.getContent().getStatus().contains("Waiting")) {
|
||||
mjMessage.setGenerateStatus(MidjourneyGennerateStatusEnum.WAITING.getStatus());
|
||||
} else if (mjMessage.getType() == 20 && !StrUtil.isBlank(mjMessage.getContent().getProgress())) {
|
||||
mjMessage.setGenerateStatus(MidjourneyGennerateStatusEnum.IN_PROGRESS.getStatus());
|
||||
} else if (mjMessage.getType() == 0 && !CollUtil.isEmpty(mjMessage.getComponents())) {
|
||||
mjMessage.setGenerateStatus(MidjourneyGennerateStatusEnum.COMPLETED.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean ignoreAndLogMessage(DataObject data, MidjourneyMessageTypeEnum messageType) {
|
||||
String channelId = data.getString(MidjourneyConstants.MSG_CHANNEL_ID);
|
||||
if (!CharSequenceUtil.equals(channelId, midjourneyConfig.getChannelId())) {
|
||||
return true;
|
||||
}
|
||||
String authorName = data.optObject("author").map(a -> a.getString("username")).orElse("System");
|
||||
log.debug("{} - {} - {}: {}", midjourneyConfig.getChannelId(), messageType.name(), authorName, data.opt("content").orElse(""));
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"type": 2,
|
||||
"guild_id": "$guild_id",
|
||||
"channel_id": "$channel_id",
|
||||
"application_id": "936929561302675456",
|
||||
"session_id": "$session_id",
|
||||
"nonce": "$nonce",
|
||||
"data": {
|
||||
"version": "1204231436023111690",
|
||||
"id": "1092492867185950852",
|
||||
"name": "describe",
|
||||
"type": 1,
|
||||
"options": [
|
||||
{
|
||||
"type": 11,
|
||||
"name": "image",
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
"attachments": [
|
||||
{
|
||||
"id": "0",
|
||||
"filename": "$file_name",
|
||||
"uploaded_filename": "$final_file_name"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"type": 2,
|
||||
"guild_id": "$guild_id",
|
||||
"channel_id": "$channel_id",
|
||||
"application_id": "936929561302675456",
|
||||
"session_id": "$session_id",
|
||||
"nonce": "$nonce",
|
||||
"data": {
|
||||
"version": "1237876415471554623",
|
||||
"id": "938956540159881230",
|
||||
"name": "imagine",
|
||||
"type": 1,
|
||||
"options": [
|
||||
{
|
||||
"type": 3,
|
||||
"name": "prompt",
|
||||
"value": "$prompt"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"type": 3,
|
||||
"guild_id": "$guild_id",
|
||||
"channel_id": "$channel_id",
|
||||
"message_id": "$message_id",
|
||||
"application_id": "936929561302675456",
|
||||
"session_id": "$session_id",
|
||||
"nonce": "$nonce",
|
||||
"message_flags": 0,
|
||||
"data": {
|
||||
"component_type": 2,
|
||||
"custom_id": "$custom_id"
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 17,
|
||||
"t": "MESSAGE_CREATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"nonce": "1784822781483888640",
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": null,
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (Waiting to start)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 38,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp",
|
||||
"size": 40906,
|
||||
"content_type": "image/webp",
|
||||
"width": 512,
|
||||
"placeholder_version": 1,
|
||||
"proxy_url": "https://media.discordapp.net/attachments/1234380679576424448/1234381954301038622/5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp?ex=66308747&is=662f35c7&hm=5cff8b62f6c174b45a80d096eefbea9bf791ccfb50f586734efadbd96b57a114&",
|
||||
"placeholder": "W/gJHwiCN4VoaZZ4ePd3aIeFCJacgqAG",
|
||||
"id": "1234381954301038622",
|
||||
"url": "https://cdn.discordapp.com/attachments/1234380679576424448/1234381954301038622/5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp?ex=66308747&is=662f35c7&hm=5cff8b62f6c174b45a80d096eefbea9bf791ccfb50f586734efadbd96b57a114&",
|
||||
"height": 512
|
||||
}
|
||||
],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:53:11.587132+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (75%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 39,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp",
|
||||
"size": 77746,
|
||||
"content_type": "image/webp",
|
||||
"width": 512,
|
||||
"placeholder_version": 1,
|
||||
"proxy_url": "https://media.discordapp.net/attachments/1234380679576424448/1234381963381444691/5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp?ex=66308749&is=662f35c9&hm=f87113bb4f667e56747a26812260f18b5c59f1e47991457756e77b576309534a&",
|
||||
"placeholder": "3OcJDwSASHWaWZZ4eNd2eHiGJyBMgKAG",
|
||||
"id": "1234381963381444691",
|
||||
"url": "https://cdn.discordapp.com/attachments/1234380679576424448/1234381963381444691/5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp?ex=66308749&is=662f35c9&hm=f87113bb4f667e56747a26812260f18b5c59f1e47991457756e77b576309534a&",
|
||||
"height": 512
|
||||
}
|
||||
],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:53:13.745586+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (95%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 40,
|
||||
"t": "MESSAGE_CREATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"custom_id": "MJ::JOB::upsample::1::5d32f4e8-8d2f-4bef-82d8-bf517e3c3660",
|
||||
"style": 2,
|
||||
"label": "U1",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::upsample::2::5d32f4e8-8d2f-4bef-82d8-bf517e3c3660",
|
||||
"style": 2,
|
||||
"label": "U2",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::upsample::3::5d32f4e8-8d2f-4bef-82d8-bf517e3c3660",
|
||||
"style": 2,
|
||||
"label": "U3",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::upsample::4::5d32f4e8-8d2f-4bef-82d8-bf517e3c3660",
|
||||
"style": 2,
|
||||
"label": "U4",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "\uD83D\uDD04"
|
||||
},
|
||||
"custom_id": "MJ::JOB::reroll::0::5d32f4e8-8d2f-4bef-82d8-bf517e3c3660::SOLO",
|
||||
"style": 2,
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"custom_id": "MJ::JOB::variation::1::5d32f4e8-8d2f-4bef-82d8-bf517e3c3660",
|
||||
"style": 2,
|
||||
"label": "V1",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::variation::2::5d32f4e8-8d2f-4bef-82d8-bf517e3c3660",
|
||||
"style": 2,
|
||||
"label": "V2",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::variation::3::5d32f4e8-8d2f-4bef-82d8-bf517e3c3660",
|
||||
"style": 2,
|
||||
"label": "V3",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::variation::4::5d32f4e8-8d2f-4bef-82d8-bf517e3c3660",
|
||||
"style": 2,
|
||||
"label": "V4",
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
],
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "andrakosq9211__5d32f4e8-8d2f-4bef-82d8-bf517e3c3660.png",
|
||||
"size": 8327001,
|
||||
"content_type": "image/png",
|
||||
"width": 2048,
|
||||
"placeholder_version": 1,
|
||||
"proxy_url": "https://media.discordapp.net/attachments/1234380679576424448/1234381975058514001/andrakosq9211__5d32f4e8-8d2f-4bef-82d8-bf517e3c3660.png?ex=6630874c&is=662f35cc&hm=20a8bb9b10c68645c9bd09a52b181de8566802590d070965d0a4738387781bb6&",
|
||||
"placeholder": "3dcJBwaASHWaWZZ4eNd2aHiGRwE+gLAH",
|
||||
"id": "1234381975058514001",
|
||||
"url": "https://cdn.discordapp.com/attachments/1234380679576424448/1234381975058514001/andrakosq9211__5d32f4e8-8d2f-4bef-82d8-bf517e3c3660.png?ex=6630874c&is=662f35cc&hm=20a8bb9b10c68645c9bd09a52b181de8566802590d070965d0a4738387781bb6&",
|
||||
"height": 2048
|
||||
}
|
||||
],
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 0,
|
||||
"mention_roles": [],
|
||||
"edited_timestamp": null,
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (relaxed)",
|
||||
"tts": false,
|
||||
"referenced_message": null,
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"id": "1234381975335342122",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:53:16.628000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 30,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:52:42.826454+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (0%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 31,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:52:48.793794+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (10%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 32,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:52:48.976941+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (20%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 33,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:52:54.993089+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (22%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 34,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:52:55.667426+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (32%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 35,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:53:01.235104+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (35%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 36,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp",
|
||||
"size": 43912,
|
||||
"content_type": "image/webp",
|
||||
"width": 512,
|
||||
"placeholder_version": 1,
|
||||
"proxy_url": "https://media.discordapp.net/attachments/1234380679576424448/1234381927348436992/5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp?ex=66308741&is=662f35c1&hm=eb4abbb4ede30b588e02eba7c18203177dcea82612ee981bde696346f1d887ac&",
|
||||
"placeholder": "WpcRLxZwanaXh4d4h6d2aIeG92d6hbAH",
|
||||
"id": "1234381927348436992",
|
||||
"url": "https://cdn.discordapp.com/attachments/1234380679576424448/1234381927348436992/5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp?ex=66308741&is=662f35c1&hm=eb4abbb4ede30b588e02eba7c18203177dcea82612ee981bde696346f1d887ac&",
|
||||
"height": 512
|
||||
}
|
||||
],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:53:05.164746+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (35%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 37,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp",
|
||||
"size": 27876,
|
||||
"content_type": "image/webp",
|
||||
"width": 512,
|
||||
"placeholder_version": 1,
|
||||
"proxy_url": "https://media.discordapp.net/attachments/1234380679576424448/1234381937288679506/5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp?ex=66308743&is=662f35c3&hm=ccebcb830d6e76127164767721ebf18ec3bc1e9acf8d61481b5f755e89caf8b8&",
|
||||
"placeholder": "G7cJFwqCeYiHeId5h/h2eHmU9xeHc7AG",
|
||||
"id": "1234381937288679506",
|
||||
"url": "https://cdn.discordapp.com/attachments/1234380679576424448/1234381937288679506/5d32f4e8-8d2f-4bef-82d8-bf517e3c3660_grid_0.webp?ex=66308743&is=662f35c3&hm=ccebcb830d6e76127164767721ebf18ec3bc1e9acf8d61481b5f755e89caf8b8&",
|
||||
"height": 512
|
||||
}
|
||||
],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T05:53:07.496257+00:00",
|
||||
"content": "**海贼王,在赶海! --v 6.0** - <@975372485971312700> (55%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"id": "1234381513597128715",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"id": "1234381516130357379",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:51:27.145000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 1112,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"custom_id": "MJ::CancelJob::ByJobid::a58fcee9-ec89-4471-aff3-088615fc78f2",
|
||||
"style": 4,
|
||||
"label": "Cancel Job",
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"interacted_message_id": "1234503859578081381",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234506142236020767",
|
||||
"type": 3,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 64,
|
||||
"type": 19,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T14:06:46.866376+00:00",
|
||||
"content": "**A girl from China, creator of ancient Chinese clothing, dances on the square --v 6.0 --ar 3:2** - Variations (Strong) by <@975372485971312700> (0%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"position": 0,
|
||||
"message_reference": {
|
||||
"guild_id": "1234355413420347402",
|
||||
"message_id": "1234503859578081381",
|
||||
"type": 0,
|
||||
"channel_id": "1234380679576424448"
|
||||
},
|
||||
"id": "1234506143943102605",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T14:06:40.731000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 47,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "97b1c75b-41c2-4dfe-bb7d-e61fbea8f1c7_grid_0.webp",
|
||||
"size": 71390,
|
||||
"content_type": "image/webp",
|
||||
"width": 512,
|
||||
"ephemeral": true,
|
||||
"placeholder_version": 1,
|
||||
"proxy_url": "https://media.discordapp.net/ephemeral-attachments/1234380679576424448/1234437493542359114/97b1c75b-41c2-4dfe-bb7d-e61fbea8f1c7_grid_0.webp?ex=6630bb01&is=662f6981&hm=60e610be44d3ae5fec8f1cbfb791997a627901d132a24e4364ac663362ab9a30&",
|
||||
"placeholder": "XQgKBYJ8H3aDh3eHiAeIecB0Bsl2",
|
||||
"id": "1234437493542359114",
|
||||
"url": "https://cdn.discordapp.com/ephemeral-attachments/1234380679576424448/1234437493542359114/97b1c75b-41c2-4dfe-bb7d-e61fbea8f1c7_grid_0.webp?ex=6630bb01&is=662f6981&hm=60e610be44d3ae5fec8f1cbfb791997a627901d132a24e4364ac663362ab9a30&",
|
||||
"height": 340
|
||||
}
|
||||
],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"interacted_message_id": "1234433732761620500",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234436261440126977",
|
||||
"type": 3,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 64,
|
||||
"type": 19,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T09:33:53.172018+00:00",
|
||||
"content": "**A girl from China, creator of ancient Chinese clothing, dances on the square --ar 3:2** - Pan Right by <@975372485971312700> (35%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"position": 0,
|
||||
"message_reference": {
|
||||
"guild_id": "1234355413420347402",
|
||||
"message_id": "1234433732761620500",
|
||||
"type": 0,
|
||||
"channel_id": "1234380679576424448"
|
||||
},
|
||||
"id": "1234436266045608016",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T09:29:00.542000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 5,
|
||||
"t": "MESSAGE_CREATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"custom_id": "MJ::Prompts::LLMComplaintSubmit::8d706b5c-36d9-4ef5-af2e-b778c876e39b",
|
||||
"style": 2,
|
||||
"label": "Notify developers",
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234381275448479744",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 64,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"nonce": "1784822542798630912",
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": null,
|
||||
"content": "",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [],
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"id": "1234381275448479744",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"position": 0,
|
||||
"id": "1234381284084809749",
|
||||
"embeds": [
|
||||
{
|
||||
"content_scan_version": 0,
|
||||
"color": 16711680,
|
||||
"footer": {
|
||||
"text": "/imagine 性感车模,站在车上! --v 6"
|
||||
},
|
||||
"description": "Sorry! Our AI moderator thinks this prompt is probably against our community standards.\n\nPlease review our current community standards:\n\n**ALLOWED**\n- Any image up to PG-13 rating involving fiction, fantasy, mythology.\n- Real images that may be seen as respectful or light-hearted parodies, satire, caricatures\n- Imaginary or exaggerated real-life scenarios, including absurd or humorous situations.\n\n**NOT ALLOWED**\n- Disrespectful, harmful, misleading public figures/events portrayals or potential to mislead.\n- Hate speech, explicit or real-world violence.\n- Nudity or unconsented overtly sexualized public figures.\n- Imagery that might be considered culturally insensitive\n\nThis AI system isn't perfect. If you find it rejecting something innocent please press the **Notify Developers** button and we will review it and try to further improve our performance. Thank you for your help!",
|
||||
"type": "rich",
|
||||
"title": "Banned prompt detected"
|
||||
}
|
||||
],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T05:50:31.821000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 5,
|
||||
"t": "MESSAGE_CREATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "972721304891453450",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1225608134878302329"
|
||||
},
|
||||
"id": "1234353096516173844",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "tiger",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "972721304891453450",
|
||||
"avatar": "3646118d04fd12dfd301c4fd17afd801",
|
||||
"username": "jverbalu4990",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 64,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"nonce": "1784794363249700864",
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": null,
|
||||
"content": "",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [],
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"id": "1234353096516173844",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "tiger",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "972721304891453450",
|
||||
"avatar": "3646118d04fd12dfd301c4fd17afd801",
|
||||
"username": "jverbalu4990",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"position": 0,
|
||||
"id": "1234353097535393822",
|
||||
"embeds": [
|
||||
{
|
||||
"content_scan_version": 0,
|
||||
"color": 16711680,
|
||||
"footer": {
|
||||
"text": "/imagine 中国长城 --ar 1:1 --niji 6"
|
||||
},
|
||||
"description": "You have been blocked from accessing Midjourney. This happens on repeated or serious ToS violations.",
|
||||
"type": "rich",
|
||||
"title": "Blocked"
|
||||
}
|
||||
],
|
||||
"channel_id": "1225608134878302332",
|
||||
"timestamp": "2024-04-29T03:58:31.624000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,239 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 24,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"emoji": {
|
||||
"name": "upscale_1",
|
||||
"id": "940147353879478324"
|
||||
},
|
||||
"custom_id": "MJ::JOB::upsample_v6_2x_subtle::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"label": "Upscale (Subtle)",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "upscale_1",
|
||||
"id": "940147353879478324"
|
||||
},
|
||||
"custom_id": "MJ::JOB::upsample_v6_2x_creative::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"label": "Upscale (Creative)",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "🪄"
|
||||
},
|
||||
"custom_id": "MJ::JOB::low_variation::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"label": "Vary (Subtle)",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "🪄"
|
||||
},
|
||||
"custom_id": "MJ::JOB::high_variation::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"label": "Vary (Strong)",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "🖌️"
|
||||
},
|
||||
"custom_id": "MJ::Inpaint::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"label": "Vary (Region)",
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"emoji": {
|
||||
"name": "🔍"
|
||||
},
|
||||
"custom_id": "MJ::Outpaint::50::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 4,
|
||||
"label": "Zoom Out 2x",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "🔍"
|
||||
},
|
||||
"custom_id": "MJ::Outpaint::75::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"label": "Zoom Out 1.5x",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "🔍"
|
||||
},
|
||||
"custom_id": "MJ::CustomZoom::519cd956-d02e-4ae2-b62d-17c499dbbe3f",
|
||||
"style": 2,
|
||||
"label": "Custom Zoom",
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"emoji": {
|
||||
"name": "⬅️"
|
||||
},
|
||||
"custom_id": "MJ::JOB::pan_left::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "➡️"
|
||||
},
|
||||
"custom_id": "MJ::JOB::pan_right::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "⬆️"
|
||||
},
|
||||
"custom_id": "MJ::JOB::pan_up::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "⬇️"
|
||||
},
|
||||
"custom_id": "MJ::JOB::pan_down::1::519cd956-d02e-4ae2-b62d-17c499dbbe3f::SOLO",
|
||||
"style": 2,
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"emoji": {
|
||||
"name": "❤️"
|
||||
},
|
||||
"custom_id": "MJ::BOOKMARK::519cd956-d02e-4ae2-b62d-17c499dbbe3f",
|
||||
"style": 2,
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"style": 5,
|
||||
"label": "Web",
|
||||
"type": 2,
|
||||
"url": "https://www.midjourney.com/app/jobs/519cd956-d02e-4ae2-b62d-17c499dbbe3f/"
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
],
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "andrakosq9211_A_girl_from_China_creator_of_ancient_Chinese_clot_519cd956-d02e-4ae2-b62d-17c499dbbe3f.png",
|
||||
"size": 2014189,
|
||||
"content_type": "image/png",
|
||||
"width": 1024,
|
||||
"placeholder_version": 1,
|
||||
"proxy_url": "https://media.discordapp.net/attachments/1234380679576424448/1234433732341927976/andrakosq9211_A_girl_from_China_creator_of_ancient_Chinese_clot_519cd956-d02e-4ae2-b62d-17c499dbbe3f.png?ex=6630b780&is=662f6600&hm=8f273f74c29274431ec9b02bc4778a37ee944aa5360d10875cbbe512847b71c2&",
|
||||
"placeholder": "YwgKDwKIWGiAiYd4iGh4d4h4mKz5uZwP",
|
||||
"id": "1234433732341927976",
|
||||
"url": "https://cdn.discordapp.com/attachments/1234380679576424448/1234433732341927976/andrakosq9211_A_girl_from_China_creator_of_ancient_Chinese_clot_519cd956-d02e-4ae2-b62d-17c499dbbe3f.png?ex=6630b780&is=662f6600&hm=8f273f74c29274431ec9b02bc4778a37ee944aa5360d10875cbbe512847b71c2&",
|
||||
"height": 1024
|
||||
}
|
||||
],
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 19,
|
||||
"mention_roles": [],
|
||||
"edited_timestamp": "2024-04-29T09:19:12.812177+00:00",
|
||||
"content": "**A girl from China, creator of ancient Chinese clothing, dances on the square** - Image #3 <@975372485971312700>",
|
||||
"tts": false,
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"message_reference": {
|
||||
"guild_id": "1234355413420347402",
|
||||
"message_id": "1234433346940043294",
|
||||
"type": 0,
|
||||
"channel_id": "1234380679576424448"
|
||||
},
|
||||
"id": "1234433732761620500",
|
||||
"embeds": [
|
||||
{
|
||||
"color": 16711680,
|
||||
"description": "Hey <@975372485971312700>\nYour job queue is full. Please wait for a job to finish first, then resubmit this one.\n*[Please check the bottom of the channel for more information.](https://discord.com/channels/1234355413420347402/1234380679576424448/1234433798599606315)*",
|
||||
"type": "rich",
|
||||
"url": "https://discord.com/channels/1234355413420347402/1234380679576424448/1234433798599606315"
|
||||
}
|
||||
],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T09:18:56.560000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
|
||||
# Midjourney 消息体解析
|
||||
|
||||
```text
|
||||
|
||||
{
|
||||
"op": 0,
|
||||
"s": 346,
|
||||
"t": "MESSAGE_CREATE", // 消息类型
|
||||
"d": {
|
||||
"id": "1234498661476601907", // 唯一id
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"channel_id": "1234380679576424448", // 频道id用来只区分自己频道
|
||||
"flags": 64, // flags 未知
|
||||
"type": 20, // 初步理解是用于区分消息类型
|
||||
"mention_roles": [],
|
||||
"nonce": "18", // 重点,我们传过去的唯一id,用于区分不同的绘画
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": null,
|
||||
"content": "", // 消息内容
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [],
|
||||
"components": [], // U1、U2等操作
|
||||
"attachments": [], // 生成的图片附件
|
||||
"embeds": [] // 重点异常、提示、错误 都是在这个里面,这个里面有信息这个任务就不正常
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
- t: 是消息类型(处理 create、和update)
|
||||
- MESSAGE_CREATE:会增加一条新的信息出来
|
||||
- MESSAGE_UPDATE:不会增加新的信息,在原来的信息上更新展示,比如进度条 10% 30%...
|
||||
- MESSAGE_DELETE 没啥用
|
||||
- components:可以理解为可以操作的按钮
|
||||
- 情况1:正常只有图片完成才有对于操作
|
||||
- 情况2:异常情况可以 submit 当前任务
|
||||
- attachments: 附件,在图片生成到50%左右就会开始有模糊的图片,这里面就会有照片的地址
|
||||
- content:正常的消息内容在这里面,一般会是一串字符串,一般有 prompt、版本、进度、状态/生成类型
|
||||
- 内容示例:**海贼王,在赶海! --v 6.0** - <@975372485971312700> (0%) (relaxed)
|
||||
- 内容示例:**海贼王,在赶海! --v 6.0** - <@975372485971312700> (35%) (relaxed)
|
||||
- embeds: <重点> 只有错误、警告、封号、异常里面才有信息,可以优先判断这里面有没有内容,就知道是否正常!
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
{
|
||||
"type": 2,
|
||||
"application_id": "936929561302675456",
|
||||
"guild_id": "1237948819677904956",
|
||||
"channel_id": "1237948819677904960",
|
||||
"session_id": "4bdb0c32158f625bbd7f0a54bfbb54aa",
|
||||
"data": {
|
||||
"version": "1237876415471554623",
|
||||
"id": "938956540159881230",
|
||||
"name": "imagine",
|
||||
"type": 1,
|
||||
"options": [
|
||||
{
|
||||
"type": 3,
|
||||
"name": "prompt",
|
||||
"value": "哈哈哈"
|
||||
}
|
||||
],
|
||||
"application_command": {
|
||||
"id": "938956540159881230",
|
||||
"type": 1,
|
||||
"application_id": "936929561302675456",
|
||||
"version": "1237876415471554623",
|
||||
"name": "imagine",
|
||||
"description": "Create images with Midjourney",
|
||||
"options": [
|
||||
{
|
||||
"type": 3,
|
||||
"name": "prompt",
|
||||
"description": "The prompt to imagine",
|
||||
"required": true,
|
||||
"description_localized": "The prompt to imagine",
|
||||
"name_localized": "prompt"
|
||||
}
|
||||
],
|
||||
"dm_permission": true,
|
||||
"contexts": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
"integration_types": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"global_popularity_rank": 1,
|
||||
"description_localized": "Create images with Midjourney",
|
||||
"name_localized": "imagine"
|
||||
},
|
||||
"attachments": []
|
||||
},
|
||||
"nonce": "1238062212925358080",
|
||||
"analytics_location": "slash_ui"
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 119,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"interacted_message_id": "1234430088515293194",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234430127618658305",
|
||||
"type": 3,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 64,
|
||||
"type": 19,
|
||||
"mention_roles": [],
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": "2024-04-29T09:06:37.616666+00:00",
|
||||
"content": "**A girl from China, creator of ancient Chinese clothing, dances on the square** - Zoom Out by <@975372485971312700> (22%) (relaxed)",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"position": 0,
|
||||
"message_reference": {
|
||||
"guild_id": "1234355413420347402",
|
||||
"message_id": "1234430088515293194",
|
||||
"type": 0,
|
||||
"channel_id": "1234380679576424448"
|
||||
},
|
||||
"id": "1234430128721887272",
|
||||
"embeds": [],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T09:04:37.290000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 5,
|
||||
"t": "MESSAGE_CREATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "975372485971312700",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234355413420347402"
|
||||
},
|
||||
"id": "1234425115912179745",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 64,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"nonce": "1234425114066419712",
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": null,
|
||||
"content": "",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [],
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"id": "1234425115912179745",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"position": 0,
|
||||
"id": "1234425117380182102",
|
||||
"embeds": [
|
||||
{
|
||||
"content_scan_version": 0,
|
||||
"color": 16239475,
|
||||
"footer": {
|
||||
"text": "/imagine Cartoon car"
|
||||
},
|
||||
"description": "You have reached the maximum allowed number of concurrent jobs. Don't worry, this job will start as soon as another one finishes!",
|
||||
"type": "rich",
|
||||
"title": "Job queued"
|
||||
}
|
||||
],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T08:44:42.493000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 1861,
|
||||
"t": "MESSAGE_UPDATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"custom_id": "MJ::JOB::upsample::1::a58fcee9-ec89-4471-aff3-088615fc78f2",
|
||||
"style": 2,
|
||||
"label": "U1",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::upsample::2::a58fcee9-ec89-4471-aff3-088615fc78f2",
|
||||
"style": 2,
|
||||
"label": "U2",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::upsample::3::a58fcee9-ec89-4471-aff3-088615fc78f2",
|
||||
"style": 2,
|
||||
"label": "U3",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::upsample::4::a58fcee9-ec89-4471-aff3-088615fc78f2",
|
||||
"style": 2,
|
||||
"label": "U4",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"emoji": {
|
||||
"name": "🔄"
|
||||
},
|
||||
"custom_id": "MJ::JOB::reroll::0::a58fcee9-ec89-4471-aff3-088615fc78f2::SOLO",
|
||||
"style": 1,
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"custom_id": "MJ::JOB::variation::1::a58fcee9-ec89-4471-aff3-088615fc78f2",
|
||||
"style": 2,
|
||||
"label": "V1",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::variation::2::a58fcee9-ec89-4471-aff3-088615fc78f2",
|
||||
"style": 2,
|
||||
"label": "V2",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::variation::3::a58fcee9-ec89-4471-aff3-088615fc78f2",
|
||||
"style": 2,
|
||||
"label": "V3",
|
||||
"type": 2
|
||||
},
|
||||
{
|
||||
"custom_id": "MJ::JOB::variation::4::a58fcee9-ec89-4471-aff3-088615fc78f2",
|
||||
"style": 2,
|
||||
"label": "V4",
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
],
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "andrakosq9211_A_girl_from_China_creator_of_ancient_Chinese_clot_a58fcee9-ec89-4471-aff3-088615fc78f2.png",
|
||||
"size": 8558317,
|
||||
"content_type": "image/png",
|
||||
"width": 2688,
|
||||
"placeholder_version": 1,
|
||||
"proxy_url": "https://media.discordapp.net/attachments/1234380679576424448/1234506591949291592/andrakosq9211_A_girl_from_China_creator_of_ancient_Chinese_clot_a58fcee9-ec89-4471-aff3-088615fc78f2.png?ex=6630fb5b&is=662fa9db&hm=ce38fbb4da6acca7a545fadf53f1bfaa3096e04fe68d24750104a2e66719f84d&",
|
||||
"placeholder": "YAgGBYBYFZeDa5eHegdnZ/3Erv7s",
|
||||
"id": "1234506591949291592",
|
||||
"url": "https://cdn.discordapp.com/attachments/1234380679576424448/1234506591949291592/andrakosq9211_A_girl_from_China_creator_of_ancient_Chinese_clot_a58fcee9-ec89-4471-aff3-088615fc78f2.png?ex=6630fb5b&is=662fa9db&hm=ce38fbb4da6acca7a545fadf53f1bfaa3096e04fe68d24750104a2e66719f84d&",
|
||||
"height": 1792
|
||||
}
|
||||
],
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 0,
|
||||
"type": 19,
|
||||
"mention_roles": [],
|
||||
"edited_timestamp": "2024-04-29T14:16:39.564000+00:00",
|
||||
"content": "**A girl from China, creator of ancient Chinese clothing, dances on the square --v 6.0 --ar 3:2** - Variations (Strong) by <@975372485971312700> (relaxed)",
|
||||
"tts": false,
|
||||
"mentions": [
|
||||
{
|
||||
"global_name": "禁止挂软件刷图,逮到删服务器,踢设备,永久拉黑!!!",
|
||||
"avatar_decoration_data": null,
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:07:43.807000+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "975372485971312700",
|
||||
"avatar": "90ab939feddeaea32e23d066ce66d0e6",
|
||||
"username": "andrakosq9211",
|
||||
"discriminator": "0"
|
||||
}
|
||||
],
|
||||
"member": {
|
||||
"premium_since": null,
|
||||
"nick": null,
|
||||
"joined_at": "2024-04-29T04:09:06.489349+00:00",
|
||||
"communication_disabled_until": null,
|
||||
"roles": [
|
||||
"1234355760184561747"
|
||||
],
|
||||
"pending": false,
|
||||
"flags": 0,
|
||||
"deaf": false,
|
||||
"mute": false,
|
||||
"avatar": null
|
||||
},
|
||||
"guild_id": "1234355413420347402",
|
||||
"position": 0,
|
||||
"message_reference": {
|
||||
"guild_id": "1234355413420347402",
|
||||
"message_id": "1234503859578081381",
|
||||
"type": 0,
|
||||
"channel_id": "1234380679576424448"
|
||||
},
|
||||
"id": "1234506592565596251",
|
||||
"embeds": [
|
||||
{
|
||||
"color": 16711680,
|
||||
"description": "Hey <@975372485971312700>\nYour job queue is full. Please wait for a job to finish first, then resubmit this one.\n*[Please check the bottom of the channel for more information.](https://discord.com/channels/1234355413420347402/1234380679576424448/1234508653562826822)*",
|
||||
"type": "rich",
|
||||
"url": "https://discord.com/channels/1234355413420347402/1234380679576424448/1234508653562826822"
|
||||
}
|
||||
],
|
||||
"channel_id": "1234380679576424448",
|
||||
"timestamp": "2024-04-29T14:08:27.691000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 34,
|
||||
"t": "MESSAGE_CREATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"custom_id": "MJ::Job::Retry::64a7ec94-9607-492e-99ac-8550a4e7faf2",
|
||||
"style": 2,
|
||||
"label": "Resubmit",
|
||||
"type": 2
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "976067621160108072",
|
||||
"name": "imagine",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1234483730148626542"
|
||||
},
|
||||
"id": "1234491017005105172",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "Sequoiab",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "976067621160108072",
|
||||
"avatar": "2ef47ed59695ff8bcdc2254f5189b70c",
|
||||
"username": "sequoiab2281",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 64,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"nonce": "1234491015356743680",
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": null,
|
||||
"content": "",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [],
|
||||
"interaction": {
|
||||
"name": "imagine",
|
||||
"id": "1234491017005105172",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "Sequoiab",
|
||||
"avatar_decoration_data": null,
|
||||
"clan": null,
|
||||
"public_flags": 0,
|
||||
"id": "976067621160108072",
|
||||
"avatar": "2ef47ed59695ff8bcdc2254f5189b70c",
|
||||
"username": "sequoiab2281",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"position": 0,
|
||||
"id": "1234491019211575376",
|
||||
"embeds": [
|
||||
{
|
||||
"content_scan_version": 0,
|
||||
"color": 16711680,
|
||||
"footer": {
|
||||
"text": "/imagine Doctor Strange vs. Ultraman --v 6"
|
||||
},
|
||||
"description": "Your job queue is full. Please wait for a job to finish first, then resubmit this one.",
|
||||
"type": "rich",
|
||||
"title": "Queue full"
|
||||
}
|
||||
],
|
||||
"channel_id": "1234490728575533057",
|
||||
"timestamp": "2024-04-29T13:06:34.714000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
{
|
||||
"type": 2,
|
||||
"application_id": "936929561302675456",
|
||||
"guild_id": "1221445697157468200",
|
||||
"channel_id": "1221445862962630706",
|
||||
"session_id": "696318caed5180a2210e358e44801449",
|
||||
"data": {
|
||||
"version": "1166847114203123795",
|
||||
"id": "938956540159881230",
|
||||
"name": "imagine",
|
||||
"type": 1,
|
||||
"options": [
|
||||
{
|
||||
"type": 3,
|
||||
"name": "prompt",
|
||||
"value": "童话世界应该是什么样?"
|
||||
}
|
||||
],
|
||||
"application_command": {
|
||||
"id": "938956540159881230",
|
||||
"type": 1,
|
||||
"application_id": "936929561302675456",
|
||||
"version": "1166847114203123795",
|
||||
"name": "imagine",
|
||||
"description": "Create images with Midjourney",
|
||||
"options": [
|
||||
{
|
||||
"type": 3,
|
||||
"name": "prompt",
|
||||
"description": "The prompt to imagine",
|
||||
"required": true,
|
||||
"description_localized": "The prompt to imagine",
|
||||
"name_localized": "prompt"
|
||||
}
|
||||
],
|
||||
"dm_permission": true,
|
||||
"integration_types": [
|
||||
0
|
||||
],
|
||||
"global_popularity_rank": 1,
|
||||
"description_localized": "Create images with Midjourney",
|
||||
"name_localized": "imagine"
|
||||
},
|
||||
"attachments": []
|
||||
},
|
||||
"nonce": "1224342266261274624",
|
||||
"analytics_location": "slash_ui"
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"type": 3,
|
||||
"nonce": "1224397626158350336",
|
||||
"guild_id": "1224337694918971392",
|
||||
"channel_id": "1224337694918971396",
|
||||
"message_flags": 64,
|
||||
"message_id": "1224397599197368330",
|
||||
"application_id": "936929561302675456",
|
||||
"session_id": "0d9ae3c799f2fb55ff435df5e6deb121",
|
||||
"data": {
|
||||
"component_type": 2,
|
||||
"custom_id": "MJ::ModMsg::Ack::2744093999977583880"
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
{
|
||||
"op": 0,
|
||||
"s": 10,
|
||||
"t": "MESSAGE_CREATE",
|
||||
"d": {
|
||||
"mention_everyone": false,
|
||||
"pinned": false,
|
||||
"components": [],
|
||||
"attachments": [],
|
||||
"interaction_metadata": {
|
||||
"user_id": "972721304891453450",
|
||||
"name": "blend",
|
||||
"authorizing_integration_owners": {
|
||||
"0": "1225608134878302329"
|
||||
},
|
||||
"id": "1226901083708723310",
|
||||
"type": 2
|
||||
},
|
||||
"author": {
|
||||
"global_name": null,
|
||||
"bot": true,
|
||||
"avatar_decoration_data": null,
|
||||
"public_flags": 589824,
|
||||
"id": "936929561302675456",
|
||||
"avatar": "f6ce562a6b4979c4b1cbc5b436d3be76",
|
||||
"username": "Midjourney Bot",
|
||||
"discriminator": "9282"
|
||||
},
|
||||
"flags": 64,
|
||||
"type": 20,
|
||||
"mention_roles": [],
|
||||
"nonce": "1226901080604934144",
|
||||
"application_id": "936929561302675456",
|
||||
"edited_timestamp": null,
|
||||
"content": "",
|
||||
"tts": false,
|
||||
"webhook_id": "936929561302675456",
|
||||
"mentions": [],
|
||||
"interaction": {
|
||||
"name": "blend",
|
||||
"id": "1226901083708723310",
|
||||
"type": 2,
|
||||
"user": {
|
||||
"global_name": "tiger",
|
||||
"avatar_decoration_data": null,
|
||||
"public_flags": 0,
|
||||
"id": "972721304891453450",
|
||||
"avatar": "3646118d04fd12dfd301c4fd17afd801",
|
||||
"username": "jverbalu4990",
|
||||
"discriminator": "0"
|
||||
}
|
||||
},
|
||||
"position": 0,
|
||||
"id": "1226901087286591558",
|
||||
"embeds": [
|
||||
{
|
||||
"content_scan_version": 0,
|
||||
"color": 16239475,
|
||||
"footer": {
|
||||
"text": "/imagine https://cdn.discordapp.com/ephemeral-attachments/1062880104792997970/1226901079514419221/srchttp___c-ssl.duitang.com_uploads_item_202001_20_20200120152231_lncpq.thumb.1000_0.jpgreferhttp___c-ssl.duitang.webp?ex=662673ac&is=6613feac&hm=bf9a400940c747fa869b8e4bf2a38238639b67b4b5e799ce1ef2c1f42bab178f& https://cdn.discordapp.com/ephemeral-attachments/1062880104792997970/1226901080970100736/xiyangyang20151021171455974.png?ex=662673ac&is=6613feac&hm=9c8f42ad2dfb1963a9e424c1942c59568544faed4d38f94b678bfcaa60f47b04& --v 5.2 --s 250"
|
||||
},
|
||||
"description": "You have reached the maximum allowed number of concurrent jobs. Don't worry, this job will start as soon as another one finishes!",
|
||||
"type": "rich",
|
||||
"title": "Job queued"
|
||||
}
|
||||
],
|
||||
"channel_id": "1225608134878302332",
|
||||
"timestamp": "2024-04-08T14:26:53.929000+00:00"
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.ai.midjourney;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyConfig;
|
||||
import org.springframework.ai.models.midjourney.api.MidjourneyInteractionsApi;
|
||||
import org.springframework.ai.models.midjourney.api.req.AttachmentsReq;
|
||||
import org.springframework.ai.models.midjourney.api.req.DescribeReq;
|
||||
import org.springframework.ai.models.midjourney.api.req.ReRollReq;
|
||||
import org.springframework.ai.models.midjourney.api.res.UploadAttachmentsRes;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* mj
|
||||
*
|
||||
* author: fansili
|
||||
* time: 2024/4/4 18:59
|
||||
*/
|
||||
public class MidjourneyInteractionsTests {
|
||||
|
||||
private MidjourneyConfig midjourneyConfig;
|
||||
@Before
|
||||
public void setup() {
|
||||
String token = "OTcyNzIxMzA0ODkxNDUzNDUw.G_vMOz.BO_Q0sXAD80u5ZKIHPNYDTRX_FgeKL3cKFc53I";
|
||||
Map<String, String> requestTemplates = new HashMap<>();
|
||||
List<File> files = FileUtil.loopFiles("/Users/fansili/projects/github/ruoyi-vue-pro/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/resources/http-body");
|
||||
for (File file : files) {
|
||||
requestTemplates.put(file.getName().replace(".json", ""), FileUtil.readUtf8String(file));
|
||||
}
|
||||
this.midjourneyConfig = new MidjourneyConfig(token, "1225608134878302329", "1225608134878302332", requestTemplates);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mjImageTest() {
|
||||
MidjourneyInteractionsApi mjImagineInteractions = new MidjourneyInteractionsApi(midjourneyConfig);
|
||||
mjImagineInteractions.imagine(String.valueOf(IdUtil.getSnowflakeNextId()), "童话里应该是什么样子?");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void reRollTest() {
|
||||
MidjourneyInteractionsApi mjImagineInteractions = new MidjourneyInteractionsApi(midjourneyConfig);
|
||||
mjImagineInteractions.reRoll(new ReRollReq()
|
||||
.setMessageId("1226165117448753243")
|
||||
.setCustomId("MJ::JOB::upsample::3::2aeefbef-43e2-4057-bcf1-43b5f39ab6f7"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uploadAttachmentsTest() {
|
||||
MidjourneyInteractionsApi mjImagineInteractions = new MidjourneyInteractionsApi(midjourneyConfig);
|
||||
UploadAttachmentsRes res = mjImagineInteractions.uploadAttachments(
|
||||
new AttachmentsReq().setFileSystemResource(
|
||||
new FileSystemResource(new File("/Users/fansili/Downloads/DSC01402.JPG")))
|
||||
);
|
||||
System.err.println(JsonUtils.toJsonString(res));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describeTest() {
|
||||
MidjourneyInteractionsApi mjImagineInteractions = new MidjourneyInteractionsApi(midjourneyConfig);
|
||||
mjImagineInteractions.describe(new DescribeReq()
|
||||
.setFileName("DSC01402.JPG")
|
||||
.setFinalFileName("16826931-2873-45ec-8cfb-0ad81f1a075f/DSC01402.JPG")
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.ai.midjourney;
|
||||
|
||||
import org.springframework.ai.models.midjourney.util.MidjourneyUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* mj util
|
||||
*
|
||||
* author: fansili
|
||||
* time: 2024/4/6 21:57
|
||||
*/
|
||||
public class MidjourneyUtilTests {
|
||||
|
||||
@Test
|
||||
public void parseContentTest() {
|
||||
String content1 = "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (32%) (fast, stealth)";
|
||||
String content2 = "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (fast, stealth)";
|
||||
|
||||
System.err.println(MidjourneyUtil.parseContent(content1));
|
||||
System.err.println(MidjourneyUtil.parseContent(content2));
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.ai.midjourney;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import org.springframework.ai.models.midjourney.MidjourneyConfig;
|
||||
import org.springframework.ai.models.midjourney.webSocket.WssNotify;
|
||||
import org.springframework.ai.models.midjourney.webSocket.listener.MidjourneyMessageListener;
|
||||
import org.springframework.ai.models.midjourney.webSocket.MidjourneyWebSocketStarter;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* author: fansili
|
||||
* time: 2024/4/3 16:40
|
||||
*/
|
||||
public class MidjourneyWebSocketTests {
|
||||
|
||||
private MidjourneyConfig midjourneyConfig;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
String token = "OTcyNzIxMzA0ODkxNDUzNDUw.G_vMOz.BO_Q0sXAD80u5ZKIHPNYDTRX_FgeKL3cKFc53I";
|
||||
Map<String, String> requestTemplates = new HashMap<>();
|
||||
List<File> files = FileUtil.loopFiles("/Users/fansili/projects/github/ruoyi-vue-pro/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/resources/http-body");
|
||||
for (File file : files) {
|
||||
requestTemplates.put(file.getName().replace(".json", ""), FileUtil.readUtf8String(file));
|
||||
}
|
||||
this.midjourneyConfig = new MidjourneyConfig(token, "1225608134878302329", "1225608134878302332", requestTemplates);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startSocketTest() {
|
||||
String wssUrl = "wss://gateway.discord.gg";
|
||||
var messageListener = new MidjourneyMessageListener(midjourneyConfig);
|
||||
var webSocketStarter = new MidjourneyWebSocketStarter(wssUrl, null, midjourneyConfig, messageListener);
|
||||
|
||||
try {
|
||||
webSocketStarter.start(new WssNotify() {
|
||||
@Override
|
||||
public void notify(int code, String message) {
|
||||
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
scanner.nextLine();
|
||||
}
|
||||
}
|
|
@ -1,15 +1,11 @@
|
|||
package cn.iocoder.yudao.framework.ai.openAiImage;
|
||||
package cn.iocoder.yudao.framework.ai.openai;
|
||||
|
||||
import org.springframework.ai.image.ImagePrompt;
|
||||
import org.springframework.ai.image.ImageResponse;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ai.openai.OpenAiChatClient;
|
||||
import org.springframework.ai.openai.OpenAiImageClient;
|
||||
import org.springframework.ai.openai.OpenAiImageOptions;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.openai.api.OpenAiImageApi;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
|
@ -18,7 +14,6 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
import java.util.Scanner;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* author: fansili
|
|
@ -1,5 +0,0 @@
|
|||
/**
|
||||
* author: fansili
|
||||
* time: 2024/3/12 21:03
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.ai;
|
Loading…
Reference in New Issue