diff --git a/gradle.properties b/gradle.properties
index d9dfb9e..4280de8 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
## Core
-VERSION = 0.7.0.7
+VERSION = 0.7.0.8
# dependencies
diff --git a/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java b/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java
index f97e70e..9536859 100644
--- a/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java
+++ b/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java
@@ -4,6 +4,6 @@ package cc.sukazyo.cono.morny;
* the final field that will be updated by gradle automatically.
*/
public class GradleProjectConfigures {
- public static final String VERSION = "0.7.0.7";
- public static final long COMPILE_TIMESTAMP = 1653044177443L;
+ public static final String VERSION = "0.7.0.8";
+ public static final long COMPILE_TIMESTAMP = 1653132713941L;
}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java
index 2f62796..53d6c72 100644
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java
@@ -13,6 +13,7 @@ public class EventListeners {
public static final OnEventHackHandle EVENT_HACK_HANDLE = new OnEventHackHandle();
public static final OnKuohuanhuanNeedSleep KUOHUANHUAN_NEED_SLEEP = new OnKuohuanhuanNeedSleep();
public static final OnUserRandoms USER_RANDOMS = new OnUserRandoms();
+ public static final OnCallMsgSend CALL_MSG_SEND = new OnCallMsgSend();
public static void registerAllListeners () {
EventListenerManager.addListener(
@@ -24,6 +25,7 @@ public class EventListeners {
USER_SLASH_ACTION,
INLINE_QUERY,
CALL_ME,
+ CALL_MSG_SEND,
EVENT_HACK_HANDLE
);
}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMsgSend.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMsgSend.java
new file mode 100644
index 0000000..e54a443
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMsgSend.java
@@ -0,0 +1,215 @@
+package cc.sukazyo.cono.morny.bot.event;
+
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.pengrad.telegrambot.model.Chat;
+import com.pengrad.telegrambot.model.Message;
+import com.pengrad.telegrambot.model.MessageEntity;
+import com.pengrad.telegrambot.model.Update;
+import com.pengrad.telegrambot.model.request.ParseMode;
+import com.pengrad.telegrambot.request.GetChat;
+import com.pengrad.telegrambot.request.SendMessage;
+import com.pengrad.telegrambot.request.SendSticker;
+
+import cc.sukazyo.cono.morny.MornyCoeur;
+import cc.sukazyo.cono.morny.bot.api.EventListener;
+import cc.sukazyo.cono.morny.data.TelegramStickers;
+import com.pengrad.telegrambot.response.GetChatResponse;
+import com.pengrad.telegrambot.response.SendResponse;
+
+import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
+
+public class OnCallMsgSend extends EventListener {
+
+ private static final Pattern REGEX_MSG_SENDREQ_DATA_HEAD = Pattern.compile("^\\*msg([\\d-]+)(\\*\\S+)?\\n([\\s\\S]+)$");
+
+ private record MessageToSend (
+ String message,
+ MessageEntity[] entities,
+ ParseMode parseMode,
+ long targetId
+ ) { }
+
+ @Override
+ public boolean onMessage(Update update) {
+
+ // 执行体检查
+ if (update.message().chat().type() != Chat.Type.Private) return false;
+ if (update.message().text() == null) return false;
+ if (!update.message().text().startsWith("*msg")) return false;
+
+ // 权限检查
+ if (!MornyCoeur.trustedInstance().isTrusted(update.message().from().id())) {
+ MornyCoeur.extra().exec(new SendSticker(
+ update.message().chat().id(),
+ TelegramStickers.ID_403
+ ).replyToMessageId(update.message().messageId()));
+ return true;
+ }
+
+ Message msgsendReqRaw; // 用户书写的发送请求原文
+ MessageToSend msgsendReqBody; // 解析后的发送请求实例
+
+ // *msgsend 发送标识
+ // 处理发送要求
+ if (update.message().text().equals("*msgsend")) {
+ // 发送体处理
+ if (update.message().replyToMessage() == null) return answer404(update);
+ msgsendReqBody = parseRequest(update.message().replyToMessage());
+ if (msgsendReqBody == null) return answer404(update);
+ // 执行发送任务
+ SendResponse sendResponse = MornyCoeur.getAccount().execute(parseMessageToSend(msgsendReqBody));
+ if (!sendResponse.isOk()) { // 发送失败
+ MornyCoeur.extra().exec(new SendMessage(
+ update.message().chat().id(),
+ String.format("""
+ %d FAILED
+ %s
""",
+ sendResponse.errorCode(),
+ sendResponse.description()
+ )
+ ).replyToMessageId(update.message().messageId()).parseMode(ParseMode.HTML));
+ }
+ return true;
+ // 发送完成/失败 - 事件结束
+ }
+
+ // *msg 检查标识
+ if (update.message().text().equals("*msg")) { // 处理对曾经的原文的检查
+ if (update.message().replyToMessage() == null) {
+ return answer404(update);
+ }
+ msgsendReqRaw = update.message().replyToMessage();
+ } else if (update.message().text().startsWith("*msg")) { // 对接受到的原文进行检查
+ msgsendReqRaw = update.message();
+ } else {
+ return answer404(update); // 未定义的动作
+ }
+
+ // 对发送请求的用户原文进行解析
+ msgsendReqBody = parseRequest(msgsendReqRaw);
+ if (msgsendReqBody == null) {
+ return answer404(update);
+ }
+
+ // 输出发送目标信息
+ GetChatResponse targetChatReq = MornyCoeur.getAccount().execute(new GetChat(msgsendReqBody.targetId()));
+ if (!targetChatReq.isOk()) {
+ MornyCoeur.extra().exec(new SendMessage(
+ update.message().chat().id(),
+ String.format("""
+ %d FAILED
+ %s
""",
+ targetChatReq.errorCode(),
+ targetChatReq.description()
+ )
+ ).replyToMessageId(update.message().messageId()).parseMode(ParseMode.HTML));
+ } {
+ MornyCoeur.extra().exec(new SendMessage(
+ update.message().chat().id(),
+ targetChatReq.chat().type()== Chat.Type.Private ? (
+ String.format("""
+ %d@%s
+ 🔒 %s %s""",
+ msgsendReqBody.targetId(),
+ escapeHtml(targetChatReq.chat().type().name()),
+ escapeHtml(targetChatReq.chat().firstName()+(targetChatReq.chat().lastName()==null?"":" "+targetChatReq.chat().lastName())),
+ targetChatReq.chat().username()==null?
+ String.format("@@", targetChatReq.chat().id()):
+ (escapeHtml("@"+targetChatReq.chat().username()))
+ )
+ ) : (
+ String.format("""
+ %d@%s:::
+ %s %s%s""",
+ msgsendReqBody.targetId(),
+ escapeHtml(targetChatReq.chat().type().name()),
+ switch (targetChatReq.chat().type()) {
+ case group -> "💭";
+ case channel -> "📢";
+ case supergroup -> "💬";
+ default -> "⭕️";
+ },
+ escapeHtml(targetChatReq.chat().title()),
+ targetChatReq.chat().username() != null?String.format(
+ " @%s", escapeHtml(targetChatReq.chat().username())
+ ):""
+ )
+ )
+ ).replyToMessageId(update.message().messageId()).parseMode(ParseMode.HTML));
+ }
+ // 发送文本测试
+ SendResponse testSendResp = MornyCoeur.getAccount().execute(
+ parseMessageToSend(msgsendReqBody, update.message().chat().id()).replyToMessageId(update.message().messageId())
+ );
+ if (!testSendResp.isOk()) {
+ MornyCoeur.extra().exec(new SendMessage(
+ update.message().chat().id(),
+ String.format("""
+ %d FAILED
+ %s
""",
+ testSendResp.errorCode(),
+ testSendResp.description()
+ )
+ ).replyToMessageId(update.message().messageId()).parseMode(ParseMode.HTML));
+ }
+
+ return true;
+
+ }
+
+ @Nullable
+ private static MessageToSend parseRequest (@Nonnull Message requestBody) {
+
+ final Matcher matcher = REGEX_MSG_SENDREQ_DATA_HEAD.matcher(requestBody.text());
+ if (matcher.matches()) {
+ long targetId = Long.parseLong(matcher.group(1));
+ ParseMode parseMode = matcher.group(2) == null ? null : switch (matcher.group(2)) {
+ case "*markdown", "*md", "*m↓" -> ParseMode.MarkdownV2;
+ case "*md1" -> ParseMode.Markdown;
+ case "*html" -> ParseMode.HTML;
+ default -> null;
+ };
+ final int offset = "*msg".length()+matcher.group(1).length()+(matcher.group(2)==null?0:matcher.group(2).length())+1;
+ final ArrayList entities = new ArrayList<>();
+ if (requestBody.entities() != null) for (MessageEntity entity : requestBody.entities()) {
+ final MessageEntity parsed = new MessageEntity(entity.type(), entity.offset() - offset, entity.length());
+ if (entity.url() != null) parsed.url(entity.url());
+ if (entity.user() != null) parsed.user(entity.user());
+ if (entity.language() != null) parsed.language(entity.language());
+ entities.add(parsed);
+ }
+ return new MessageToSend(matcher.group(3), entities.toArray(MessageEntity[]::new), parseMode, targetId);
+ }
+
+ return null;
+
+ }
+
+ @Nonnull
+ private static SendMessage parseMessageToSend (@Nonnull MessageToSend body) {
+ return parseMessageToSend(body, body.targetId);
+ }
+
+ @Nonnull
+ private static SendMessage parseMessageToSend (@Nonnull MessageToSend body, long targetId) {
+ SendMessage sendingBody = new SendMessage(targetId, body.message);
+ if (body.entities != null) sendingBody.entities(body.entities);
+ if (body.parseMode != null) sendingBody.parseMode(body.parseMode);
+ return sendingBody;
+ }
+
+ private static boolean answer404 (@Nonnull Update update) {
+ MornyCoeur.extra().exec(new SendSticker(
+ update.message().chat().id(),
+ TelegramStickers.ID_404
+ ).replyToMessageId(update.message().messageId()));
+ return true;
+ }
+
+}