├── .github ├── FUNDING.yml └── workflows │ ├── maven-test.yml │ └── release.yml ├── .gitignore ├── LICENSE ├── README.md ├── docs ├── action.md ├── event.md ├── imgs │ ├── img.png │ ├── img_1.png │ └── img_2.png ├── message.md ├── network.md ├── readme.md └── v2.md ├── pom.xml └── src ├── main └── java │ └── io │ └── github │ └── kloping │ └── qqbot │ ├── HttpClientConfig.java │ ├── Resource.java │ ├── Start0.java │ ├── Starter.java │ ├── api │ ├── AtAble.java │ ├── BotContent.java │ ├── DeleteAble.java │ ├── DirectSender.java │ ├── Intents.java │ ├── OpAble.java │ ├── Reactive.java │ ├── SendAble.java │ ├── Sender.java │ ├── SenderAndCidMidGetter.java │ ├── SenderV2.java │ ├── SessionCreator.java │ ├── event │ │ ├── ChannelEvent.java │ │ ├── ChannelUpdateEvent.java │ │ ├── ConnectedEvent.java │ │ ├── Event.java │ │ ├── GuildEvent.java │ │ ├── GuildUpdateEvent.java │ │ ├── InterActionEvent.java │ │ ├── MemberUpdateEvent.java │ │ └── ReactionEvent.java │ ├── exc │ │ └── RequestException.java │ ├── message │ │ ├── Builder.java │ │ ├── MessageChannelReceiveEvent.java │ │ ├── MessageContainsAtEvent.java │ │ ├── MessageDeleteEvent.java │ │ ├── MessageDirectReceiveEvent.java │ │ ├── MessageEvent.java │ │ ├── MessageReactionEvent.java │ │ ├── MessageReceiveEvent.java │ │ └── Pinsble.java │ └── v2 │ │ ├── FriendAdd.java │ │ ├── FriendEvent.java │ │ ├── FriendMessageEvent.java │ │ ├── GroupEvent.java │ │ ├── GroupMessageEvent.java │ │ ├── GroupOpRobotEvent.java │ │ ├── MessageV2Event.java │ │ └── V2Event.java │ ├── entities │ ├── Bot.java │ ├── Pack.java │ ├── ex │ │ ├── At.java │ │ ├── AtAll.java │ │ ├── BaseKeyVals.java │ │ ├── ChannelData.java │ │ ├── Image.java │ │ ├── Keyboard.java │ │ ├── Markdown.java │ │ ├── MessageAsyncBuilder.java │ │ ├── MessagePre.java │ │ ├── MessagePreBuilder.java │ │ ├── PlainText.java │ │ ├── enums │ │ │ └── EnvType.java │ │ └── msg │ │ │ └── MessageChain.java │ ├── exc │ │ └── QBotError.java │ ├── exceptions │ │ └── ImageUploadFailedException.java │ └── qqpd │ │ ├── Channel.java │ │ ├── ChannelType.java │ │ ├── Common.java │ │ ├── Dms.java │ │ ├── DmsRequest.java │ │ ├── Guild.java │ │ ├── InterAction.java │ │ ├── Member.java │ │ ├── MemberWithGuildID.java │ │ ├── PinsMessage.java │ │ ├── Role.java │ │ ├── Roles.java │ │ ├── User.java │ │ ├── data │ │ └── Emoji.java │ │ ├── message │ │ ├── DirectMessage.java │ │ ├── EmojiReaction.java │ │ ├── MessageAttachment.java │ │ ├── MessagePack.java │ │ ├── MessageReference.java │ │ ├── RawMessage.java │ │ ├── RawPreMessage.java │ │ └── audited │ │ │ ├── MessageAudit.java │ │ │ ├── MessageAuditData.java │ │ │ └── MessageAudited.java │ │ └── v2 │ │ ├── Contact.java │ │ ├── Friend.java │ │ ├── Group.java │ │ └── Member.java │ ├── http │ ├── AuthV2Base.java │ ├── BaseV2.java │ ├── BotBase.java │ ├── ChannelBase.java │ ├── DmsBase.java │ ├── GroupBaseV2.java │ ├── GuildBase.java │ ├── InterActionBase.java │ ├── MemberBase.java │ ├── MessageBase.java │ ├── UserBase.java │ ├── UserBaseV2.java │ └── data │ │ ├── ActionResult.java │ │ ├── MutePack.java │ │ ├── Result.java │ │ ├── Token.java │ │ ├── UrlPack.java │ │ ├── V2MsgData.java │ │ └── V2Result.java │ ├── impl │ ├── BaseChannelEvent.java │ ├── BaseChannelUpdateEvent.java │ ├── BaseConnectedEvent.java │ ├── BaseGuildEvent.java │ ├── BaseGuildUpdateEvent.java │ ├── BaseInterActionEvent.java │ ├── BaseMemberRemoveEvent.java │ ├── BaseMemberUpdateEvent.java │ ├── ListenerHost.java │ ├── MessagePacket.java │ ├── exc │ │ ├── InvalidRequestException.java │ │ └── TokenExpireException.java │ ├── message │ │ ├── BaseMessageChannelReceiveEvent.java │ │ ├── BaseMessageContainsAtEvent.java │ │ ├── BaseMessageDeleteEvent.java │ │ ├── BaseMessageDirectReceiveEvent.java │ │ ├── BaseMessageEvent.java │ │ ├── BaseMessageReactionEvent.java │ │ ├── BaseMessageReceiveEvent.java │ │ └── v2 │ │ │ ├── BaseFriendAdd.java │ │ │ ├── BaseFriendEvent.java │ │ │ ├── BaseFriendMessageEvent.java │ │ │ ├── BaseGroupAddRobotEvent.java │ │ │ ├── BaseGroupDelRobotEvent.java │ │ │ ├── BaseGroupEvent.java │ │ │ ├── BaseGroupMessageEvent.java │ │ │ ├── BaseGroupOpRobotEvent.java │ │ │ └── BaseMessageEvent.java │ └── registers │ │ ├── ChannelEventsRegister.java │ │ ├── FriendEventsRegister.java │ │ ├── GroupEventsRegister.java │ │ ├── GroupRobotEventRegister.java │ │ ├── GuildEventsRegister.java │ │ ├── InterActionEventRegister.java │ │ ├── MemberEventRegisters.java │ │ ├── MessageDeleteEventRegister.java │ │ ├── MessageEventsRegister.java │ │ └── MessageReactionEventRegister.java │ ├── interfaces │ ├── ImageUploadInterceptor.java │ ├── OnCloseListener.java │ └── OnPackReceive.java │ ├── network │ ├── AuthAndHeartbeat.java │ ├── Events.java │ ├── WebSocketListener.java │ ├── WssWorker.java │ └── hookauth │ │ ├── CustomPrivateKey.java │ │ ├── CustomPublicKey.java │ │ └── HookAuth.java │ └── utils │ ├── BaseUtils.java │ ├── InvokeUtils.java │ ├── LoggerImpl.java │ └── PdCode.java └── test └── java ├── EventsRegisterTest.java ├── test_Intents.java ├── test_bot_all.java ├── test_channel_create_delete.java ├── test_inputSendMessage.java ├── test_main.java ├── test_mute.java ├── test_onError.java ├── test_onMessage.java ├── test_sendMessage.java └── test_weather.java /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: 2 | - "Kloping" 3 | custom: 4 | - "https://kloping.top/sponsors" -------------------------------------------------------------------------------- /.github/workflows/maven-test.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Java CI with Maven 10 | 11 | on: 12 | push: 13 | branches: [ "group-r0" ] 14 | paths: 15 | - '**/src/test/**/*.java' 16 | pull_request: 17 | branches: [ "group-r0" ] 18 | paths: 19 | - '**/src/main/**/*.java' 20 | 21 | jobs: 22 | build: 23 | 24 | runs-on: ubuntu-latest 25 | 26 | steps: 27 | - uses: actions/checkout@v3 28 | - name: Set up JDK 11 29 | uses: actions/setup-java@v3 30 | with: 31 | java-version: '11' 32 | distribution: 'temurin' 33 | cache: maven 34 | - shell: bash 35 | name: Build with Maven 36 | env: 37 | test: ${{ secrets.SIMPLESECRET }} 38 | appid: ${{ secrets.APPID }} 39 | token: ${{ secrets.TOKEN }} 40 | run: mvn test --file pom.xml -Dappid=${appid} -Dtoken=${token} 41 | 42 | # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive 43 | - name: Update dependency graph 44 | uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 45 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Publish package to the Maven Central Repository 2 | on: 3 | push: 4 | branches: [ "group-r0","master" ] 5 | paths: 6 | - '**/src/main/java/io/github/kloping/qqbot/impl/BaseConnectedEvent.java' 7 | 8 | jobs: 9 | publish: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Set up Maven Central Repository 14 | uses: actions/setup-java@v2 15 | with: 16 | java-version: '8' 17 | distribution: 'adopt' 18 | server-id: central 19 | server-username: MAVEN_USERNAME 20 | server-password: MAVEN_PASSWORD 21 | - id: install-secret-key 22 | name: Install gpg secret key 23 | run: | 24 | cat <(echo -e "${{ secrets.GPG_PRIVATE_KEY }}") | gpg --batch --import 25 | gpg --list-secret-keys --keyid-format LONG 26 | - name: Publish package 27 | env: 28 | MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} 29 | MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} 30 | appid: ${{ secrets.APPID }} 31 | token: ${{ secrets.TOKEN }} 32 | run: mvn --batch-mode -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} clean deploy -P release -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs/* 2 | temp* 3 | # Project exclude paths 4 | src/test/java/temp/gs/** 5 | out/** 6 | /target/ 7 | .idea 8 | temp.log 9 | temp.json 10 | temp.http 11 | bot-qqpd-java.iml 12 | test_temp.java 13 | src/test/java/temp/* 14 | /src/test/java/test_temp_public.java 15 | /src/test/java/test_temp_private.java 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![qqpd-bot-java](https://socialify.git.ci/Kloping/qqpd-bot-java/image?description=1&descriptionEditable=QQ%E5%AE%98%E6%96%B9%E6%9C%BA%E5%99%A8%E4%BA%BA%20Java%2FJVM%2Fkotlin%20SDK%20QQ%20bot%20sdk%20qq%E6%9C%BA%E5%99%A8%E4%BA%BAsdk&font=Source%20Code%20Pro&forks=1&issues=1&language=1&name=1&owner=1&pattern=Overlapping%20Hexagons&pulls=1&stargazers=1&theme=Auto) 2 | 3 |

4 | License 5 | release 6 |

7 | 8 | ## QQ机器人 Java/JVM/kotlin SDK 9 | 10 | > 非官方 可用于 Java 8+ 11 | 12 | Java SDK主要基于[基础 API (opens new window)](https://bot.q.qq.com/wiki/develop/api/)封装,提供给用户一种简单、高效的使用方式。 13 | 14 | ### ✨ 特性 15 | - 支持QQ官方频道与Q群消息收发(私域/公域兼容) 16 | - 开箱即用的消息类型(文本/图片/Markdown/按钮交互) 17 | - 灵活的事件监听机制(`@EventReceiver`注解驱动) 18 | - 多环境支持(沙箱/正式环境一键切换) 19 | - 完善的HTTP API封装(频道管理、禁言、消息审核等) 20 | - 支持Java 8+及Kotlin协程环境 21 | - 支持`websocket`与`webhook`方式链接 22 | 23 | Maven 24 | 25 | ```xml 26 | 27 | 28 | io.github.kloping 29 | bot-qqpd-java 30 | 1.5.2-L1 31 | 32 | ``` 33 | 34 | Gradle 35 | 36 | implementation 'io.github.kloping:bot-qqpd-java:1.5.2-L1' 37 | 38 | ### 使用前提 39 | 40 | 1. 到https://q.qq.com/ 申请机器人 获得Bot 开发者ID(appid) 和 机器人令牌(token) 41 | 42 | ~~2. 发布审核 发布后为公域~~ 43 | 44 | ### [开发文档](./docs/readme.md) / [q群使用说明](./docs/v2.md) 45 | 46 | ### 使用示例 47 | 48 | 启动方式 49 | 50 | ```java 51 | Starter starter = new Starter("appid","token"); 52 | //如果使用q群 则 new Starter("appid", "token", "secret"); 53 | starter.getConfig().setCode(Intents.PRIVATE_INTENTS.getCode()); 54 | // webhook 链接方式 55 | //starter.getConfig().setWebhookport(81); 56 | starter.run(); 57 | ``` 58 | 59 | > #### V1.5.0-Beta7+ 注册监听器主机方式 [荐] 60 | 61 | ```java 62 | starter.registerListenerHost(new ListenerHost(){ 63 | @EventReceiver 64 | public void onEvent(MessageEvent event){ 65 | event.send("测试通过"); 66 | } 67 | }); 68 | ``` 69 | 70 | > #### V1.4.6 71 | > 事件订阅 默认的事件订阅 不会接收消息事件
72 | > 需要确定自己的机器人是公域还是私域
73 | > 来确定 需要 **[设置订阅](src/test/java/test_Intents.java)** 的 **[事件类型](src/main/java/io/github/kloping/qqbot/api/Intents.java)** 74 | ```java 75 | //单事件订阅方式 76 | starter.getConfig().setCode(Intents.GUILD_MESSAGES.getCode()); 77 | 78 | //多事件订阅方式 79 | starter.getConfig().setCode(Intents.START.and(Intents.GUILD_MESSAGES,Intents.DIRECT_MESSAGE)); 80 | 81 | // 公域机器人订阅推荐 82 | starter.getConfig().setCode(Intents.PUBLIC_INTENTS.getCode()); 83 | 84 | // 私域机器人订阅推荐 85 | starter.getConfig().setCode(Intents.PRIVATE_INTENTS.getCode()); 86 | ``` 87 | 88 | #### 导入指引 89 | 90 | ```java 91 | import io.github.kloping.qqbot.Starter; 92 | import io.github.kloping.qqbot.api.Intents; 93 | import io.github.kloping.qqbot.api.message.MessageChannelReceiveEvent; 94 | import io.github.kloping.qqbot.api.message.MessageDirectReceiveEvent; 95 | import io.github.kloping.qqbot.impl.ListenerHost; 96 | ``` 97 | 98 | 更多使用方式参考查看 [test](./src/test/java) 99 | -------------------------------------------------------------------------------- /docs/action.md: -------------------------------------------------------------------------------- 1 | ## 动作文档 2 | 3 | - send 发送消息动作 4 | - 所有实现[Sender](../src/main/java/io/github/kloping/qqbot/api/Sender.java)的对象(Object) 5 | - 常用: 通过消息事件获取的 [Message](../src/main/java/io/github/kloping/qqbot/entities/qqpd/message/Message.java) 6 | - delete 撤回事件 7 | - 所有实现[DeleteAble](../src/main/java/io/github/kloping/qqbot/api/DeleteAble.java) 的对象 8 | - 常用: 通过消息事件获取的 [Message](../src/main/java/io/github/kloping/qqbot/entities/qqpd/message/Message.java) 9 | - at 获取at可发送的消息 10 | - 所有实现[AtAble](../src/main/java/io/github/kloping/qqbot/api/AtAble.java) 的对象 11 | - Channel 12 | - Member 13 | - MemberWithGuildID 14 | - Reactive 可被添加表情的 15 | - BaseMessageChannelReceiveEvent 16 | - BaseMessageContainsAtEvent 17 | - DirectMessage 18 | - MessageChannelReceiveEvent 19 | - RawMessage 20 | -------------------------------------------------------------------------------- /docs/event.md: -------------------------------------------------------------------------------- 1 | ## 事件文档 2 | 3 | ### 事件概述 4 | 5 | 在 QQ 官方机器人 Java SDK 中,事件是处理机器人接收到的各种消息和状态变化的核心机制。通过注册事件监听器,开发者可以捕获并处理这些事件,从而实现机器人的各种功能。 6 | 7 | ### 事件注册 8 | 9 | 事件注册是通过 `Starter` 类的 `registerListenerHost` 方法完成的。开发者需要创建一个实现了 `ListenerHost` 接口的类,并在其中使用 `@EventReceiver` 注解标记事件处理方法。 10 | 11 | 12 | **_待完善.._** 13 | 14 | - [Event](../src/main/java/io/github/kloping/qqbot/api/event/Event.java) 所有事件顶级接口 15 | 16 |
17 | 以下事件可直接写入 ↓ 18 | 19 | [ListenerHost](../src/main/java/io/github/kloping/qqbot/impl/ListenerHost.java) 监听事件中. 20 | [详细实现](readme.md#事件注册) 21 | 22 | - [MessageEvent](../src/main/java/io/github/kloping/qqbot/api/message/MessageEvent.java) 消息事件顶级接口 23 | 24 | > 对框架未处理的事件 在 1.5.0-Alpha5 中添加的[事件注册的方法](../src/test/java/EventsRegisterTest.java) 25 | 26 | Starter#registerEventsRegister(Class cla) 27 | -------------------------------------------------------------------------------- /docs/imgs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kloping/qqpd-bot-java/93aa0e91eb484352b3f01fd228b49f8ed282bf5b/docs/imgs/img.png -------------------------------------------------------------------------------- /docs/imgs/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kloping/qqpd-bot-java/93aa0e91eb484352b3f01fd228b49f8ed282bf5b/docs/imgs/img_1.png -------------------------------------------------------------------------------- /docs/imgs/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kloping/qqpd-bot-java/93aa0e91eb484352b3f01fd228b49f8ed282bf5b/docs/imgs/img_2.png -------------------------------------------------------------------------------- /docs/network.md: -------------------------------------------------------------------------------- 1 | ## 网络相关文档 2 | 3 | 4 | ### 主要新增 5 | 6 | ```java 7 | 8 | /** 9 | * WebSocketClient的监听处理 10 | *
根据提示文档自行处理操作 11 | * 12 | * @author github.kloping 13 | */ 14 | public interface WebSocketListener { 15 | /** 16 | * @param client 17 | * @param handshake 18 | * @return 决定是否进行框架接下来的操作 true执行 19 | */ 20 | boolean onOpen(WebSocketClient client, ServerHandshake handshake) 21 | 22 | /** 23 | * @param client 24 | * @param msg 25 | * @return 决定是否进行框架接下来的操作 true执行 此处若false则不执行(所有事件无法触发) 26 | */ 27 | boolean onMessage(WebSocketClient client, String msg) 28 | 29 | /** 30 | * @param client 31 | * @param msg 32 | * @return 决定是否进行框架接下来的操作 true执行 若为false将无法发送消息 33 | */ 34 | boolean onSend(WebSocketClient client, String msg) 35 | 36 | /** 37 | * Called after the websocket connection has been closed. 38 | * 39 | * @param client 40 | * @param code The codes can be looked up here: {@link CloseFrame} 41 | * @param reason Additional information string 42 | * @param remote Returns whether or not the closing of the connection was initiated by the remote 43 | * host. 44 | * @return 决定是否进行框架接下来的操作 true执行 若为false将不自动重连 45 | */ 46 | boolean onClose(WebSocketClient client, int code, String reason, boolean remote) 47 | 48 | /** 49 | * @param client 50 | * @param e 51 | * @return 同上 框架操作仅日志 52 | */ 53 | boolean onError(WebSocketClient client, Exception e) 54 | } 55 | 56 | ``` 57 | 58 | > 使用示例 59 | 60 | ```java 61 | public class demo{ 62 | public static void main(String[] args) { 63 | starter.getConfig().setWebSocketListener(new WebSocketListener() { 64 | @Override 65 | public boolean onOpen(WebSocketClient client, ServerHandshake handshake) { 66 | client.setConnectionLostTimeout(10); 67 | System.out.println("ws打开了"); 68 | return true; 69 | } 70 | 71 | @Override 72 | public boolean onMessage(WebSocketClient client, String msg) { 73 | System.out.println("ws接收到消息了"); 74 | return true; 75 | } 76 | 77 | @Override 78 | public boolean onSend(WebSocketClient client, String msg) { 79 | System.out.println("ws将发送消息"); 80 | return true; 81 | } 82 | 83 | @Override 84 | public boolean onClose(WebSocketClient client, int code, String reason, boolean remote) { 85 | System.out.println("ws关闭了"); 86 | return true; 87 | } 88 | 89 | @Override 90 | public boolean onError(WebSocketClient client, Exception e) { 91 | System.out.println("ws内部发送报错"); 92 | return true; 93 | } 94 | }); 95 | } 96 | } 97 | ``` -------------------------------------------------------------------------------- /docs/v2.md: -------------------------------------------------------------------------------- 1 | ### 此处为qq机器人在群里中使用的说明 2 | 3 | v2 使用条件(必须) 当前(23.11.16) 4 | 5 | - 机器人必须为公域 6 | - 必须有 **_[在QQ群配置](https://q.qq.com/qqbot/#/developer/sandbox)_** 的权限 7 | - 配置完成后,群主可从沙箱群“设置-群机器人”打开机器人列表页添加测试机器人 8 | 9 |
10 | 11 | > 以下为 必要启动代码 12 | 13 | 14 |
15 | 展开查看 16 | 17 | ```java 18 | import io.github.kloping.qqbot.Starter; 19 | import io.github.kloping.qqbot.api.Intents; 20 | import io.github.kloping.qqbot.api.message.MessageChannelReceiveEvent; 21 | import io.github.kloping.qqbot.api.v2.GroupMessageEvent; 22 | import io.github.kloping.qqbot.entities.ex.Image; 23 | import io.github.kloping.qqbot.entities.ex.MessageAsyncBuilder; 24 | import io.github.kloping.qqbot.entities.qqpd.data.Emoji; 25 | import io.github.kloping.qqbot.impl.BaseConnectedEvent; 26 | import io.github.kloping.qqbot.impl.EventReceiver; 27 | import io.github.kloping.qqbot.impl.ListenerHost; 28 | 29 | public class demo { 30 | public static void main(String[] args) { 31 | //==============================================必要↓↓↓↓↓↓↓ 32 | Starter starter = new Starter("appid", "token", "secret"); 33 | //===================================公域推荐订阅===============↓群聊/好友 事件订阅 34 | starter.getConfig().setCode(Intents.PUBLIC_INTENTS.and(Intents.GROUP_INTENTS)); 35 | starter.run(); 36 | starter.registerListenerHost(new ListenerHost() { 37 | 38 | @EventReceiver 39 | public void onMessage(MessageChannelReceiveEvent event) { 40 | MessageAsyncBuilder builder = new MessageAsyncBuilder(); 41 | builder.append("测试发图!"); 42 | builder.append(new Image("http://kloping.top/icon.jpg")); 43 | builder.append(Emoji.K歌); 44 | event.send(builder.build()); 45 | } 46 | 47 | /** 48 | * 因为是公域 所以仅当bot被at时才能触发事件 49 | * @param event 50 | */ 51 | @EventReceiver 52 | public void onMessage(GroupMessageEvent event) { 53 | MessageAsyncBuilder builder = new MessageAsyncBuilder(); 54 | builder.append("测试发图!"); 55 | //目前仅支持 以url发送图片 https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html#%E5%8F%91%E9%80%81%E5%88%B0%E7%BE%A4%E8%81%8A 56 | builder.append(new Image("http://kloping.top/icon.jpg")); 57 | builder.append(Emoji.K歌); 58 | event.sendMessage(builder.build()); 59 | } 60 | }); 61 | } 62 | } 63 | ``` 64 | 65 |
66 | 67 | 68 | > 选择性配置 # date 2023.11.17 version 1.5.0-L6 69 | 70 | - > 支持image发送视频/语音 视频:Image(url,2); 语音:Image(url,3); 文件:暂不支持 71 | 72 | > 2024.3.24 version 1.5.1-Beta1 支持非url直链上传 73 | 74 |
75 | 展开查看 76 | 77 | ```java 78 | public class demo1 { 79 | public static void main(String[] args) { 80 | //设置qq群发送图片时将bytes上传为url以达到适配bytes image 81 | starter.getConfig().setInterceptor0(bytes -> upload(url)); 82 | 83 | 84 | 85 | //仅推荐 / 当前可用 不保证未来可用 86 | starter.getConfig().setInterceptor0(bytes -> { 87 | try { 88 | String url = Jsoup.connect("http://bak0.kloping.top:81/upload-img") 89 | .ignoreContentType(true) 90 | .ignoreContentType(true) 91 | .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.67") 92 | .data("file", "temp.jpg", new ByteArrayInputStream(bytes)).method(Connection.Method.POST).execute().body(); 93 | return url; 94 | } catch (IOException e) { 95 | System.err.println("上传失败! "+e.getMessage()); 96 | return null; 97 | } 98 | }); 99 | } 100 | } 101 | ``` 102 | 103 |
104 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/Resource.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot; 2 | 3 | import com.google.gson.Gson; 4 | import io.github.kloping.qqbot.api.exc.RequestException; 5 | import io.github.kloping.qqbot.impl.exc.InvalidRequestException; 6 | import io.github.kloping.spt.annotations.Entity; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author github.kloping 13 | */ 14 | @Entity 15 | public class Resource { 16 | public static final Gson GSON = new Gson(); 17 | 18 | public static final Map> CODE2EXCEPTION = new HashMap<>(); 19 | 20 | static { 21 | Resource.CODE2EXCEPTION.put(11255, InvalidRequestException.class); 22 | Resource.CODE2EXCEPTION.put(11244, InvalidRequestException.class); 23 | } 24 | 25 | public static void print() { 26 | System.out.println("\n" + 27 | " __ __ __ \n" + 28 | " /\\ \\ /\\ \\ /\\ \\__ __ \n" + 29 | " __ __ _____ \\_\\ \\ \\ \\ \\____ ___ \\ \\ ,_\\ /\\_\\ __ __ __ __ \n" + 30 | " /'__`\\ /'__`\\ /\\ '__`\\ /'_` \\ _______ \\ \\ '__`\\ / __`\\ \\ \\ \\/ _______ \\/\\ \\ /'__`\\ /\\ \\/\\ \\ /'__`\\ \n" + 31 | "/\\ \\L\\ \\ /\\ \\L\\ \\ \\ \\ \\L\\ \\/\\ \\L\\ \\ /\\______\\ \\ \\ \\L\\ \\/\\ \\L\\ \\ \\ \\ \\_ /\\______\\ \\ \\ \\ /\\ \\L\\.\\_ \\ \\ \\_/ |/\\ \\L\\.\\_ \n" + 32 | "\\ \\___, \\ \\ \\___, \\ \\ \\ ,__/\\ \\___,_\\\\/______/ \\ \\_,__/\\ \\____/ \\ \\__\\\\/______/ _\\ \\ \\ \\ \\__/.\\_\\ \\ \\___/ \\ \\__/.\\_\\\n" + 33 | " \\/___/\\ \\ \\/___/\\ \\ \\ \\ \\/ \\/__,_ / \\/___/ \\/___/ \\/__/ /\\ \\_\\ \\ \\/__/\\/_/ \\/__/ \\/__/\\/_/\n" + 34 | " \\ \\_\\ \\ \\_\\ \\ \\_\\ \\ \\____/ \n" + 35 | " \\/_/ \\/_/ \\/_/ \\/___/ \n"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/Start0.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.Channel; 4 | import io.github.kloping.qqbot.http.AuthV2Base; 5 | import io.github.kloping.qqbot.http.data.Token; 6 | import io.github.kloping.spt.annotations.AutoStand; 7 | import io.github.kloping.spt.annotations.ComponentScan; 8 | import io.github.kloping.spt.interfaces.component.ContextManager; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | /** 14 | * @author github.kloping 15 | */ 16 | @ComponentScan(value = "io.github.kloping.qqbot") 17 | public class Start0 { 18 | 19 | public Map headers = new HashMap(); 20 | public Map v2headers = new HashMap(); 21 | 22 | @AutoStand 23 | ContextManager contextManager; 24 | 25 | //ALL req token header 26 | public synchronized Map getHeaders() { 27 | if (isExpired(token)) headers.clear(); 28 | if (headers.isEmpty()) { 29 | headers.put("Authorization", String.format("QQBot %s", getV2Token())); 30 | headers.put("Accept-Encoding", "application/json"); 31 | headers.put("X-Union-Appid", contextManager.getContextEntity(String.class, Starter.APPID_ID)); 32 | } 33 | return headers; 34 | } 35 | 36 | private boolean isExpired(Token token) { 37 | return token == null || token.isExpired(); 38 | } 39 | 40 | @AutoStand 41 | AuthV2Base authV2Base; 42 | 43 | 44 | private Token token; 45 | 46 | private String getV2Token() { 47 | String appid = contextManager.getContextEntity(String.class, Starter.APPID_ID); 48 | String secret = contextManager.getContextEntity(String.class, Starter.SECRET_ID); 49 | token = authV2Base.auth( 50 | String.format("{\"appId\": \"%s\",\"clientSecret\": \"%s\"}\n", appid, secret) 51 | , Channel.SEND_MESSAGE_HEADERS); 52 | token.setT0(System.currentTimeMillis()); 53 | return token.getAccess_token(); 54 | } 55 | 56 | public String getAccessToken() { 57 | return isExpired(token) ? getV2Token() : token.getAccess_token(); 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/AtAble.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | import io.github.kloping.qqbot.entities.ex.At; 4 | 5 | /** 6 | * 能被at的 7 | * 8 | * @author github.kloping 9 | */ 10 | public interface AtAble { 11 | At at(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/BotContent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | import io.github.kloping.qqbot.entities.Bot; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface BotContent { 9 | Bot getBot(); 10 | 11 | void setBot(Bot bot); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/DeleteAble.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | /** 4 | * 能删除的 5 | * 6 | * @author github.kloping 7 | */ 8 | public interface DeleteAble { 9 | /** 10 | * 删除 11 | * 12 | * @return 13 | */ 14 | Object delete(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/DirectSender.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 4 | import io.github.kloping.qqbot.entities.qqpd.message.RawPreMessage; 5 | import io.github.kloping.qqbot.http.data.ActionResult; 6 | import io.github.kloping.qqbot.http.data.Result; 7 | import io.github.kloping.qqbot.impl.MessagePacket; 8 | 9 | /** 10 | * 私信发送者(消息)接口 11 | * 12 | * @author github.kloping 13 | */ 14 | public interface DirectSender extends Sender { 15 | @Override 16 | default Result send(String text) { 17 | return sendDirect(text); 18 | } 19 | 20 | @Override 21 | default Result send(String text, RawMessage message) { 22 | return sendDirect(text, message); 23 | } 24 | 25 | @Override 26 | default Result send(MessagePacket packet) { 27 | return sendDirect(packet); 28 | } 29 | 30 | @Override 31 | default Result send(RawPreMessage msg) { 32 | return sendDirect(msg); 33 | } 34 | 35 | /** 36 | * 以JSON方式发送文本消息 37 | * 38 | * @param text 39 | * @return 40 | */ 41 | Result sendDirect(String text); 42 | 43 | /** 44 | * 以JSON方式发送文本消息并引用指定消息 45 | * 46 | * @param text 47 | * @param message 48 | * @return 49 | */ 50 | Result sendDirect(String text, RawMessage message); 51 | 52 | /** 53 | * 以自定义方式发送消息 54 | * 55 | * @param packet 56 | * @return 57 | */ 58 | Result sendDirect(MessagePacket packet); 59 | 60 | /** 61 | * 自定义消息 62 | * 63 | * @param msg 64 | * @return 65 | */ 66 | Result sendDirect(RawPreMessage msg); 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/OpAble.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | /** 4 | * 信息可被修改的 5 | * 6 | * @author github.kloping 7 | */ 8 | public interface OpAble { 9 | /** 10 | * 管理者id 11 | * 12 | * @return 13 | */ 14 | String getOpUserId(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/Reactive.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.data.Emoji; 4 | 5 | /** 6 | * 可被添加表情的 7 | * 8 | * @author github.kloping 9 | */ 10 | public interface Reactive { 11 | void addEmoji(Emoji emoji); 12 | 13 | void removeEmoji(Emoji emoji); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/SendAble.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | import io.github.kloping.qqbot.http.data.Result; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface SendAble { 9 | /** 10 | * 所有可发送的 11 | * 12 | * @param er 13 | * @return 14 | */ 15 | Result send(SenderAndCidMidGetter er); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/Sender.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 4 | import io.github.kloping.qqbot.entities.qqpd.message.RawPreMessage; 5 | import io.github.kloping.qqbot.http.data.Result; 6 | import io.github.kloping.qqbot.impl.MessagePacket; 7 | 8 | /** 9 | * 发送者(消息)接口 10 | * 11 | * @author github.kloping 12 | */ 13 | public interface Sender { 14 | 15 | /** 16 | * 以JSON方式发送文本消息 17 | * 18 | * @param text 19 | * @return 20 | */ 21 | Result send(String text); 22 | 23 | /** 24 | * 以JSON方式发送文本消息并引用指定消息 25 | * 26 | * @param text 27 | * @param message 28 | * @return 29 | */ 30 | Result send(String text, RawMessage message); 31 | 32 | /** 33 | * 以各种方式 达到想要发送的效果 34 | * 35 | * @param msg 36 | * @return 37 | */ 38 | Result send(SendAble msg); 39 | 40 | /** 41 | * 以自定义方式发送消息 42 | * 43 | * @param packet 44 | * @return 45 | */ 46 | default Result send(MessagePacket packet) { 47 | return null; 48 | } 49 | 50 | /** 51 | * 自定义消息 52 | * 53 | * @param msg 54 | * @return 55 | */ 56 | default Result send(RawPreMessage msg) { 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/SenderAndCidMidGetter.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface SenderAndCidMidGetter extends Sender, BotContent { 9 | /** 10 | * 获取 channel id 11 | * 12 | * @return 13 | */ 14 | String getCid(); 15 | 16 | /** 17 | * 获取 message id 18 | * 19 | * @return 20 | */ 21 | default String getMid() { 22 | return null; 23 | } 24 | 25 | /** 26 | * 获得发送环境 27 | * guild/qq 28 | * 29 | * @return 30 | */ 31 | EnvType getEnvType(); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/SenderV2.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | import io.github.kloping.qqbot.http.BaseV2; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface SenderV2 extends Sender, BotContent { 9 | BaseV2 getV2(); 10 | 11 | default Integer getMsgSeq() { 12 | return 1; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/SessionCreator.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.Dms; 4 | 5 | /** 6 | * 私信会话创建接口 7 | * 8 | * @author github.kloping 9 | */ 10 | public interface SessionCreator { 11 | /** 12 | * 私信会话创建 13 | * 14 | * @param uid 15 | * @return 16 | */ 17 | Dms create(String uid); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/event/ChannelEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.event; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.Channel; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface ChannelEvent extends GuildEvent { 9 | /** 10 | * 事件所在子频道 11 | * 12 | * @return 13 | */ 14 | Channel getChannel(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/event/ChannelUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.event; 2 | 3 | /** 4 | * 子频道更新事件 5 | * 6 | * @author github.kloping 7 | */ 8 | public interface ChannelUpdateEvent extends ChannelEvent { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/event/ConnectedEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.event; 2 | 3 | /** 4 | * @author github.kloping 5 | */ 6 | public interface ConnectedEvent extends Event { 7 | /** 8 | * session id 9 | * 10 | * @return 11 | */ 12 | String getSessionId(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/event/Event.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.event; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.entities.Bot; 5 | 6 | /** 7 | * 所有事件的顶级接口 8 | * 9 | * @author github.kloping 10 | */ 11 | public interface Event { 12 | /** 13 | * 获得元数据 14 | * 15 | * @return 16 | */ 17 | JSONObject getMetadata(); 18 | 19 | /** 20 | * 事件所在bot 21 | * 22 | * @return 23 | */ 24 | Bot getBot(); 25 | 26 | /** 27 | * 事件id 28 | * 29 | * @return 30 | */ 31 | String getId(); 32 | 33 | default String getClassName() { 34 | return this.getClass().getSimpleName(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/event/GuildEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.event; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.Guild; 4 | 5 | /** 6 | * 频道事件 7 | * 8 | * @author github.kloping 9 | */ 10 | public interface GuildEvent extends Event { 11 | /** 12 | * 事件所在频道 13 | * 14 | * @return 15 | */ 16 | Guild getGuild(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/event/GuildUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.event; 2 | 3 | /** 4 | * @author github.kloping 5 | */ 6 | public interface GuildUpdateEvent extends GuildEvent { 7 | 8 | String getUnionAppId(); 9 | 10 | String getUnionOrgId(); 11 | 12 | String getUnionWorldId(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/event/InterActionEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.event; 2 | 3 | import io.github.kloping.qqbot.api.Sender; 4 | import io.github.kloping.qqbot.entities.qqpd.InterAction; 5 | 6 | /** 7 | * @author github.kloping 8 | */ 9 | public interface InterActionEvent extends Event, Sender { 10 | /** 11 | * 0 频道场景,1 群聊场景,2 单聊场景 12 | * 13 | * @return 14 | */ 15 | Integer getChatType(); 16 | 17 | /** 18 | * 获得数据 19 | * 20 | * @return 21 | */ 22 | InterAction getInterAction(); 23 | 24 | /** 25 | * 响应 26 | * 0 成功 1 操作失败 2 操作频繁 3 重复操作 4 没有权限 5 仅管理员操作
27 | * 测试未知异常 暂不可用 28 | * 29 | * @param code 30 | */ 31 | void response(int code); 32 | 33 | @Override 34 | default String getClassName() { 35 | return "InterActionEvent"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/event/MemberUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.event; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.MemberWithGuildID; 4 | 5 | /** 6 | * 成员信息更新事件 7 | * 8 | * @author github.kloping 9 | */ 10 | public interface MemberUpdateEvent extends GuildEvent { 11 | /** 12 | * 被修改的成员 13 | * 14 | * @return 15 | */ 16 | MemberWithGuildID getMember(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/event/ReactionEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.event; 2 | 3 | /** 4 | * 表情表态事件 5 | * 6 | * @author github.kloping 7 | */ 8 | public interface ReactionEvent extends Event { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/exc/RequestException.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.exc; 2 | 3 | import io.github.kloping.qqbot.entities.exc.QBotError; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | /** 8 | * 发送请求时抛出的运行是异常 9 | * http resp code != 200 10 | * 11 | * @author github.kloping 12 | */ 13 | @Getter 14 | public class RequestException extends RuntimeException { 15 | private final int code; 16 | private final String body; 17 | private final String url; 18 | private final String method; 19 | @Setter 20 | protected QBotError data; 21 | 22 | public RequestException(int code, String body, String url,String method) { 23 | super(String.format("The request error response url [%s] code is [%s] (%s)", url, code, body)); 24 | this.code = code; 25 | this.body = body; 26 | this.url = url; 27 | this.method = method; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/message/Builder.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.message; 2 | 3 | /** 4 | * @author github.kloping 5 | */ 6 | public interface Builder { 7 | Builder append(R r); 8 | 9 | T build(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/message/MessageChannelReceiveEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.message; 2 | 3 | import io.github.kloping.qqbot.api.Reactive; 4 | import io.github.kloping.qqbot.entities.qqpd.Member; 5 | 6 | /** 7 | * 消息接收事件 8 | * 9 | * @author github.kloping 10 | */ 11 | public interface MessageChannelReceiveEvent extends MessageReceiveEvent, Reactive { 12 | /** 13 | * 消息内容 14 | * 15 | * @return 16 | */ 17 | String getContent(); 18 | 19 | /** 20 | * 获取子频道ID 21 | * 22 | * @return 23 | */ 24 | String getChannelId(); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/message/MessageContainsAtEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.message; 2 | 3 | /** 4 | * 消息存在AT事件 5 | * 6 | * @author github.kloping 7 | */ 8 | public interface MessageContainsAtEvent extends MessageChannelReceiveEvent, MessageReceiveEvent { 9 | /** 10 | * 获取消息中所有被AT者ID 11 | * 12 | * @return 13 | */ 14 | String[] getAllAt(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/message/MessageDeleteEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.message; 2 | 3 | import io.github.kloping.qqbot.api.event.ChannelEvent; 4 | import io.github.kloping.qqbot.entities.qqpd.Channel; 5 | import io.github.kloping.qqbot.entities.qqpd.Member; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public interface MessageDeleteEvent extends ChannelEvent, MessageEvent { 11 | /** 12 | * 事件 操作者ID 13 | * 14 | * @return 15 | */ 16 | String getOpUserId(); 17 | 18 | /** 19 | * 被撤回者ID 20 | * 21 | * @return 22 | */ 23 | String getAuthorId(); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/message/MessageDirectReceiveEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.message; 2 | 3 | import io.github.kloping.qqbot.api.DirectSender; 4 | import io.github.kloping.qqbot.entities.qqpd.Guild; 5 | import io.github.kloping.qqbot.entities.qqpd.message.DirectMessage; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | import io.github.kloping.qqbot.entities.qqpd.message.RawPreMessage; 8 | import io.github.kloping.qqbot.http.data.ActionResult; 9 | import io.github.kloping.qqbot.http.data.Result; 10 | import io.github.kloping.qqbot.impl.MessagePacket; 11 | 12 | /** 13 | * 私信消息接收事件 14 | * 15 | * @author github.kloping 16 | */ 17 | public interface MessageDirectReceiveEvent extends MessageReceiveEvent, DirectSender { 18 | /** 19 | * 来源guild 20 | * 21 | * @return 22 | */ 23 | String getSrcGuildId(); 24 | 25 | /** 26 | * 来源guild 27 | * 28 | * @return 29 | */ 30 | Guild getSrcGuild(); 31 | 32 | /** 33 | * 获取私信消息 34 | * 35 | * @return 36 | */ 37 | DirectMessage getDirectMessage(); 38 | 39 | /** 40 | * 替换默认 41 | * 42 | * @param text 43 | * @return 44 | */ 45 | @Override 46 | default Result send(String text) { 47 | return sendDirect(text); 48 | } 49 | 50 | /** 51 | * 替换默认 52 | * 53 | * @param text 54 | * @param message 55 | * @return 56 | */ 57 | @Override 58 | default Result send(String text, RawMessage message) { 59 | return sendDirect(text, message); 60 | } 61 | 62 | /** 63 | * 替换默认 64 | * 65 | * @param packet 66 | * @return 67 | */ 68 | @Override 69 | default Result send(MessagePacket packet) { 70 | return sendDirect(packet); 71 | } 72 | 73 | /** 74 | * 替换默认 75 | * 76 | * @param msg 77 | * @return 78 | */ 79 | @Override 80 | default Result send(RawPreMessage msg) { 81 | return sendDirect(msg); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/message/MessageEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.message; 2 | 3 | import io.github.kloping.qqbot.api.Sender; 4 | import io.github.kloping.qqbot.api.event.Event; 5 | import io.github.kloping.qqbot.entities.ex.msg.MessageChain; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | import io.github.kloping.qqbot.entities.qqpd.v2.Contact; 8 | 9 | /** 10 | * 消息事件接口 11 | * 12 | * @author github.kloping 13 | */ 14 | public interface MessageEvent extends Event, Sender { 15 | /** 16 | * 获取消息 17 | * 18 | * @return 19 | */ 20 | RawMessage getRawMessage(); 21 | 22 | /** 23 | * 消息事件发送者 24 | * 25 | * @return 26 | */ 27 | T getSender(); 28 | 29 | /** 30 | * 发送环境 31 | * 32 | * @return 33 | */ 34 | S getSubject(); 35 | /** 36 | * 将消息转为 MessageChain 37 | * 38 | * @return 39 | */ 40 | MessageChain getMessage(); 41 | 42 | /** 43 | * set filter 44 | * 45 | * @param filters 46 | */ 47 | void setFilter(Class[] filters); 48 | 49 | @Override 50 | default String getClassName() { 51 | return MessageEvent.class.getSimpleName(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/message/MessageReactionEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.message; 2 | 3 | import io.github.kloping.qqbot.api.event.ChannelEvent; 4 | import io.github.kloping.qqbot.entities.qqpd.Channel; 5 | import io.github.kloping.qqbot.entities.qqpd.Member; 6 | import io.github.kloping.qqbot.entities.qqpd.message.EmojiReaction; 7 | 8 | /** 9 | * 消息表情表态事件接口 10 | * 11 | * @author github.kloping 12 | */ 13 | public interface MessageReactionEvent extends ChannelEvent, MessageEvent { 14 | 15 | /** 16 | * get MessageReaction 17 | * 18 | * @return 19 | */ 20 | EmojiReaction getMessageReaction(); 21 | 22 | @Override 23 | default String getClassName() { 24 | return "MessageReactionEvent"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/message/MessageReceiveEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.message; 2 | 3 | import io.github.kloping.qqbot.api.event.ChannelEvent; 4 | import io.github.kloping.qqbot.entities.qqpd.Channel; 5 | import io.github.kloping.qqbot.entities.qqpd.Guild; 6 | import io.github.kloping.qqbot.entities.qqpd.Member; 7 | 8 | /** 9 | * 消息接收事件 10 | * 11 | * @author github.kloping 12 | */ 13 | public interface MessageReceiveEvent extends ChannelEvent, MessageEvent { 14 | /** 15 | * 消息内容 16 | * 17 | * @return 18 | */ 19 | String getContent(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/message/Pinsble.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.message; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.PinsMessage; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface Pinsble { 9 | PinsMessage addPins(); 10 | 11 | void deletePins(); 12 | 13 | PinsMessage getPins(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/v2/FriendAdd.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.v2; 2 | 3 | /** 4 | * @author github.kloping 5 | */ 6 | public interface FriendAdd extends FriendEvent { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/v2/FriendEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.v2; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.v2.Contact; 4 | import io.github.kloping.qqbot.entities.qqpd.v2.Friend; 5 | 6 | /** 7 | * @author github.kloping 8 | */ 9 | public interface FriendEvent extends V2Event { 10 | /** 11 | * get friend 12 | * 13 | * @return 14 | */ 15 | Friend getFriend(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/v2/FriendMessageEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.v2; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.v2.Friend; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface FriendMessageEvent extends FriendEvent, MessageV2Event { 9 | @Override 10 | Friend getSender(); 11 | 12 | @Override 13 | Friend getSubject(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/v2/GroupEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.v2; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.v2.Group; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface GroupEvent extends V2Event { 9 | Group getGroup(); 10 | 11 | String getGroupId(); 12 | 13 | default String getGroupOpenId() { 14 | return getGroupId(); 15 | } 16 | 17 | @Override 18 | default String getOpenId() { 19 | return getGroupOpenId(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/v2/GroupMessageEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.v2; 2 | 3 | import io.github.kloping.qqbot.api.SenderV2; 4 | import io.github.kloping.qqbot.api.message.MessageEvent; 5 | import io.github.kloping.qqbot.entities.qqpd.v2.Contact; 6 | import io.github.kloping.qqbot.entities.qqpd.v2.Group; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | public interface GroupMessageEvent extends GroupEvent, MessageEvent, MessageV2Event, SenderV2 { 12 | /** 13 | * 发送环境 14 | * 15 | * @return 16 | */ 17 | Group getSubject(); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/v2/GroupOpRobotEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.v2; 2 | 3 | /** 4 | * @author github.kloping 5 | */ 6 | public interface GroupOpRobotEvent extends GroupEvent { 7 | String getOpMemberOpenid(); 8 | 9 | Long getTimestamp(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/v2/MessageV2Event.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.v2; 2 | 3 | import io.github.kloping.qqbot.api.SendAble; 4 | import io.github.kloping.qqbot.api.Sender; 5 | import io.github.kloping.qqbot.api.event.Event; 6 | import io.github.kloping.qqbot.entities.ex.msg.MessageChain; 7 | import io.github.kloping.qqbot.entities.qqpd.v2.Contact; 8 | import io.github.kloping.qqbot.http.data.V2Result; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | public interface MessageV2Event extends Event, Sender, V2Event { 14 | /** 15 | * 发送纯文本 16 | * 17 | * @param text 18 | * @return 19 | */ 20 | V2Result sendMessage(String text); 21 | 22 | V2Result sendMessage(SendAble msg); 23 | 24 | /** 25 | * 当前 因为腾讯服务器原因 消息中不存在at类型 26 | * 消息组 27 | * 28 | * @return 29 | */ 30 | MessageChain getMessage(); 31 | 32 | /** 33 | * 发送者 34 | * 35 | * @return 36 | */ 37 | Contact getSender(); 38 | 39 | /** 40 | * 发送环境 41 | * 42 | * @return 43 | */ 44 | Contact getSubject(); 45 | 46 | 47 | /** 48 | * 设置消息序列号并返回原序列号 49 | * @param seq 50 | * @return 51 | */ 52 | Integer setMsgSeq(Integer seq); 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/api/v2/V2Event.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.api.v2; 2 | 3 | import io.github.kloping.qqbot.api.event.Event; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface V2Event extends Event { 9 | /** 10 | * 所处环境 openid 可能是 user openid 或 group openid 11 | * @return 12 | */ 13 | String getOpenId(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/Bot.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities; 2 | 3 | import io.github.kloping.spt.annotations.AutoStand; 4 | import io.github.kloping.spt.annotations.Entity; 5 | import io.github.kloping.spt.interfaces.Logger; 6 | import io.github.kloping.qqbot.Starter; 7 | import io.github.kloping.qqbot.entities.qqpd.Guild; 8 | import io.github.kloping.qqbot.entities.qqpd.User; 9 | import io.github.kloping.qqbot.http.*; 10 | import lombok.Getter; 11 | 12 | import java.util.Collection; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * @author github.kloping 18 | */ 19 | @Entity 20 | public class Bot { 21 | @AutoStand 22 | public Logger logger; 23 | 24 | @AutoStand 25 | public InterActionBase interActionBase; 26 | 27 | @AutoStand 28 | public GuildBase guildBase; 29 | 30 | @AutoStand 31 | public UserBase userBase; 32 | 33 | @AutoStand 34 | public ChannelBase channelBase; 35 | 36 | @AutoStand 37 | public DmsBase dmsBase; 38 | 39 | @AutoStand 40 | public MessageBase messageBase; 41 | 42 | @AutoStand 43 | public MemberBase memberBase; 44 | 45 | @AutoStand 46 | public GroupBaseV2 groupBaseV2; 47 | 48 | @AutoStand 49 | public UserBaseV2 userBaseV2; 50 | 51 | @AutoStand 52 | public AuthV2Base authV2Base; 53 | 54 | @Getter 55 | @AutoStand 56 | Starter.Config config; 57 | 58 | private User user; 59 | 60 | private Map guildMap = new HashMap<>(); 61 | 62 | private void tryLoadGuilds() { 63 | if (guildMap.isEmpty()) { 64 | user = userBase.botInfo(); 65 | for (Guild guild : guildBase.getGuilds()) { 66 | guild.setBot(this); 67 | guildMap.put(guild.getId(), guild); 68 | } 69 | } 70 | } 71 | 72 | public synchronized Guild getGuild(String id) { 73 | tryLoadGuilds(); 74 | if (!guildMap.containsKey(id)) { 75 | Guild guild = guildBase.getGuild(id); 76 | if (guild != null) setGuild(guild); 77 | } 78 | return guildMap.get(id); 79 | } 80 | 81 | public Guild setGuild(Guild guild) { 82 | guildMap.put(guild.getId(), guild); 83 | return guildMap.get(guild.getId()); 84 | } 85 | 86 | public Guild delGuild(Guild guild) { 87 | guildMap.remove(guild.getId()); 88 | return guild; 89 | } 90 | 91 | public Collection guilds() { 92 | tryLoadGuilds(); 93 | return guildMap.values(); 94 | } 95 | 96 | public synchronized User getInfo() { 97 | if (user == null) { 98 | user = userBase.botInfo(); 99 | } 100 | return user; 101 | } 102 | 103 | public String getId() { 104 | return getInfo().getId(); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/Pack.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities; 2 | 3 | import io.github.kloping.object.ObjectUtils; 4 | import lombok.Data; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | *
CODE 名称 客户端操作 描述
0 Dispatch Receive 服务端进行消息推送
1 Heartbeat Send/Receive 客户端或服务端发送心跳
2 Identify Send 客户端发送鉴权
6 Resume Send 客户端恢复连接
7 Reconnect Receive 服务端通知客户端重新连接
9 Invalid Session Receive 当identify或resume的时候,如果参数有错,服务端会返回该消息
10 Hello Receive 当客户端与网关建立ws连接之后,网关下发的第一条消息
11 Heartbeat ACK Receive/Reply 当发送心跳成功之后,就会收到该消息
12 HTTP Callback ACK Reply 仅用于 http 回调模式的回包,代表机器人收到了平台推送的数据
10 | * 11 | * @author github-kloping 12 | */ 13 | @Data 14 | public class Pack { 15 | private Integer op; 16 | private Number s; 17 | private Object d; 18 | private String t; 19 | private String id; 20 | 21 | public T dAsMapGet(Object key, Class cla) { 22 | if (d instanceof Map) { 23 | Map map = (Map) d; 24 | Object obj = map.get(key); 25 | T t = ObjectUtils.asPossible(cla, obj); 26 | return t; 27 | } 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/ex/At.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.ex; 2 | 3 | import io.github.kloping.qqbot.api.SendAble; 4 | import io.github.kloping.qqbot.api.SenderAndCidMidGetter; 5 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 6 | import io.github.kloping.qqbot.http.data.Result; 7 | import io.github.kloping.qqbot.impl.MessagePacket; 8 | import lombok.Data; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | @Data 14 | public class At implements SendAble { 15 | public static final String MEMBER_TYPE = "member"; 16 | public static final String CHANNEL_TYPE = "channel"; 17 | 18 | private String type = "member"; 19 | private String targetId; 20 | 21 | public At(String type, String targetId) { 22 | this.type = type; 23 | this.targetId = targetId; 24 | } 25 | 26 | public At(String targetId) { 27 | this.targetId = targetId; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | if (CHANNEL_TYPE.equals(type)) { 33 | return "<#" + targetId + ">"; 34 | } else if (MEMBER_TYPE.equals(type)) { 35 | return String.format("", targetId); 36 | } else return "@"; 37 | } 38 | 39 | @Override 40 | public Result send(SenderAndCidMidGetter er) { 41 | if (er.getEnvType() == EnvType.GUILD) { 42 | MessagePacket packet = new MessagePacket(); 43 | packet.setContent(toString()); 44 | return er.send(packet); 45 | } else { 46 | return er.send(toString()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/ex/AtAll.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.ex; 2 | 3 | import io.github.kloping.qqbot.api.SendAble; 4 | import io.github.kloping.qqbot.api.SenderAndCidMidGetter; 5 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 6 | import io.github.kloping.qqbot.http.data.Result; 7 | import io.github.kloping.qqbot.impl.MessagePacket; 8 | 9 | /** 10 | * @author github.kloping 11 | */ 12 | public class AtAll implements SendAble { 13 | 14 | @Override 15 | public Result send(SenderAndCidMidGetter er) { 16 | if (er.getEnvType() == EnvType.GUILD) { 17 | MessagePacket packet = new MessagePacket(); 18 | packet.setContent("@everyone"); 19 | return er.send(packet); 20 | } else { 21 | return er.send("@所有人"); 22 | } 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "@atAll"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/ex/BaseKeyVals.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.ex; 2 | 3 | import io.github.kloping.spt.entity.KeyVals; 4 | import org.jsoup.helper.HttpConnection; 5 | 6 | import java.util.Collection; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | public class BaseKeyVals implements KeyVals { 14 | private List list = new LinkedList<>(); 15 | 16 | public BaseKeyVals add(HttpConnection.KeyVal keyVal) { 17 | list.add(keyVal); 18 | return this; 19 | } 20 | 21 | @Override 22 | public Collection values() { 23 | return list; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/ex/Markdown.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.ex; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import io.github.kloping.qqbot.api.SendAble; 5 | import io.github.kloping.qqbot.api.SenderAndCidMidGetter; 6 | import io.github.kloping.qqbot.api.SenderV2; 7 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 8 | import io.github.kloping.qqbot.entities.qqpd.message.RawPreMessage; 9 | import io.github.kloping.qqbot.http.data.Result; 10 | import io.github.kloping.qqbot.http.data.V2MsgData; 11 | import io.github.kloping.qqbot.http.data.V2Result; 12 | import lombok.AllArgsConstructor; 13 | import lombok.Data; 14 | import lombok.Getter; 15 | import lombok.NoArgsConstructor; 16 | 17 | import java.util.LinkedList; 18 | import java.util.List; 19 | 20 | import static io.github.kloping.qqbot.entities.qqpd.Channel.SEND_MESSAGE_HEADERS; 21 | 22 | /** 23 | * @author github.kloping 24 | */ 25 | @Getter 26 | public class Markdown implements SendAble { 27 | private String custom_template_id; 28 | private List params = null; 29 | 30 | /** 31 | * 原生md可用 32 | */ 33 | private String content; 34 | 35 | private Keyboard keyboard; 36 | 37 | /** 38 | * 需要再QQ机器人管理平台 申请并审核通过后使用 39 | * 40 | * @param custom_template_id 41 | */ 42 | public Markdown(String custom_template_id) { 43 | this.custom_template_id = custom_template_id; 44 | } 45 | 46 | public Markdown addParam(String key, String value) { 47 | if (params == null) params = new LinkedList<>(); 48 | params.add(new Param(key, new String[]{value})); 49 | return this; 50 | } 51 | 52 | public Markdown setContent(String content) { 53 | this.content = content; 54 | return this; 55 | } 56 | 57 | public Markdown setKeyboard(Keyboard keyboard) { 58 | this.keyboard = keyboard; 59 | return this; 60 | } 61 | 62 | public Markdown setKeyboard(String id) { 63 | return setKeyboard(new Keyboard(id)); 64 | } 65 | 66 | @Data 67 | @AllArgsConstructor 68 | @NoArgsConstructor 69 | public static class Param { 70 | public String key; 71 | private String[] values; 72 | } 73 | 74 | @Override 75 | public Result send(SenderAndCidMidGetter er) { 76 | return send(er, 1); 77 | } 78 | 79 | public Result send(SenderAndCidMidGetter er, Integer msgSeq) { 80 | if (er.getEnvType().isV2()) { 81 | V2MsgData v2MsgData = new V2MsgData().setMarkdown(this).setMsg_type(2).setMsg_id(er.getMid()); 82 | if (keyboard != null) v2MsgData.setKeyboard(getKeyboard()); 83 | SenderV2 senderV2 = (SenderV2) er; 84 | return new Result(senderV2.getV2().send(er.getCid(), JSON.toJSONString(v2MsgData), SEND_MESSAGE_HEADERS)); 85 | } else if (er.getEnvType() == EnvType.GUILD) { 86 | RawPreMessage preMessage = new RawPreMessage().setMarkdown(this).setMsgId(er.getMid()); 87 | return new Result(er.getBot().messageBase.send(er.getCid(), preMessage, SEND_MESSAGE_HEADERS)); 88 | } 89 | return er.send(this); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/ex/MessageAsyncBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.ex; 2 | 3 | import io.github.kloping.qqbot.api.SendAble; 4 | import io.github.kloping.qqbot.api.message.Builder; 5 | import io.github.kloping.qqbot.entities.ex.msg.MessageChain; 6 | 7 | /** 8 | * 异步 消息 发送
9 | * 用于处理 多图片 无法同时发送的问题
10 | * tips:构建的{@link Image}对象仅适用 byte[] 构建方式 11 | * 12 | * @author github.kloping 13 | */ 14 | public class MessageAsyncBuilder implements Builder { 15 | 16 | private final MessageChain chain = new MessageChain(); 17 | 18 | @Override 19 | public MessageAsyncBuilder append(SendAble sendAble) { 20 | chain.append(sendAble); 21 | return this; 22 | } 23 | 24 | public MessageAsyncBuilder append(String text) { 25 | chain.append(new PlainText(text)); 26 | return this; 27 | } 28 | 29 | @Override 30 | public SendAble build() { 31 | return chain; 32 | } 33 | 34 | public MessageAsyncBuilder at(String id) { 35 | return append(new At(At.MEMBER_TYPE, id)); 36 | } 37 | 38 | public MessageAsyncBuilder image(String url) { 39 | return append(new Image(url)); 40 | } 41 | 42 | public MessageAsyncBuilder image(byte[] bytes) { 43 | return append(new Image(bytes)); 44 | } 45 | 46 | public MessageAsyncBuilder text(String text) { 47 | return append(new PlainText(text)); 48 | } 49 | 50 | /** 51 | * @return 52 | */ 53 | public boolean isEmpty() { 54 | return chain.isEmpty(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/ex/MessagePre.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.ex; 2 | 3 | import io.github.kloping.judge.Judge; 4 | import io.github.kloping.qqbot.api.SendAble; 5 | import io.github.kloping.qqbot.api.SenderAndCidMidGetter; 6 | import io.github.kloping.qqbot.entities.qqpd.Dms; 7 | import io.github.kloping.qqbot.entities.qqpd.message.DirectMessage; 8 | import io.github.kloping.qqbot.http.data.ActionResult; 9 | import io.github.kloping.qqbot.http.data.Result; 10 | import io.github.kloping.qqbot.impl.MessagePacket; 11 | import lombok.Data; 12 | import org.jsoup.helper.HttpConnection; 13 | 14 | import java.io.ByteArrayInputStream; 15 | 16 | import static io.github.kloping.qqbot.entities.qqpd.Channel.SEND_FORM_DATA_HEADERS; 17 | 18 | /** 19 | * 不适配 group 20 | * @author github.kloping 21 | */ 22 | @Data 23 | public class MessagePre implements SendAble { 24 | private String content = ""; 25 | private Image image; 26 | private String replyId; 27 | 28 | @Override 29 | public Result send(SenderAndCidMidGetter er) { 30 | if (image != null) { 31 | if (image.getBytes() != null) { 32 | BaseKeyVals keyVals = new BaseKeyVals(); 33 | if (er.getMid() != null) { 34 | HttpConnection.KeyVal v0 = HttpConnection.KeyVal.create("msg_id", er.getMid()); 35 | v0.contentType("text/plain"); 36 | keyVals.add(v0); 37 | } 38 | if (Judge.isNotEmpty(content)) { 39 | HttpConnection.KeyVal v1 = HttpConnection.KeyVal.create("content", content); 40 | v1.contentType("text/plain"); 41 | keyVals.add(v1); 42 | } 43 | HttpConnection.KeyVal v1 = HttpConnection.KeyVal.create("file_image", image.getName(), new ByteArrayInputStream(image.getBytes())); 44 | v1.contentType(image.getType()); 45 | keyVals.add(v1); 46 | if (er instanceof Dms) { 47 | Dms dms = (Dms) er; 48 | return new Result<>(er.getBot().dmsBase.send(dms.getGuildId(), SEND_FORM_DATA_HEADERS, keyVals)); 49 | }else if (er instanceof DirectMessage) { 50 | DirectMessage dms = (DirectMessage) er; 51 | return new Result<>(er.getBot().dmsBase.send(dms.getGuildId(), SEND_FORM_DATA_HEADERS, keyVals)); 52 | } else return new Result<>(er.getBot().messageBase.send(er.getCid(), SEND_FORM_DATA_HEADERS, keyVals)); 53 | } 54 | } 55 | return getActionResult(er, image, content, replyId); 56 | } 57 | 58 | public static Result getActionResult(SenderAndCidMidGetter er, Image image, String content, String replyId) { 59 | MessagePacket packet = new MessagePacket(); 60 | if (Judge.isNotEmpty(replyId)) packet.setReplyId(replyId); 61 | if (Judge.isNotEmpty(content)) packet.setContent(content); 62 | if (image != null && Judge.isNotEmpty(image.getUrl())) packet.setImage(image.getUrl()); 63 | return er.send(packet); 64 | } 65 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/ex/MessagePreBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.ex; 2 | 3 | import io.github.kloping.qqbot.entities.qqpd.data.Emoji; 4 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 5 | import lombok.Getter; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public class MessagePreBuilder { 11 | private MessagePre pre = new MessagePre(); 12 | @Getter 13 | private boolean empty = true; 14 | public MessagePreBuilder append(String text) { 15 | pre.setContent(pre.getContent() + text); 16 | empty = false; 17 | return this; 18 | } 19 | 20 | public MessagePreBuilder append(Image image) { 21 | pre.setImage(image); 22 | empty = false; 23 | return this; 24 | } 25 | 26 | public MessagePreBuilder append(At at) { 27 | return append(at.toString()); 28 | } 29 | 30 | public MessagePreBuilder append(AtAll at) { 31 | return append("@everyone"); 32 | } 33 | 34 | public MessagePreBuilder append(Emoji emoji) { 35 | return append(emoji.toString0()); 36 | } 37 | 38 | public MessagePreBuilder reply(RawMessage message) { 39 | pre.setReplyId(message.getId()); 40 | return this; 41 | } 42 | 43 | public MessagePre build() { 44 | return pre; 45 | } 46 | 47 | public void clear() { 48 | pre.setContent(""); 49 | empty = true; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/ex/PlainText.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.ex; 2 | 3 | import io.github.kloping.qqbot.api.SendAble; 4 | import io.github.kloping.qqbot.api.SenderAndCidMidGetter; 5 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 6 | import io.github.kloping.qqbot.http.data.Result; 7 | import io.github.kloping.qqbot.impl.MessagePacket; 8 | import lombok.Data; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | @Data 14 | public class PlainText implements SendAble { 15 | private String text; 16 | 17 | public PlainText(String text) { 18 | this.text = text; 19 | } 20 | 21 | @Override 22 | public Result send(SenderAndCidMidGetter er) { 23 | if (er.getEnvType() == EnvType.GUILD) { 24 | MessagePacket packet = new MessagePacket(); 25 | packet.setContent(toString()); 26 | return er.send(packet); 27 | } else if (er.getEnvType() == EnvType.GROUP) { 28 | return er.send(text); 29 | } else return null; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return text; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/ex/enums/EnvType.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.ex.enums; 2 | 3 | /** 4 | * 发送环境 5 | * 6 | * @author github.kloping 7 | */ 8 | public enum EnvType { 9 | GUILD, GROUP, GROUP_USER, USER; 10 | 11 | public boolean isV2() { 12 | return this == GROUP_USER || this == USER || this == GROUP; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/exc/QBotError.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.exc; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | @Data 9 | public class QBotError { 10 | private String message; 11 | private Integer code; 12 | private Integer err_code; 13 | private String trace_id; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/exceptions/ImageUploadFailedException.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.exceptions; 2 | 3 | /** 4 | * @author github.kloping 5 | */ 6 | public class ImageUploadFailedException extends RuntimeException { 7 | public ImageUploadFailedException() { 8 | } 9 | 10 | public ImageUploadFailedException(String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/ChannelType.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | /** 4 | *
描述
0 文字子频道
1 保留,不可用
2 语音子频道
3 保留,不可用
4 子频道分组
10005 直播子频道
10006 应用子频道
10007 论坛子频道
5 | * 6 | * @author github.kloping 7 | */ 8 | public enum ChannelType { 9 | TEXT_CHANNEL(0), 10 | UNKNOWN1(1), 11 | VOICE_CHANNEL(2), 12 | UNKNOWN3(3), 13 | GROUPING(4), 14 | LIVING_CHANNEL(10005), 15 | APP_CHANNEL(10006), 16 | FORUM_CHANNEL(10007), 17 | ; 18 | 19 | final int id; 20 | 21 | ChannelType(int id) { 22 | this.id = id; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/Common.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public class Common { 11 | /** 12 | * key 13 | * guild id 14 | * value 15 | * key: memberId value: 16 | */ 17 | public static final Map> GUILD_MEMBER_TEMP = new ConcurrentHashMap<>(); 18 | public static final Map> GUILD_CHANNEL_TEMP = new ConcurrentHashMap<>(); 19 | public static final Map EMPTY_MEMBER_MAP = new HashMap<>(); 20 | public static final Map EMPTY_CHANNEL_MAP = new HashMap<>(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/Dms.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import io.github.kloping.qqbot.api.DirectSender; 5 | import io.github.kloping.qqbot.api.SendAble; 6 | import io.github.kloping.qqbot.api.SenderAndCidMidGetter; 7 | import io.github.kloping.qqbot.entities.Bot; 8 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 9 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 10 | import io.github.kloping.qqbot.entities.qqpd.message.RawPreMessage; 11 | import io.github.kloping.qqbot.http.data.ActionResult; 12 | import io.github.kloping.qqbot.http.data.Result; 13 | import io.github.kloping.qqbot.impl.MessagePacket; 14 | import io.github.kloping.qqbot.utils.BaseUtils; 15 | import lombok.Data; 16 | import lombok.Getter; 17 | 18 | import static io.github.kloping.qqbot.entities.qqpd.Channel.SEND_MESSAGE_HEADERS; 19 | 20 | /** 21 | *
字段名 类型 描述
guild_id string 私信会话关联的频道 id
channel_id string 私信会话关联的子频道 id
create_time string 创建私信会话时间戳
22 | * 23 | * @author github.kloping 24 | */ 25 | @Data 26 | public class Dms implements DirectSender, SenderAndCidMidGetter { 27 | private String guildId; 28 | private String channelId; 29 | private String createTime; 30 | 31 | /** 32 | * 此方式为主动消息 33 | * 34 | * @param text 35 | * @return 36 | */ 37 | @Override 38 | public Result sendDirect(String text) { 39 | return sendDirect(new MessagePacket().setContent(text)); 40 | } 41 | 42 | /** 43 | * 此方式为主动消息 44 | * 45 | * @param text 46 | * @param message 47 | * @return 48 | */ 49 | @Override 50 | public Result sendDirect(String text, RawMessage message) { 51 | return sendDirect(new MessagePacket().setContent(text).setReplyId(message.getId())); 52 | } 53 | 54 | /** 55 | * 此方式为主动消息 56 | * 57 | * @param packet 58 | * @return 59 | */ 60 | @Override 61 | public Result sendDirect(MessagePacket packet) { 62 | RawPreMessage msg = new RawPreMessage(); 63 | BaseUtils.packet2pre(packet, msg); 64 | return new Result<>(bot.dmsBase.send(this.guildId, msg, SEND_MESSAGE_HEADERS)); 65 | } 66 | 67 | @Override 68 | public Result sendDirect(RawPreMessage msg) { 69 | return new Result<>(bot.dmsBase.send(this.guildId, msg, SEND_MESSAGE_HEADERS)); 70 | } 71 | 72 | @Override 73 | public Result send(SendAble msg) { 74 | return msg.send(this); 75 | } 76 | 77 | @Override 78 | public String getCid() { 79 | return channelId; 80 | } 81 | 82 | @Getter 83 | @JSONField(serialize = false, deserialize = false) 84 | private Bot bot; 85 | 86 | public void setBot(Bot bot) { 87 | this.bot = bot; 88 | } 89 | 90 | @Override 91 | public EnvType getEnvType() { 92 | return EnvType.GUILD; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/DmsRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | *
字段名 类型 描述
recipient_id string 接收者 id
source_guild_id string 源频道 id
8 | * 9 | * @author github.kloping 10 | */ 11 | @Data 12 | public class DmsRequest { 13 | @JSONField(name = "recipient_id") 14 | private String recipientId; 15 | @JSONField(name = "source_guild_id") 16 | private String sourceGuildId; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/Member.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import io.github.kloping.qqbot.api.AtAble; 5 | import io.github.kloping.qqbot.api.OpAble; 6 | import io.github.kloping.qqbot.api.SendAble; 7 | import io.github.kloping.qqbot.entities.ex.At; 8 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 9 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 10 | import io.github.kloping.qqbot.entities.qqpd.v2.Contact; 11 | import io.github.kloping.qqbot.http.data.Result; 12 | import lombok.*; 13 | import lombok.experimental.Accessors; 14 | 15 | /** 16 | *
字段名 类型 描述
user User 用户的频道基础信息,只有成员相关接口中会填充此信息
nick string 用户的昵称
roles string 数组 用户在频道内的身份组ID, 默认值可参考DefaultRoles
joined_at ISO8601 timestamp 用户加入频道的时间
17 | * 18 | * @author github-kloping 19 | */ 20 | @Data 21 | @Accessors(chain = true) 22 | @ToString 23 | @EqualsAndHashCode(callSuper = false) 24 | public class Member extends Contact implements OpAble, AtAble { 25 | private String nick; 26 | private String joinedAt; 27 | private String[] roles; 28 | private User user; 29 | private String opUserId; 30 | 31 | @Override 32 | public At at() { 33 | return new At("member", user.getId()); 34 | } 35 | 36 | @Getter 37 | @Setter 38 | @JSONField(serialize = false, deserialize = false) 39 | private Guild guild; 40 | 41 | @Override 42 | public String getId() { 43 | return user.getId(); 44 | } 45 | 46 | @Override 47 | public String getOpenid() { 48 | return getId(); 49 | } 50 | 51 | @Override 52 | public Result send(String text) { 53 | return getGuild().create(user.getId()).send(text); 54 | } 55 | 56 | @Override 57 | public Result send(String text, RawMessage message) { 58 | return getGuild().create(user.getId()).send(text, message); 59 | } 60 | 61 | @Override 62 | public Result send(SendAble msg) { 63 | return getGuild().create(getId()).send(msg); 64 | } 65 | 66 | @Override 67 | public String getCid() { 68 | return getGuild().create(getId()).getCid(); 69 | } 70 | 71 | @Override 72 | public EnvType getEnvType() { 73 | return EnvType.GUILD; 74 | } 75 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/MemberWithGuildID.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import io.github.kloping.qqbot.api.BotContent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.http.data.MutePack; 7 | import lombok.Data; 8 | import lombok.EqualsAndHashCode; 9 | import lombok.ToString; 10 | import lombok.experimental.Accessors; 11 | 12 | /** 13 | * 14 | * 15 | *
字段名 类型 描述
guild_id string 频道id
user{@link User} 用户的频道基础信息
nick string 用户的昵称
roles string 数组 用户在频道内的身份
joined_at ISO8601 timestamp 用户加入频道的时间
16 | * 17 | * @author github-kloping 18 | */ 19 | @Data 20 | @Accessors(chain = true) 21 | @ToString 22 | @EqualsAndHashCode(callSuper = false) 23 | public class MemberWithGuildID extends Member implements BotContent { 24 | private String guildId; 25 | 26 | /** 27 | * 禁言秒数 28 | * 29 | * @param seconds 30 | */ 31 | public void mute(int seconds) { 32 | MutePack mutePack = new MutePack(); 33 | mutePack.setMuteSeconds(seconds); 34 | bot.memberBase.muteOne(guildId, getUser().getId(), mutePack); 35 | } 36 | 37 | /** 38 | * 禁言到指定时间戳 单位:秒 39 | * 40 | * @param timestamp 41 | */ 42 | public void mute(long timestamp) { 43 | MutePack mutePack = new MutePack(); 44 | mutePack.setMuteEndTimestamp(timestamp); 45 | bot.memberBase.muteOne(guildId, getUser().getId(), mutePack); 46 | } 47 | 48 | @JSONField(serialize = false, deserialize = false) 49 | private Bot bot; 50 | 51 | public Bot getBot() { 52 | return bot; 53 | } 54 | 55 | public void setBot(Bot bot) { 56 | this.bot = bot; 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/PinsMessage.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * source 8 | *
字段名 类型 描述
guild_id string 频道 id
channel_id string 子频道 id
message_ids string 数组 子频道内精华消息 id 数组
9 | * 10 | * @author github.kloping 11 | */ 12 | public class PinsMessage { 13 | private String guild_id; 14 | private String channel_id; 15 | private List message_ids = new ArrayList<>(); 16 | 17 | public String getGuild_id() { 18 | return guild_id; 19 | } 20 | 21 | public void setGuild_id(String guild_id) { 22 | this.guild_id = guild_id; 23 | } 24 | 25 | public String getChannel_id() { 26 | return channel_id; 27 | } 28 | 29 | public void setChannel_id(String channel_id) { 30 | this.channel_id = channel_id; 31 | } 32 | 33 | public List getMessage_ids() { 34 | return message_ids; 35 | } 36 | 37 | public void setMessage_ids(List message_ids) { 38 | this.message_ids = message_ids; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/Role.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import lombok.experimental.Accessors; 7 | 8 | /** 9 | *
字段名 类型 描述
id string 身份组ID
name string 名称
color uint32 ARGB的HEX十六进制颜色值转换后的十进制数值
hoist uint32 是否在成员列表中单独展示: 0-否, 1-是
number uint32 人数
member_limit uint32 成员上限
10 | * 11 | *

# DefaultRoleIDs(系统默认生成下列身份组ID)

12 | *
身份组ID默认值 描述
1 全体成员
2 管理员
4 群主/创建者
5 子频道管理员
13 | * 14 | * @author github-kloping 15 | */ 16 | @Data 17 | @Accessors(chain = true) 18 | @ToString 19 | @EqualsAndHashCode 20 | public class Role { 21 | private Number number; 22 | private Number color; 23 | private Number memberLimit; 24 | private String name; 25 | private String id; 26 | private Number hoist; 27 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/Roles.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import lombok.experimental.Accessors; 7 | 8 | /** 9 | * 10 | * 11 | * 12 | * 13 | *
字段名 类型 描述
guild_id string 频道 ID
roles {@link Role} 对象数组 一组频道身份组对象
role_num_limit string 默认分组上限
14 | * 15 | * @author github-kloping 16 | */ 17 | @Data 18 | @Accessors(chain = true) 19 | @ToString 20 | @EqualsAndHashCode 21 | public class Roles { 22 | private String roleNumLimit; 23 | private Role[] roles; 24 | private String guildId; 25 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/User.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import lombok.experimental.Accessors; 7 | 8 | /** 9 | *

# 10 | * 用户对象(User)

11 | *

用户对象中所涉及的 ID 类数据,都仅在机器人场景流通,与真实的 ID 无关。请不要理解为真实的 ID

12 | *

# User

13 | *
14 | * 15 | * 16 | * 17 | * 18 | * 19 | * 20 | * 21 | * 22 | * 23 | * 24 | * 25 | * 26 | * 27 | * 28 | * 29 | * 30 | * 31 | * 32 | * 33 | * 34 | * 35 | * 36 | * 37 | * 38 | * 39 | * 40 | * 41 | * 42 | * 43 | * 44 | * 45 | * 46 | * 47 | * 48 | * 49 | * 50 | * 51 | * 52 | * 53 | * 54 | *
-字段名---类型----描述--
idstring用户 id
usernamestring用户名
avatarstring用户头像地址
botbool是否是机器人
union_openidstring特殊关联应用的 openid,需要特殊申请并配置后才会返回。如需申请,请联系平台运营人员。
union_user_accountstring机器人关联的互联应用的用户信息,与union_openid关联的应用是同一个。如需申请,请联系平台运营人员。
55 | *

# 提示

56 | *

union_openidunion_user_account 只有在单独拉取 member 信息的时候才会提供,在其他的事件中所携带的 user 57 | * 对象,均无这两个字段的内容。

58 | * 59 | * @author github.kloping 60 | */ 61 | @Data 62 | @Accessors(chain = true) 63 | @ToString 64 | @EqualsAndHashCode 65 | public class User { 66 | private String id; 67 | private String username; 68 | private String avatar; 69 | private Boolean bot; 70 | private String unionOpenid; 71 | private String unionUserAccount; 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/message/EmojiReaction.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.message; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import io.github.kloping.qqbot.entities.qqpd.data.Emoji; 5 | import lombok.Data; 6 | 7 | /** 8 | * 表情表态对象 9 | *
字段名 类型 描述
user_id string 用户ID
guild_id string 频道ID
channel_id string 子频道ID
target ReactionTarget 表态对象
emoji Emoji 表态所用表情
10 | * 11 | * @author github.kloping 12 | */ 13 | @Data 14 | public class EmojiReaction { 15 | private String userId; 16 | private String guildId; 17 | private String channelId; 18 | private ReactionTarget target; 19 | @JSONField(serialize = false, deserialize = false) 20 | private Emoji emoji; 21 | 22 | /** 23 | *
字段名 类型 描述
id string 表态对象ID
type ReactionTargetType 表态对象类型,参考 ReactionTargetType
24 | */ 25 | @Data 26 | public static class ReactionTarget { 27 | private String id; 28 | /** 29 | *
描述
0 消息
1 帖子
2 评论
3 回复
30 | */ 31 | private String type; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/message/MessageAttachment.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.message; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 附件 7 | * 8 | * @author github.kloping 9 | */ 10 | @Data 11 | public class MessageAttachment { 12 | private String content_type; 13 | private String filename; 14 | private String url; 15 | private String id; 16 | private Integer height; 17 | private Integer size; 18 | private Integer width; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/message/MessagePack.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.message; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | @Data 9 | public class MessagePack { 10 | private RawMessage message; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/message/MessageReference.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.message; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * 引用消息 8 | * 9 | * @author github.kloping 10 | */ 11 | @Data 12 | public class MessageReference { 13 | @JSONField(name = "message_id") 14 | private String messageId; 15 | @JSONField(name = "ignore_get_message_error") 16 | private Boolean ignoreGetMessageError = false; 17 | 18 | public MessageReference(String messageId) { 19 | this.messageId = messageId; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/message/RawPreMessage.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.message; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import io.github.kloping.qqbot.entities.ex.Markdown; 5 | import lombok.Data; 6 | import lombok.experimental.Accessors; 7 | 8 | /** 9 | *
字段名 类型 描述
content string 选填,消息内容,文本内容,支持内嵌格式
embed MessageEmbed 选填,embed 消息,一种特殊的 ark,详情参考Embed消息
ark MessageArk ark消息对象 选填,ark 消息
message_reference MessageReference 引用消息对象 选填,引用消息
image string 选填,图片url地址,平台会转存该图片,用于下发图片消息
msg_id string 选填,要回复的消息id(Message.id), 在 AT_CREATE_MESSAGE 事件中获取。
event_id string 选填,要回复的事件id, 在各事件对象中获取。
markdown MessageMarkdown markdown 消息对象 选填,markdown 消息
10 | * 11 | * @author github.kloping 12 | */ 13 | @Data 14 | @Accessors(chain = true) 15 | public class RawPreMessage { 16 | private String content; 17 | private Object embed; 18 | private Object ark; 19 | private MessageReference messageReference; 20 | /** 21 | * 这里上传图片的网址必须是经过备案的域名下的文件
否则将报错500
22 | */ 23 | private String image; 24 | @JSONField(name = "msg_id") 25 | private String msgId; 26 | private String eventId; 27 | private Markdown markdown; 28 | 29 | public RawPreMessage(String content) { 30 | this.content = content; 31 | } 32 | 33 | public RawPreMessage() { 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/message/audited/MessageAudit.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.message.audited; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import lombok.experimental.Accessors; 7 | /** 8 | * 9 | * @author github.kloping 10 | */ 11 | @Data 12 | @Accessors(chain = true) 13 | @ToString 14 | @EqualsAndHashCode 15 | public class MessageAudit { 16 | private String auditId; 17 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/message/audited/MessageAuditData.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.message.audited; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import lombok.ToString; 5 | import lombok.experimental.Accessors; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | @lombok.Data 11 | @Accessors(chain = true) 12 | @ToString 13 | @EqualsAndHashCode 14 | public class MessageAuditData { 15 | private MessageAudit messageAudit; 16 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/message/audited/MessageAudited.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.message.audited; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import lombok.ToString; 5 | import lombok.experimental.Accessors; 6 | 7 | /** 8 | * @author github-kloping 9 | */ 10 | @lombok.Data 11 | @Accessors(chain = true) 12 | @ToString 13 | @EqualsAndHashCode 14 | public class MessageAudited { 15 | private Number code; 16 | private MessageAuditData data; 17 | private String message; 18 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/v2/Contact.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.v2; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.alibaba.fastjson.annotation.JSONField; 5 | import io.github.kloping.qqbot.api.SenderAndCidMidGetter; 6 | import io.github.kloping.qqbot.entities.Bot; 7 | import lombok.Data; 8 | import lombok.Getter; 9 | import lombok.experimental.Accessors; 10 | 11 | /** 12 | * 群聊/单聊 父 13 | * 14 | * @author github.kloping 15 | */ 16 | @Data 17 | @Accessors(chain = true) 18 | public abstract class Contact implements SenderAndCidMidGetter { 19 | @JSONField(serialize = false, deserialize = false) 20 | protected JSONObject meta; 21 | 22 | public Contact() { 23 | } 24 | 25 | public Contact(JSONObject mate) { 26 | this.meta = mate; 27 | } 28 | 29 | protected String id; 30 | protected String openid; 31 | 32 | @Getter 33 | protected Bot bot; 34 | 35 | @Override 36 | public void setBot(Bot bot) { 37 | this.bot = bot; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/v2/Friend.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.v2; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import io.github.kloping.qqbot.api.SendAble; 6 | import io.github.kloping.qqbot.api.SenderAndCidMidGetter; 7 | import io.github.kloping.qqbot.api.SenderV2; 8 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 9 | import io.github.kloping.qqbot.entities.qqpd.Channel; 10 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 11 | import io.github.kloping.qqbot.http.BaseV2; 12 | import io.github.kloping.qqbot.http.data.Result; 13 | import io.github.kloping.qqbot.http.data.V2MsgData; 14 | import io.github.kloping.qqbot.http.data.V2Result; 15 | import lombok.EqualsAndHashCode; 16 | 17 | /** 18 | * @author github.kloping 19 | */ 20 | @EqualsAndHashCode(callSuper = true) 21 | public class Friend extends Contact implements SenderAndCidMidGetter, SenderV2 { 22 | public Friend(JSONObject mate) { 23 | super(mate); 24 | if (getMeta().containsKey("openid")) { 25 | String id = getMeta().getString("openid"); 26 | this.setId(id); 27 | this.setOpenid(openid); 28 | } else { 29 | this.setId(this.getMeta().getString("id")); 30 | this.setOpenid(this.getMeta().getString("user_openid")); 31 | } 32 | } 33 | 34 | @Override 35 | public Result send(String text) { 36 | V2MsgData data = new V2MsgData().setContent(text); 37 | return new Result(bot.userBaseV2.send(getOpenid(), JSON.toJSONString(data), Channel.SEND_MESSAGE_HEADERS)); 38 | } 39 | 40 | @Override 41 | public Result send(String text, RawMessage message) { 42 | return message.send(text); 43 | } 44 | 45 | @Override 46 | public Result send(SendAble msg) { 47 | return msg.send(this); 48 | } 49 | 50 | @Override 51 | public String getCid() { 52 | return getOpenid(); 53 | } 54 | 55 | @Override 56 | public EnvType getEnvType() { 57 | return EnvType.GROUP_USER; 58 | } 59 | 60 | @Override 61 | public BaseV2 getV2() { 62 | return getBot().userBaseV2; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/v2/Group.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.v2; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import io.github.kloping.judge.Judge; 6 | import io.github.kloping.qqbot.api.SendAble; 7 | import io.github.kloping.qqbot.api.SenderV2; 8 | import io.github.kloping.qqbot.entities.ex.Image; 9 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 10 | import io.github.kloping.qqbot.entities.qqpd.Channel; 11 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 12 | import io.github.kloping.qqbot.http.BaseV2; 13 | import io.github.kloping.qqbot.http.data.Result; 14 | import io.github.kloping.qqbot.http.data.V2MsgData; 15 | import io.github.kloping.qqbot.http.data.V2Result; 16 | import lombok.Getter; 17 | import lombok.experimental.Accessors; 18 | 19 | import java.util.Base64; 20 | 21 | import static io.github.kloping.qqbot.entities.qqpd.Channel.SEND_MESSAGE_HEADERS; 22 | 23 | /** 24 | * @author github.kloping 25 | */ 26 | @Getter 27 | @Accessors(chain = true) 28 | public class Group extends Contact implements SenderV2 { 29 | 30 | public Group(JSONObject mate) { 31 | super(mate); 32 | this.setId(getMeta().getString("group_id")); 33 | this.setOpenid(getMeta().getString("group_openid")); 34 | } 35 | 36 | @Override 37 | public Result send(String text) { 38 | V2MsgData data = new V2MsgData().setContent(text); 39 | return new Result(bot.groupBaseV2.send(getOpenid(), JSON.toJSONString(data), Channel.SEND_MESSAGE_HEADERS)); 40 | } 41 | 42 | @Override 43 | public Result send(String text, RawMessage message) { 44 | return message.send(text); 45 | } 46 | 47 | private V2Result sendImage(Image msg) { 48 | RawMessage.imagePrepare(msg, bot); 49 | V2Result result = null; 50 | if (Judge.isNotEmpty(msg.getUrl())) { 51 | result = bot.groupBaseV2.sendFile(getOpenid(), String.format("{\"file_type\": %s,\"url\": \"%s\",\"srv_send_msg\": false}", msg.getFile_type(), msg.getUrl()), Channel.SEND_MESSAGE_HEADERS); 52 | } else { 53 | result = bot.groupBaseV2.sendFile(getCid(), String.format("{\"file_type\": %s,\"file_data\": \"%s\",\"srv_send_msg\": false}", msg.getFile_type(), Base64.getEncoder().encodeToString(msg.getBytes())), Channel.SEND_MESSAGE_HEADERS); 54 | } 55 | result.logFileInfo(bot.logger, msg); 56 | V2MsgData data = new V2MsgData(); 57 | data.setMedia(new V2MsgData.Media(result.getFile_info())); 58 | return bot.groupBaseV2.send(getOpenid(), data.toString(), SEND_MESSAGE_HEADERS); 59 | } 60 | 61 | @Override 62 | public Result send(SendAble msg) { 63 | if (msg instanceof Image) { 64 | return new Result(sendImage((Image) msg)); 65 | } else return msg.send(this); 66 | } 67 | 68 | @Override 69 | public String getCid() { 70 | return getOpenid(); 71 | } 72 | 73 | @Override 74 | public EnvType getEnvType() { 75 | return EnvType.GROUP; 76 | } 77 | 78 | @Override 79 | public BaseV2 getV2() { 80 | return getBot().groupBaseV2; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/entities/qqpd/v2/Member.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.entities.qqpd.v2; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import io.github.kloping.qqbot.api.SendAble; 6 | import io.github.kloping.qqbot.api.SenderAndCidMidGetter; 7 | import io.github.kloping.qqbot.api.SenderV2; 8 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 9 | import io.github.kloping.qqbot.entities.qqpd.Channel; 10 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 11 | import io.github.kloping.qqbot.http.BaseV2; 12 | import io.github.kloping.qqbot.http.data.Result; 13 | import io.github.kloping.qqbot.http.data.V2MsgData; 14 | import io.github.kloping.qqbot.http.data.V2Result; 15 | import lombok.EqualsAndHashCode; 16 | 17 | /** 18 | * @author github.kloping 19 | */ 20 | @EqualsAndHashCode(callSuper = true) 21 | public class Member extends Contact implements SenderAndCidMidGetter, SenderV2 { 22 | public Member(JSONObject mate) { 23 | super(mate); 24 | this.setId(this.getMeta().getString("id")); 25 | this.setOpenid(this.getMeta().getString("member_openid")); 26 | } 27 | 28 | @Override 29 | public Result send(String text) { 30 | V2MsgData data = new V2MsgData().setContent(text); 31 | return new Result(bot.userBaseV2.send(getOpenid(), JSON.toJSONString(data), Channel.SEND_MESSAGE_HEADERS)); 32 | } 33 | 34 | @Override 35 | public Result send(String text, RawMessage message) { 36 | return message.send(text); 37 | } 38 | 39 | @Override 40 | public Result send(SendAble msg) { 41 | return msg.send(this); 42 | } 43 | 44 | @Override 45 | public String getCid() { 46 | return getOpenid(); 47 | } 48 | 49 | @Override 50 | public EnvType getEnvType() { 51 | return EnvType.GROUP_USER; 52 | } 53 | 54 | @Override 55 | public BaseV2 getV2() { 56 | return getBot().userBaseV2; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/AuthV2Base.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.Headers; 4 | import io.github.kloping.spt.annotations.http.HttpClient; 5 | import io.github.kloping.spt.annotations.http.PostPath; 6 | import io.github.kloping.spt.annotations.http.RequestBody; 7 | import io.github.kloping.qqbot.http.data.Token; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * @author github.kloping 13 | */ 14 | @HttpClient("https://bots.qq.com/") 15 | public interface AuthV2Base { 16 | /** 17 | *
属性 类型 必填 说明
appId string 在开放平台管理端上获得。
clientSecret string 在开放平台管理端上获得。
18 | * 19 | * @return 20 | */ 21 | @PostPath("/app/getAppAccessToken") 22 | Token auth(@RequestBody String body, @Headers Map headers); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/BaseV2.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.Headers; 4 | import io.github.kloping.spt.annotations.http.RequestBody; 5 | import io.github.kloping.qqbot.http.data.V2Result; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * base v2 11 | */ 12 | public interface BaseV2 { 13 | V2Result send(String gid, @RequestBody String body, @Headers Map headers); 14 | 15 | V2Result sendFile(String gid, @RequestBody String body, @Headers Map headers); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/BotBase.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.GetPath; 4 | import io.github.kloping.spt.annotations.http.Headers; 5 | import io.github.kloping.spt.annotations.http.HttpClient; 6 | import io.github.kloping.qqbot.Starter; 7 | import io.github.kloping.qqbot.http.data.UrlPack; 8 | 9 | /** 10 | * @author github.kloping 11 | */ 12 | @HttpClient(Starter.NET_POINT) 13 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 14 | public interface BotBase { 15 | /** 16 | * 获取网关 17 | * 18 | * @return 19 | */ 20 | @GetPath("/gateway") 21 | UrlPack gateway(); 22 | 23 | /** 24 | * 获取网关 gateway/bot 25 | * 26 | * @return 27 | */ 28 | @GetPath("/gateway/bot") 29 | UrlPack gateway0(); 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/ChannelBase.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.*; 4 | import io.github.kloping.qqbot.Starter; 5 | import io.github.kloping.qqbot.entities.qqpd.Channel; 6 | import io.github.kloping.qqbot.entities.qqpd.PinsMessage; 7 | import io.github.kloping.qqbot.entities.qqpd.message.MessagePack; 8 | import org.jsoup.Connection; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | @HttpClient(Starter.NET_POINT) 14 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 15 | public interface ChannelBase { 16 | /** 17 | * 获取子频道详情 18 | * 19 | * @param cid 20 | * @return 21 | */ 22 | @GetPath("/channels/{channel_id}") 23 | Channel getChannel(@PathValue("channel_id") String cid); 24 | 25 | /** 26 | * 获取指定消息 27 | * 28 | * @param cid 29 | * @param mid 30 | * @return 31 | */ 32 | @GetPath("/channels/{channel_id}/messages/{message_id}") 33 | MessagePack getMessageById(@PathValue("channel_id") String cid, @PathValue("message_id") String mid); 34 | 35 | /** 36 | * 添加一个emoji 37 | * 38 | * @param cid 39 | * @param mid 40 | * @param type 41 | * @param id 42 | * @return 43 | */ 44 | @RequestPath(method = Connection.Method.PUT, value = "/channels/{channel_id}/messages/{message_id}/reactions/{type}/{id}") 45 | void addEmoji(@PathValue("channel_id") String cid, @PathValue("message_id") String mid, @PathValue("type") Integer type, @PathValue("id") String id); 46 | 47 | /** 48 | * 移除一个emoji 49 | * 50 | * @param cid 51 | * @param mid 52 | * @param type 53 | * @param id 54 | * @return 55 | */ 56 | @RequestPath(method = Connection.Method.DELETE, value = "/channels/{channel_id}/messages/{message_id}/reactions/{type}/{id}") 57 | void removeEmoji(@PathValue("channel_id") String cid, @PathValue("message_id") String mid, @PathValue("type") Integer type, @PathValue("id") String id); 58 | 59 | 60 | /** 61 | * 添加至精华消息 62 | * 63 | * @param cid 64 | * @param mid 65 | * @return 66 | */ 67 | @RequestPath(method = Connection.Method.PUT, value = "/channels/{channel_id}/pins/{message_id}") 68 | String addPins(@PathValue("channel_id") String cid, @PathValue("message_id") String mid); 69 | 70 | 71 | /** 72 | * 移除精华消息 73 | * 74 | * @param cid 75 | * @param mid all 为全部 76 | * @return 77 | */ 78 | @RequestPath(method = Connection.Method.DELETE, value = "/channels/{channel_id}/pins/{message_id}") 79 | PinsMessage deletePins(@PathValue("channel_id") String cid, @PathValue("message_id") String mid); 80 | 81 | /** 82 | * 获取精华消息 83 | * 84 | * @param cid 85 | * @return 86 | */ 87 | @GetPath("/channels/{channel_id}/pins") 88 | PinsMessage getPins(@PathValue("channel_id") String cid); 89 | 90 | 91 | /** 92 | * 删除 93 | * 94 | * @param cid 95 | */ 96 | @RequestPath(value = "/channels/{channel_id}", method = Connection.Method.DELETE) 97 | void delete(@PathValue("channel_id") String cid); 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/DmsBase.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.*; 4 | import io.github.kloping.spt.entity.KeyVals; 5 | import io.github.kloping.qqbot.Starter; 6 | import io.github.kloping.qqbot.entities.qqpd.Dms; 7 | import io.github.kloping.qqbot.entities.qqpd.DmsRequest; 8 | import io.github.kloping.qqbot.entities.qqpd.message.RawPreMessage; 9 | import io.github.kloping.qqbot.http.data.ActionResult; 10 | 11 | import java.util.Map; 12 | 13 | import static org.jsoup.Connection.Method.DELETE; 14 | 15 | /** 16 | * @author github.kloping 17 | */ 18 | @HttpClient(Starter.NET_POINT) 19 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 20 | public interface DmsBase { 21 | /** 22 | * send a Direct message 23 | * 24 | * @param gid 25 | * @param body 26 | * @param headers 27 | * @return 28 | */ 29 | @PostPath("/dms/{guild_id}/messages") 30 | @Callback("io.github.kloping.qqbot.http.data.ActionResult.doc") 31 | ActionResult send(@PathValue("guild_id") String gid, @RequestBody(type = RequestBody.type.json) RawPreMessage body, 32 | @Headers Map headers); 33 | 34 | @PostPath("/dms/{guild_id}/messages") 35 | @Callback("io.github.kloping.qqbot.http.data.ActionResult.doc") 36 | ActionResult send(@PathValue("guild_id") String gid, @Headers Map headers, @RequestData KeyVals data); 37 | 38 | /** 39 | * create The session 40 | * 41 | * @param request 42 | * @param header0 43 | * @return 44 | */ 45 | @PostPath("/users/@me/dms") 46 | Dms create(@RequestBody(type = RequestBody.type.json) DmsRequest request, @Headers Map header0); 47 | 48 | /** 49 | * 撤回一条消息 50 | * 51 | * @param gid 52 | * @param mid 53 | * @param hidetip 54 | * @return 55 | */ 56 | @RequestPath(method = DELETE, value = "/dms/{guild_id}/messages/{message_id}") 57 | Object delete(@PathValue("guild_id") String gid, 58 | @PathValue("message_id") String mid, @ParamName("hidetip") Boolean hidetip); 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/GroupBaseV2.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.*; 4 | import io.github.kloping.qqbot.Starter; 5 | import io.github.kloping.qqbot.http.data.V2Result; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | *
基本
HTTP URL /v2/groups/{group_openid}/messages
HTTP Method POST
11 | *
12 | *
属性 类型 必填 说明
group_openid string 群聊的 openid
13 | * 14 | * @author github.kloping 15 | */ 16 | @HttpClient(Starter.NET_POINT) 17 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 18 | public interface GroupBaseV2 extends BaseV2{ 19 | /** 20 | * 发送群聊消息 21 | * @param gid 22 | * @param body 23 | * @param headers 24 | * @return msg 25 | */ 26 | @PostPath("/v2/groups/{group_openid}/messages") 27 | V2Result send(@PathValue("group_openid") String gid, @RequestBody String body, @Headers Map headers); 28 | 29 | /** 30 | * 发送群聊媒体 31 | *
属性 类型 必填 说明
file_type int 媒体类型:1 图片,2 视频,3 语音,4 文件(暂不开放)
资源格式要求
图片:png/jpg,视频:mp4,语音:silk
url string 需要发送媒体资源的url
srv_send_msg bool 设置 true 会直接发送消息到目标端,且会占用主动消息频次
file_data 【暂未支持】
32 | * @param gid 33 | * @param body 34 | * @param headers 35 | * @return 文件id 36 | */ 37 | @PostPath("/v2/groups/{group_openid}/files") 38 | V2Result sendFile(@PathValue("group_openid") String gid, @RequestBody String body, @Headers Map headers); 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/GuildBase.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.*; 4 | import io.github.kloping.qqbot.Starter; 5 | import io.github.kloping.qqbot.entities.ex.ChannelData; 6 | import io.github.kloping.qqbot.entities.qqpd.Channel; 7 | import io.github.kloping.qqbot.entities.qqpd.Guild; 8 | import io.github.kloping.qqbot.entities.qqpd.Member; 9 | import io.github.kloping.qqbot.entities.qqpd.Roles; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | * @author github.kloping 15 | */ 16 | @HttpClient(Starter.NET_POINT) 17 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 18 | public interface GuildBase { 19 | /** 20 | * get guilds 21 | * 22 | * @return 23 | */ 24 | @GetPath("/users/@me/guilds") 25 | Guild[] getGuilds(); 26 | 27 | /** 28 | * get a guild 29 | * 30 | * @param gid 31 | * @return 32 | */ 33 | @GetPath("/guilds/{gid}") 34 | Guild getGuild(@PathValue("gid") String gid); 35 | 36 | /** 37 | * get channels 38 | * 39 | * @param gid 40 | * @return 41 | */ 42 | @GetPath("/guilds/{gid}/channels") 43 | Channel[] getChannels(@PathValue("gid") String gid); 44 | 45 | /** 46 | * get members 47 | * 48 | * @param gid 49 | * @param num 50 | * @return 51 | */ 52 | @GetPath("/guilds/{guild_id}/members") 53 | Member[] getMembers(@PathValue("guild_id") String gid, @ParamName("limit") Integer num); 54 | 55 | /** 56 | * get member 57 | * 58 | * @param gid 59 | * @param userId 60 | * @return 61 | */ 62 | @GetPath("/guilds/{guild_id}/members/{user_id}") 63 | Member getMember(@PathValue("guild_id") String gid, @PathValue("user_id") String userId); 64 | 65 | /** 66 | * get roles 67 | * 68 | * @param gid 69 | * @return 70 | */ 71 | @GetPath("/guilds/{guild_id}/roles") 72 | Roles getRoles(@PathValue("guild_id") String gid); 73 | 74 | /** 75 | * 创建一个子频道 76 | * 77 | * @param headers 78 | * @param gid 79 | * @param data 80 | * @return 81 | */ 82 | @PostPath("/guilds/{guild_id}/channels") 83 | Channel create(@Headers Map headers, @PathValue("guild_id") String gid, @RequestBody ChannelData data); 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/InterActionBase.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.*; 4 | import io.github.kloping.qqbot.Starter; 5 | import org.jsoup.Connection; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | @HttpClient(Starter.NET_POINT) 11 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 12 | public interface InterActionBase { 13 | /** 14 | *
属性 类型 必填 说明
interaction_id string 上述事件中获得。
15 | *
属性 类型 必填 说明
code int 0 成功
1 操作失败
2 操作频繁
3 重复操作
4 没有权限
5 仅管理员操作
16 | * @param interaction_id 17 | * 18 | * @param body 19 | */ 20 | @RequestPath(value = "/interactions/{interaction_id}", method = Connection.Method.PUT) 21 | void response(@PathValue("interaction_id") String interaction_id, @RequestBody String body); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/MemberBase.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.*; 4 | import io.github.kloping.qqbot.Starter; 5 | import io.github.kloping.qqbot.http.data.MutePack; 6 | import org.jsoup.Connection; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | @HttpClient(Starter.NET_POINT) 12 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 13 | public interface MemberBase { 14 | 15 | /** 16 | * 禁言指定 17 | * 18 | * @param guild 19 | * @param id 20 | * @param mute 21 | */ 22 | @RequestPath(method = Connection.Method.PATCH, value = "/guilds/{guild_id}/members/{user_id}/mute") 23 | void muteOne(@PathValue("guild_id") String guild, @PathValue("user_id") String id, @RequestBody MutePack mute); 24 | 25 | /** 26 | * 禁言群体 全部 or 多个 27 | * 28 | * @param guild 29 | * @param mute 30 | */ 31 | @RequestPath(method = Connection.Method.PATCH, value = "/guilds/{guild_id}/mute") 32 | void muteOne(@PathValue("guild_id") String guild, @RequestBody MutePack mute); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/MessageBase.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.*; 4 | import io.github.kloping.spt.entity.KeyVals; 5 | import io.github.kloping.qqbot.Starter; 6 | import io.github.kloping.qqbot.http.data.ActionResult; 7 | 8 | import java.util.Map; 9 | 10 | import static org.jsoup.Connection.Method.DELETE; 11 | 12 | /** 13 | *
字段名 类型 描述
content string 选填,消息内容,文本内容,支持内嵌格式
embed MessageEmbed 选填,embed 消息,一种特殊的 ark,详情参考Embed消息
ark MessageArk ark消息对象 选填,ark 消息
message_reference MessageReference 引用消息对象 选填,引用消息
image string 选填,图片url地址,平台会转存该图片,用于下发图片消息
msg_id string 选填,要回复的消息id(Message.id), 在 AT_CREATE_MESSAGE 事件中获取。
markdown MessageMarkdown markdown 消息对象 选填,markdown 消息
14 | * 15 | * @author github.kloping 16 | */ 17 | @HttpClient(Starter.NET_POINT) 18 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 19 | public interface MessageBase { 20 | /** 21 | * send a message 22 | * 23 | * @param cid 24 | * @param body 25 | * @param headers 26 | * @return 27 | */ 28 | @PostPath("/channels/{channel_id}/messages") 29 | @Callback("io.github.kloping.qqbot.http.data.ActionResult.doc") 30 | ActionResult send(@PathValue("channel_id") String cid, @RequestBody(type = RequestBody.type.json) Object body, @Headers Map headers); 31 | 32 | /** 33 | * send a message 34 | * 35 | * @param cid 36 | * @param headers 37 | * @param bytes 38 | * @param data 39 | * @return 40 | */ 41 | @PostPath("/channels/{channel_id}/messages") 42 | @Callback("io.github.kloping.qqbot.http.data.ActionResult.doc") 43 | ActionResult send(@PathValue("channel_id") String cid, @Headers Map headers, 44 | @FileParm(value = "file_image", name = "temp.jpg", type = "image/jpg") byte[] bytes, 45 | @RequestData KeyVals data); 46 | 47 | /** 48 | * send a message 49 | * 50 | * @param cid 51 | * @param headers 52 | * @param data 53 | * @return 54 | */ 55 | @PostPath("/channels/{channel_id}/messages") 56 | @Callback("io.github.kloping.qqbot.http.data.ActionResult.doc") 57 | ActionResult send(@PathValue("channel_id") String cid, @Headers Map headers, @RequestData KeyVals data); 58 | 59 | 60 | /** 61 | * 撤回一条消息 62 | * 63 | * @param cid 64 | * @param mid 65 | * @param hidetip 66 | * @return 67 | */ 68 | @RequestPath(method = DELETE, value = "/channels/{channel_id}/messages/{message_id}") 69 | Object delete(@PathValue("channel_id") String cid, 70 | @PathValue("message_id") String mid, @ParamName("hidetip") Boolean hidetip); 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/UserBase.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.GetPath; 4 | import io.github.kloping.spt.annotations.http.Headers; 5 | import io.github.kloping.spt.annotations.http.HttpClient; 6 | import io.github.kloping.qqbot.entities.qqpd.User; 7 | 8 | import static io.github.kloping.qqbot.Starter.NET_POINT; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | @HttpClient(NET_POINT) 14 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 15 | public interface UserBase { 16 | /** 17 | * bot info 18 | * 19 | * @return 20 | */ 21 | @GetPath("/users/@me") 22 | User botInfo(); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/UserBaseV2.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http; 2 | 3 | import io.github.kloping.spt.annotations.http.*; 4 | import io.github.kloping.qqbot.Starter; 5 | import io.github.kloping.qqbot.http.data.V2Result; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | *
基本
HTTP URL /v2/groups/{group_openid}/messages
HTTP Method POST
11 | *
12 | *
属性 类型 必填 说明
group_openid string 群聊的 openid
13 | * 14 | * @author github.kloping 15 | */ 16 | @HttpClient(Starter.NET_POINT) 17 | @Headers("io.github.kloping.qqbot.Start0.getHeaders") 18 | public interface UserBaseV2 extends BaseV2 { 19 | /** 20 | * 发送私聊消息 21 | * @param uid 22 | * @param body 23 | * @param headers 24 | * @return msg 25 | */ 26 | @PostPath("/v2/users/{openid}/messages") 27 | V2Result send(@PathValue("openid") String uid, @RequestBody String body, @Headers Map headers); 28 | 29 | /** 30 | * 发送私聊媒体 31 | * @param uid 32 | * @param body 33 | * @param headers 34 | * @return 文件id 35 | */ 36 | @PostPath("/v2/users/{openid}/files") 37 | V2Result sendFile(@PathValue("openid") String uid, @RequestBody String body, @Headers Map headers); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/data/ActionResult.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http.data; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.entities.ex.msg.MessageChain; 5 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 6 | import io.github.kloping.qqbot.entities.qqpd.message.audited.MessageAudited; 7 | import io.github.kloping.qqbot.utils.BaseUtils; 8 | import lombok.Getter; 9 | import lombok.ToString; 10 | 11 | /** 12 | * @author github.kloping 13 | */ 14 | @Getter 15 | @ToString 16 | public class ActionResult { 17 | public static ActionResult doc(String json) { 18 | try { 19 | RawMessage message = JSONObject.parseObject(json, RawMessage.class); 20 | if (message.getId() != null) return new ActionResult(message, null); 21 | else return new ActionResult(null, JSONObject.parseObject(json, MessageAudited.class)); 22 | } catch (Exception e) { 23 | return null; 24 | } 25 | } 26 | 27 | private Boolean sent; 28 | private RawMessage rawMessage; 29 | private MessageAudited messageAudited; 30 | 31 | public ActionResult(RawMessage rawMessage, MessageAudited messageAudited) { 32 | this.rawMessage = rawMessage; 33 | this.messageAudited = messageAudited; 34 | sent = rawMessage == null ? false : true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/data/MutePack.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http.data; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import io.github.kloping.judge.Judge; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | public class MutePack { 14 | private String mute_end_timestamp; 15 | private String mute_seconds; 16 | private List user_ids = new ArrayList<>(); 17 | 18 | public void setMuteEndTimestamp(long timestamp) { 19 | this.mute_end_timestamp = String.valueOf(timestamp); 20 | } 21 | 22 | public void setMuteSeconds(int sec) { 23 | this.mute_seconds = String.valueOf(sec); 24 | } 25 | 26 | public List getUserIds() { 27 | return user_ids; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | JSONObject jo = new JSONObject(); 33 | if (Judge.isNotEmpty(mute_end_timestamp)) { 34 | jo.put("mute_end_timestamp", mute_end_timestamp); 35 | } else if (Judge.isNotEmpty(mute_seconds)) { 36 | jo.put("mute_seconds", mute_seconds); 37 | } 38 | if (!user_ids.isEmpty()) { 39 | jo.put("user_ids", JSON.toJSONString(user_ids)); 40 | } 41 | return jo.toString(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/data/Result.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http.data; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | @Data 9 | public class Result { 10 | private String msg; 11 | private D data; 12 | 13 | public Result(D data) { 14 | this.data = data; 15 | } 16 | 17 | public Result() { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/data/Token.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http.data; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | import lombok.experimental.Accessors; 6 | 7 | /** 8 | * { 9 | * "access_token": "ACCESS_TOKEN", 10 | * "expires_in": "7200" 11 | * } 12 | *
属性 类型 说明
access_token string 获取到的凭证。
expires_in number 凭证有效时间,单位:秒。目前是7200秒之内的值。
13 | * 14 | * @author github.kloping 15 | */ 16 | @Data 17 | @Accessors(chain = true) 18 | public class Token { 19 | private String access_token; 20 | private String expires_in; 21 | 22 | /** 23 | * 用来记录获取时的时间戳 24 | */ 25 | @JSONField(serialize = false, deserialize = false) 26 | private Long t0; 27 | 28 | /** 29 | * @return true 当前时间 > 过期截止 30 | */ 31 | public boolean isExpired() { 32 | Integer sec = Integer.valueOf(expires_in); 33 | Integer secto = (sec * 1000); 34 | Long t = t0 + secto; 35 | return System.currentTimeMillis() >= t; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/data/UrlPack.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http.data; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public class UrlPack { 9 | private String url; 10 | 11 | public String getUrl() { 12 | return url; 13 | } 14 | 15 | public void setUrl(String url) { 16 | this.url = url; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "UrlPack{" + 22 | "url='" + url + '\'' + 23 | '}'; 24 | } 25 | 26 | @Override 27 | public boolean equals(Object o) { 28 | if (this == o) return true; 29 | if (o == null || getClass() != o.getClass()) return false; 30 | UrlPack urlPack = (UrlPack) o; 31 | return Objects.equals(url, urlPack.url); 32 | } 33 | 34 | @Override 35 | public int hashCode() { 36 | return Objects.hash(url); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/data/V2MsgData.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http.data; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import io.github.kloping.qqbot.entities.ex.Markdown; 5 | import lombok.Data; 6 | import lombok.Getter; 7 | import lombok.experimental.Accessors; 8 | 9 | /** 10 | *
11 | * *
属性 类型 必填 说明
content string 文本内容
msg_type int 消息类型: 0 是文本,1 图文混排 ,2 是 markdown 3 ark,4 embed
markdown object 格式参考"消息类型=>markdown=>数据结构与协议"
keyboard object 格式参考"消息交互=>消息按钮=>数据结构与协"
ark object 格式参考"消息类型=>ark=>数据结构与协议"
image 【暂不支持】
message_reference object 【暂未支持】消息引用
event_id string 【暂未支持】前置收到的事件ID,用于发送被动消息
msg_id string 前置收到的消息ID,用于发送被动消息
12 | * * 13 | * 14 | * @author github.kloping 15 | */ 16 | @Data 17 | @Accessors(chain = true) 18 | public class V2MsgData { 19 | private String content = ""; 20 | private Integer msg_type = 0; 21 | private String image = null; 22 | private Media media; 23 | private Markdown markdown; 24 | private Object keyboard; 25 | private String msg_id; 26 | private Integer msg_seq; 27 | 28 | @Override 29 | public String toString() { 30 | return JSON.toJSONString(this); 31 | } 32 | 33 | @Getter 34 | public static class Media { 35 | private String file_info; 36 | 37 | public Media(String file_info) { 38 | this.file_info = file_info; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/http/data/V2Result.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.http.data; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import io.github.kloping.spt.interfaces.Logger; 7 | import io.github.kloping.judge.Judge; 8 | import io.github.kloping.qqbot.entities.ex.Image; 9 | import io.github.kloping.qqbot.entities.exceptions.ImageUploadFailedException; 10 | import lombok.Data; 11 | 12 | import java.text.ParseException; 13 | import java.text.SimpleDateFormat; 14 | 15 | /** 16 | * 官方文档 17 | *
属性 类型 说明
id string 消息唯一ID
timestamp int 发送时间
18 | * 实际则 19 | *
20 | * {"group_code":"","ret":1,"msg":""} 21 | * @author github.kloping 22 | */ 23 | @Data 24 | public class V2Result { 25 | private String id; 26 | private Long timestamp; 27 | 28 | private String group_code; 29 | private Integer ret = 200; 30 | private String msg; 31 | 32 | private String file_uuid; 33 | private String file_info; 34 | private Integer ttl; 35 | 36 | public static String docMsg(String json) { 37 | V2Result result = JSON.parseObject(json, V2Result.class); 38 | if (Judge.isNotEmpty(result.getMsg())) return result.getMsg(); 39 | else return ""; 40 | } 41 | 42 | public static String docFiles(String json) { 43 | JSONObject data = JSON.parseObject(json); 44 | if (Judge.isEmpty(data.getString("file_uuid"))) return ""; 45 | else return data.getString("file_uuid"); 46 | } 47 | 48 | public void logFileInfo(Logger logger, Image image) { 49 | if (file_uuid == null) 50 | throw new ImageUploadFailedException(String.format("Failed to upload image(%s)", image.getUrl())); 51 | logger.info("file uuid: " + file_uuid); 52 | } 53 | 54 | @JSONField(deserialize = false, serialize = false) 55 | public static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); 56 | 57 | public void setTimestamp(String timestamp) { 58 | try { 59 | Long t0 = format.parse(timestamp).getTime(); 60 | this.timestamp = t0; 61 | } catch (ParseException e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/BaseChannelEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.HttpClientConfig; 5 | import io.github.kloping.qqbot.api.event.ChannelEvent; 6 | import io.github.kloping.qqbot.entities.Bot; 7 | import io.github.kloping.qqbot.entities.qqpd.Channel; 8 | 9 | /** 10 | * @author github.kloping 11 | */ 12 | public class BaseChannelEvent extends BaseGuildEvent implements ChannelEvent { 13 | private Channel channel; 14 | 15 | public BaseChannelEvent(JSONObject jo, Bot bot) { 16 | super(jo, bot); 17 | channel = jo.toJavaObject(Channel.class); 18 | channel.setBot(bot); 19 | } 20 | 21 | @Override 22 | public Channel getChannel() { 23 | return channel; 24 | } 25 | 26 | @Override 27 | public String getId() { 28 | return getMetadata().get("id").toString(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/BaseChannelUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.event.ChannelUpdateEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public class BaseChannelUpdateEvent extends BaseChannelEvent implements ChannelUpdateEvent { 11 | public BaseChannelUpdateEvent(JSONObject jo, Bot bot) { 12 | super(jo, bot); 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return String.format("子频道'%s'信息更新", getChannel().getName()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/BaseConnectedEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.event.ConnectedEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | 7 | /** 8 | * version show 9 | * 10 | * @author github.kloping 11 | */ 12 | public class BaseConnectedEvent implements ConnectedEvent { 13 | protected JSONObject metadata; 14 | protected Bot bot; 15 | private String sessionId; 16 | 17 | public BaseConnectedEvent(JSONObject metadata, Bot bot, String sessionId) { 18 | this.metadata = metadata; 19 | this.bot = bot; 20 | this.sessionId = sessionId; 21 | } 22 | 23 | @Override 24 | public Bot getBot() { 25 | return bot; 26 | } 27 | 28 | @Override 29 | public JSONObject getMetadata() { 30 | return metadata; 31 | } 32 | 33 | @Override 34 | public String getSessionId() { 35 | return sessionId; 36 | } 37 | 38 | @Override 39 | public String getClassName() { 40 | return ConnectedEvent.class.getSimpleName(); 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return String.format(FORMAT, bot.getConfig().getAppid()); 46 | } 47 | 48 | @Override 49 | public String getId() { 50 | return getMetadata().get("id").toString(); 51 | } 52 | 53 | public static final String VERSION = "1.5.2-L1"; 54 | public static final String PROJECT_NAME = "qqpd-bot-java"; 55 | public static final String AUTHOR = "kloping"; 56 | public static final String FORMAT = "Bot(%s) connected! By " + AUTHOR + " of " + PROJECT_NAME + " v" + VERSION; 57 | public static final String FORMAT_SERVER = "Bot(%s) webhook server started! By " + AUTHOR + " of " + PROJECT_NAME + " v" + VERSION; 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/BaseGuildEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.event.GuildEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.Guild; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | public abstract class BaseGuildEvent implements GuildEvent { 12 | protected JSONObject metadata; 13 | protected Guild guild; 14 | 15 | protected Bot bot; 16 | 17 | public BaseGuildEvent() { 18 | } 19 | 20 | public BaseGuildEvent(JSONObject jo, Bot bot) { 21 | this.metadata = jo; 22 | this.bot = bot; 23 | this.guild = jo.toJavaObject(Guild.class); 24 | getBot().setGuild(guild); 25 | if (this.guild != null) guild.setBot(getBot()); 26 | } 27 | 28 | @Override 29 | public JSONObject getMetadata() { 30 | return metadata; 31 | } 32 | 33 | @Override 34 | public Guild getGuild() { 35 | return guild; 36 | } 37 | 38 | @Override 39 | public Bot getBot() { 40 | return bot; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/BaseGuildUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.event.GuildUpdateEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public class BaseGuildUpdateEvent extends BaseGuildEvent implements GuildUpdateEvent { 11 | public BaseGuildUpdateEvent(JSONObject jo, Bot bot) { 12 | super(jo, bot); 13 | } 14 | 15 | @Override 16 | public String getUnionAppId() { 17 | return getMetadata().getString("union_appid"); 18 | } 19 | 20 | @Override 21 | public String getUnionOrgId() { 22 | return getMetadata().getString("union_org_id"); 23 | } 24 | 25 | @Override 26 | public String getUnionWorldId() { 27 | return getMetadata().getString("union_world_id"); 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return String.format("guild(%s) id(%s) info change", guild.getName(), guild.getId()); 33 | } 34 | 35 | @Override 36 | public String getId() { 37 | return getMetadata().get("id").toString(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/BaseInterActionEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.SendAble; 5 | import io.github.kloping.qqbot.api.event.InterActionEvent; 6 | import io.github.kloping.qqbot.entities.Bot; 7 | import io.github.kloping.qqbot.entities.qqpd.InterAction; 8 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 9 | import io.github.kloping.qqbot.http.data.Result; 10 | 11 | /** 12 | * @author github.kloping 13 | */ 14 | public class BaseInterActionEvent implements InterActionEvent { 15 | 16 | public BaseInterActionEvent(Bot bot, JSONObject metaData) { 17 | interAction = metaData.toJavaObject(InterAction.class); 18 | interAction.setBot(bot); 19 | } 20 | 21 | private JSONObject metaData; 22 | private InterAction interAction; 23 | 24 | @Override 25 | public Result send(String text) { 26 | return getInterAction().send(text); 27 | } 28 | 29 | @Override 30 | public Result send(String text, RawMessage message) { 31 | return getInterAction().send(text, message); 32 | } 33 | 34 | @Override 35 | public Result send(SendAble msg) { 36 | return getInterAction().send(msg); 37 | } 38 | 39 | @Override 40 | public JSONObject getMetadata() { 41 | return metaData; 42 | } 43 | 44 | @Override 45 | public Bot getBot() { 46 | return getInterAction().getBot(); 47 | } 48 | 49 | @Override 50 | public Integer getChatType() { 51 | return getInterAction().getChat_type(); 52 | } 53 | 54 | @Override 55 | public InterAction getInterAction() { 56 | return interAction; 57 | } 58 | 59 | @Override 60 | public void response(int code) { 61 | getBot().interActionBase.response(getInterAction().getId(), String.format("{\"code\": %s}", code)); 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return String.format("InterActionEvent [button %s(%s)] from %s" 67 | , getInterAction().getData().getResolved().getButton_data() 68 | , getInterAction().getData().getResolved().getButton_id() 69 | , getInterAction().getCid()); 70 | } 71 | 72 | @Override 73 | public String getId() { 74 | return getMetadata().get("id").toString(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/BaseMemberRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.event.MemberUpdateEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.MemberWithGuildID; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | public class BaseMemberRemoveEvent extends BaseGuildEvent implements MemberUpdateEvent { 12 | 13 | public BaseMemberRemoveEvent(JSONObject jo, Bot bot) { 14 | super(); 15 | this.metadata = jo; 16 | this.bot = bot; 17 | this.member = jo.toJavaObject(MemberWithGuildID.class); 18 | this.guild = getBot().getGuild(member.getGuildId()); 19 | this.member.setGuild(guild); 20 | if (member != null) member.setBot(bot); 21 | } 22 | 23 | protected MemberWithGuildID member; 24 | 25 | @Override 26 | public MemberWithGuildID getMember() { 27 | return member; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return String.format("member(%s) remove from %s", member.getNick(), guild.getName()); 33 | } 34 | 35 | @Override 36 | public String getId() { 37 | return getMetadata().get("id").toString(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/BaseMemberUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.event.MemberUpdateEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.MemberWithGuildID; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | public class BaseMemberUpdateEvent extends BaseGuildEvent implements MemberUpdateEvent { 12 | 13 | public BaseMemberUpdateEvent(JSONObject jo, Bot bot) { 14 | super(); 15 | this.metadata = jo; 16 | this.bot = bot; 17 | this.member = jo.toJavaObject(MemberWithGuildID.class); 18 | if (member != null) member.setBot(bot); 19 | this.guild = getBot().getGuild(member.getGuildId()); 20 | this.member.setGuild(guild); 21 | getGuild().setMember(member); 22 | } 23 | 24 | protected MemberWithGuildID member; 25 | 26 | @Override 27 | public MemberWithGuildID getMember() { 28 | return member; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return String.format("member(%s) in %s info change", member.getNick(), guild.getName()); 34 | } 35 | 36 | @Override 37 | public String getId() { 38 | return getMetadata().get("id").toString(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/ListenerHost.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.RetentionPolicy; 5 | import java.lang.annotation.Target; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public abstract class ListenerHost { 11 | /** 12 | * 错误抛出处理 13 | * 14 | * @param e 15 | * @return true 继续日志打印报错 16 | */ 17 | public boolean handleException(Throwable e) { 18 | return true; 19 | } 20 | 21 | @Override 22 | public int hashCode() { 23 | return super.hashCode(); 24 | } 25 | 26 | @Override 27 | public boolean equals(Object obj) { 28 | return super.equals(obj); 29 | } 30 | 31 | @Override 32 | protected Object clone() throws CloneNotSupportedException { 33 | return super.clone(); 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return super.toString(); 39 | } 40 | 41 | @Override 42 | protected void finalize() throws Throwable { 43 | super.finalize(); 44 | } 45 | 46 | /** 47 | * @author github.kloping 48 | */ 49 | @Target(ElementType.METHOD) 50 | @java.lang.annotation.Retention(RetentionPolicy.RUNTIME) 51 | public @interface EventReceiver { 52 | } 53 | 54 | /** 55 | * 过滤不需要的消息类型 且必须与 {@link EventReceiver} 一起使用 56 | *
57 | * 58 | * //例如 59 | *
{@code @EventReceiver} 60 | *
{@code @Filter(exclusions = {At.class})} 61 | *
62 | */ 63 | @Target(ElementType.METHOD) 64 | @java.lang.annotation.Retention(RetentionPolicy.RUNTIME) 65 | public @interface Filter { 66 | Class[] exclusions(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/MessagePacket.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl; 2 | 3 | import lombok.Data; 4 | import lombok.experimental.Accessors; 5 | 6 | /** 7 | * @author github.kloping 8 | */ 9 | @Data 10 | @Accessors(chain = true) 11 | public class MessagePacket { 12 | /** 13 | * 文本 14 | */ 15 | private String content; 16 | /** 17 | * 这里上传图片的网址必须是经过备案的域名下的文件
否则将报错500
18 | * 图片地址 19 | */ 20 | private String image; 21 | /** 22 | * 引用消息id 23 | */ 24 | private String replyId; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/exc/InvalidRequestException.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.exc; 2 | 3 | import io.github.kloping.qqbot.Resource; 4 | import io.github.kloping.qqbot.api.exc.RequestException; 5 | import io.github.kloping.qqbot.entities.exc.QBotError; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public class InvalidRequestException extends RequestException { 11 | 12 | 13 | private QBotError error; 14 | 15 | public InvalidRequestException(int code, String body, String url, String method) { 16 | super(code, body, url, method); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/exc/TokenExpireException.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.exc; 2 | 3 | import io.github.kloping.qqbot.Resource; 4 | import io.github.kloping.qqbot.api.exc.RequestException; 5 | import io.github.kloping.qqbot.entities.exc.QBotError; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public class TokenExpireException extends RequestException { 11 | 12 | 13 | private QBotError error; 14 | 15 | public TokenExpireException(int code, String body, String url, String method) { 16 | super(code, body, url, method); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/BaseMessageChannelReceiveEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.event.ChannelEvent; 5 | import io.github.kloping.qqbot.api.message.MessageChannelReceiveEvent; 6 | import io.github.kloping.qqbot.entities.Bot; 7 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 8 | import io.github.kloping.qqbot.entities.qqpd.data.Emoji; 9 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 10 | 11 | /** 12 | * @author github.kloping 13 | */ 14 | public class BaseMessageChannelReceiveEvent extends BaseMessageEvent implements ChannelEvent, MessageChannelReceiveEvent { 15 | public BaseMessageChannelReceiveEvent(RawMessage message, JSONObject jo, Bot bot) { 16 | super(message, jo, bot); 17 | this.channel = getGuild().getChannel(message.getChannelId()); 18 | this.sender = getGuild().getMember(message.getAuthor().getId()); 19 | this.channelId = getChannel().getId(); 20 | } 21 | 22 | protected String content; 23 | protected String channelId; 24 | 25 | @Override 26 | public String getContent() { 27 | return content == null ? content = getMessage().toString() : content; 28 | } 29 | 30 | @Override 31 | public String getChannelId() { 32 | return channelId; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return String.format("[type(%s) %s].%s member(%s)=>%s" 38 | , EnvType.GUILD.name() 39 | , getGuild().getName() 40 | , getChannel().getName() 41 | , getSender().getNick() 42 | , getRawMessage().toString0() 43 | ); 44 | } 45 | 46 | @Override 47 | public void addEmoji(Emoji emoji) { 48 | getRawMessage().addEmoji(emoji); 49 | } 50 | 51 | @Override 52 | public void removeEmoji(Emoji emoji) { 53 | getRawMessage().addEmoji(emoji); 54 | } 55 | 56 | @Override 57 | public String getClassName() { 58 | return MessageChannelReceiveEvent.class.getSimpleName(); 59 | } 60 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/BaseMessageContainsAtEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.message.MessageContainsAtEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | public class BaseMessageContainsAtEvent extends BaseMessageChannelReceiveEvent implements MessageContainsAtEvent { 12 | public BaseMessageContainsAtEvent(RawMessage message, JSONObject jo, Bot bot) { 13 | super(message, jo,bot); 14 | this.channel = getGuild().getChannel(message.getChannelId()); 15 | this.sender = getGuild().getMember(message.getAuthor().getId()); 16 | ats = new String[message.getMentions().length]; 17 | for (int i = 0; i < message.getMentions().length; i++) { 18 | ats[i] = message.getMentions()[i].getId(); 19 | } 20 | } 21 | 22 | private String[] ats; 23 | 24 | @Override 25 | public String[] getAllAt() { 26 | return ats; 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/BaseMessageDeleteEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.message.MessageDeleteEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | public class BaseMessageDeleteEvent extends BaseMessageReceiveEvent implements MessageDeleteEvent { 12 | public BaseMessageDeleteEvent(RawMessage message, JSONObject jo, Bot bot) { 13 | super(jo.getJSONObject("message").toJavaObject(RawMessage.class), jo, bot); 14 | opUserId = getMetadata().getJSONObject("op_user").getString("id"); 15 | } 16 | 17 | private String opUserId; 18 | private String authorId; 19 | 20 | @Override 21 | public String getAuthorId() { 22 | return getRawMessage().getAuthor().getId(); 23 | } 24 | 25 | @Override 26 | public String getOpUserId() { 27 | return opUserId; 28 | } 29 | 30 | @Override 31 | public String getClassName() { 32 | return "MessageDeleteEvent"; 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/BaseMessageDirectReceiveEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.SendAble; 5 | import io.github.kloping.qqbot.api.message.MessageDirectReceiveEvent; 6 | import io.github.kloping.qqbot.entities.Bot; 7 | import io.github.kloping.qqbot.entities.qqpd.Guild; 8 | import io.github.kloping.qqbot.entities.qqpd.Member; 9 | import io.github.kloping.qqbot.entities.qqpd.message.DirectMessage; 10 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 11 | import io.github.kloping.qqbot.entities.qqpd.message.RawPreMessage; 12 | import io.github.kloping.qqbot.http.data.ActionResult; 13 | import io.github.kloping.qqbot.http.data.Result; 14 | import io.github.kloping.qqbot.impl.MessagePacket; 15 | 16 | /** 17 | * @author github.kloping 18 | */ 19 | public class BaseMessageDirectReceiveEvent extends BaseMessageReceiveEvent implements MessageDirectReceiveEvent { 20 | public BaseMessageDirectReceiveEvent(RawMessage message, JSONObject jo, Bot bot) { 21 | super(); 22 | this.bot = bot; 23 | this.directMessage = DirectMessage.messageAsDirectMessage(message); 24 | this.message = this.directMessage; 25 | this.metadata = jo; 26 | this.srcGuildId = getRawMessage().getSrcGuildId(); 27 | this.content = getRawMessage().getContent() == null ? "" : getRawMessage().getContent(); 28 | this.srcGuild = getBot().getGuild(getSrcGuildId()); 29 | this.guild = getBot().getGuild(getSrcGuildId()); 30 | this.sender = getRawMessage().getMember(); 31 | } 32 | 33 | @Override 34 | public Member getSender() { 35 | return super.getSender(); 36 | } 37 | 38 | private String srcGuildId; 39 | private Guild srcGuild; 40 | private DirectMessage directMessage; 41 | 42 | @Override 43 | public DirectMessage getDirectMessage() { 44 | return directMessage; 45 | } 46 | 47 | @Override 48 | public String getSrcGuildId() { 49 | return srcGuildId; 50 | } 51 | 52 | @Override 53 | public Guild getSrcGuild() { 54 | return srcGuild; 55 | } 56 | 57 | /** 58 | * 替换默认 59 | * 60 | * @param text 61 | * @return 62 | */ 63 | @Override 64 | public Result send(String text) { 65 | return sendDirect(text); 66 | } 67 | 68 | /** 69 | * 替换默认 70 | * 71 | * @param text 72 | * @param message 73 | * @return 74 | */ 75 | @Override 76 | public Result send(String text, RawMessage message) { 77 | return sendDirect(text, message); 78 | } 79 | 80 | /** 81 | * 替换默认 82 | * 83 | * @param packet 84 | * @return 85 | */ 86 | @Override 87 | public Result send(MessagePacket packet) { 88 | return sendDirect(packet); 89 | } 90 | 91 | /** 92 | * 替换默认 93 | * 94 | * @param msg 95 | * @return 96 | */ 97 | @Override 98 | public Result send(RawPreMessage msg) { 99 | return sendDirect(msg); 100 | } 101 | 102 | @Override 103 | public Result sendDirect(String text) { 104 | return getDirectMessage().sendDirect(text); 105 | } 106 | 107 | @Override 108 | public Result sendDirect(String text, RawMessage message) { 109 | return getDirectMessage().sendDirect(text, message); 110 | } 111 | 112 | @Override 113 | public Result sendDirect(MessagePacket packet) { 114 | return getDirectMessage().sendDirect(packet); 115 | } 116 | 117 | @Override 118 | public Result sendDirect(RawPreMessage msg) { 119 | return getDirectMessage().sendDirect(msg); 120 | } 121 | 122 | @Override 123 | public String toString() { 124 | return String.format("[channel(%s)]direct(%s)=>%s" 125 | , getDirectMessage().getChannelId() 126 | , getSender().getNick() 127 | , getContent()); 128 | } 129 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/BaseMessageEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.alibaba.fastjson.annotation.JSONField; 5 | import io.github.kloping.qqbot.api.SendAble; 6 | import io.github.kloping.qqbot.api.event.ChannelEvent; 7 | import io.github.kloping.qqbot.api.message.MessageEvent; 8 | import io.github.kloping.qqbot.entities.Bot; 9 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 10 | import io.github.kloping.qqbot.entities.ex.msg.MessageChain; 11 | import io.github.kloping.qqbot.entities.qqpd.Channel; 12 | import io.github.kloping.qqbot.entities.qqpd.Guild; 13 | import io.github.kloping.qqbot.entities.qqpd.Member; 14 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 15 | import io.github.kloping.qqbot.entities.qqpd.message.RawPreMessage; 16 | import io.github.kloping.qqbot.http.data.ActionResult; 17 | import io.github.kloping.qqbot.http.data.Result; 18 | import io.github.kloping.qqbot.impl.MessagePacket; 19 | import io.github.kloping.qqbot.utils.BaseUtils; 20 | 21 | /** 22 | * @author github.kloping 23 | */ 24 | public abstract class BaseMessageEvent implements ChannelEvent, MessageEvent { 25 | protected RawMessage message; 26 | protected JSONObject metadata; 27 | protected Member sender; 28 | protected Guild guild; 29 | protected Channel channel; 30 | 31 | protected Bot bot; 32 | 33 | public BaseMessageEvent() { 34 | } 35 | 36 | public BaseMessageEvent(RawMessage message, JSONObject jo, Bot bot) { 37 | this.message = message; 38 | this.metadata = jo; 39 | this.bot = bot; 40 | this.guild = getBot().getGuild(message.getGuildId()); 41 | this.channel = getGuild().getChannel(message.getChannelId()); 42 | this.sender = getGuild().getMember(message.getAuthor().getId()); 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return String.format("[type(%s) %s].%s:%s" 48 | , EnvType.GUILD.name() 49 | , getSubject().getId() 50 | , getSender().getId() 51 | , getRawMessage().toString0() 52 | ); 53 | } 54 | 55 | @Override 56 | public Channel getChannel() { 57 | return channel; 58 | } 59 | 60 | @Override 61 | public Channel getSubject() { 62 | return getChannel(); 63 | } 64 | 65 | @Override 66 | public Guild getGuild() { 67 | return guild; 68 | } 69 | 70 | @Override 71 | public RawMessage getRawMessage() { 72 | return message; 73 | } 74 | 75 | @Override 76 | public JSONObject getMetadata() { 77 | return metadata; 78 | } 79 | 80 | @Override 81 | public Member getSender() { 82 | return sender; 83 | } 84 | 85 | @Override 86 | public Result send(String text) { 87 | return getRawMessage().send(text); 88 | } 89 | 90 | @Override 91 | public Result send(String text, RawMessage message) { 92 | return getRawMessage().send(text, message); 93 | } 94 | 95 | @Override 96 | public Result send(MessagePacket packet) { 97 | return getRawMessage().send(packet); 98 | } 99 | 100 | @Override 101 | public Result send(RawPreMessage msg) { 102 | return getRawMessage().send(msg); 103 | } 104 | 105 | @Override 106 | public Bot getBot() { 107 | return bot; 108 | } 109 | 110 | @Override 111 | public Result send(SendAble msg) { 112 | return getRawMessage().send(msg); 113 | } 114 | 115 | protected MessageChain chain; 116 | 117 | @Override 118 | public MessageChain getMessage() { 119 | return chain == null ? chain = BaseUtils.parseToMessageChain(getRawMessage(), filters) : chain; 120 | } 121 | 122 | @JSONField(serialize = false, deserialize = false) 123 | private Class[] filters = null; 124 | 125 | @Override 126 | public void setFilter(Class[] filters) { 127 | this.filters = filters; 128 | } 129 | 130 | @Override 131 | public String getId() { 132 | return getRawMessage().getId(); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/BaseMessageReactionEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.event.ChannelEvent; 5 | import io.github.kloping.qqbot.api.message.MessageReactionEvent; 6 | import io.github.kloping.qqbot.entities.Bot; 7 | import io.github.kloping.qqbot.entities.qqpd.Channel; 8 | import io.github.kloping.qqbot.entities.qqpd.Guild; 9 | import io.github.kloping.qqbot.entities.qqpd.Member; 10 | import io.github.kloping.qqbot.entities.qqpd.message.EmojiReaction; 11 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 12 | import lombok.Getter; 13 | 14 | /** 15 | * @author github.kloping 16 | */ 17 | public class BaseMessageReactionEvent extends BaseMessageEvent implements ChannelEvent, MessageReactionEvent { 18 | public BaseMessageReactionEvent(RawMessage message, JSONObject jo, 19 | Bot bot, EmojiReaction reaction) { 20 | super(message, jo, bot); 21 | this.channel = getGuild().getChannel(message.getChannelId()); 22 | this.sender = getGuild().getMember(message.getAuthor().getId()); 23 | this.reaction = reaction; 24 | } 25 | 26 | @Override 27 | public Channel getChannel() { 28 | return channel; 29 | } 30 | 31 | @Override 32 | public Guild getGuild() { 33 | return guild; 34 | } 35 | 36 | @Getter 37 | private EmojiReaction reaction; 38 | 39 | private Boolean isAdd; 40 | 41 | public void setReaction(EmojiReaction reaction) { 42 | this.reaction = reaction; 43 | } 44 | 45 | public Boolean getAdd() { 46 | return isAdd; 47 | } 48 | 49 | public void setAdd(Boolean add) { 50 | isAdd = add; 51 | } 52 | 53 | @Override 54 | public EmojiReaction getMessageReaction() { 55 | return reaction; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | Member member = 61 | getGuild().getMember(reaction.getUserId()); 62 | return String.format("%s'%s'表情(%s)", member.getNick(), isAdd ? "添加" : "移除", reaction.getEmoji().getText()); 63 | } 64 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/BaseMessageReceiveEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.message.MessageReceiveEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.Channel; 7 | import io.github.kloping.qqbot.entities.qqpd.Guild; 8 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | public class BaseMessageReceiveEvent extends BaseMessageEvent implements MessageReceiveEvent { 14 | public BaseMessageReceiveEvent() { 15 | } 16 | 17 | public BaseMessageReceiveEvent(RawMessage message, JSONObject jo, Bot bot) { 18 | super(message, jo, bot); 19 | message.setBot(bot); 20 | this.content = getRawMessage().getContent() == null ? "" : getRawMessage().getContent(); 21 | } 22 | 23 | protected String content; 24 | 25 | @Override 26 | public String getContent() { 27 | return content; 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/v2/BaseFriendAdd.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message.v2; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.v2.FriendAdd; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | public class BaseFriendAdd extends BaseFriendEvent implements FriendAdd { 12 | public BaseFriendAdd(RawMessage message, JSONObject jo, Bot bot) { 13 | super(message, jo, bot); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "FRIEND_ADD EVENT FID:" + getOpenId(); 19 | } 20 | 21 | @Override 22 | public String getClassName() { 23 | return "FriendAdd"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/v2/BaseFriendEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message.v2; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.v2.FriendEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | import io.github.kloping.qqbot.entities.qqpd.v2.Friend; 8 | import io.github.kloping.qqbot.network.Events; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | public abstract class BaseFriendEvent implements FriendEvent { 14 | 15 | private final Friend friend; 16 | private final JSONObject rawData; 17 | private final Bot bot; 18 | 19 | public BaseFriendEvent(RawMessage message, JSONObject jo, Bot bot) { 20 | this.rawData = jo; 21 | this.bot = bot; 22 | this.friend = new Friend(getMetadata()); 23 | } 24 | 25 | @Override 26 | public JSONObject getMetadata() { 27 | return rawData; 28 | } 29 | 30 | @Override 31 | public Bot getBot() { 32 | return bot; 33 | } 34 | 35 | @Override 36 | public Friend getFriend() { 37 | return friend; 38 | } 39 | 40 | @Override 41 | public String getOpenId() { 42 | return getFriend().getId(); 43 | } 44 | 45 | @Override 46 | public String getId() { 47 | return rawData.getString(Events.EXTEND_ID); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/v2/BaseGroupAddRobotEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message.v2; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.v2.GroupEvent; 5 | import io.github.kloping.qqbot.api.v2.GroupOpRobotEvent; 6 | import io.github.kloping.qqbot.entities.Bot; 7 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 8 | 9 | /** 10 | * @author github.kloping 11 | */ 12 | public class BaseGroupAddRobotEvent extends BaseGroupOpRobotEvent implements GroupOpRobotEvent { 13 | public BaseGroupAddRobotEvent(RawMessage message, JSONObject jo, Bot bot) { 14 | super(message, jo, bot); 15 | } 16 | 17 | @Override 18 | public String getClassName() { 19 | return "GroupAddRobotEvent"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/v2/BaseGroupDelRobotEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message.v2; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.v2.GroupOpRobotEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | public class BaseGroupDelRobotEvent extends BaseGroupOpRobotEvent implements GroupOpRobotEvent { 12 | public BaseGroupDelRobotEvent(RawMessage message, JSONObject jo, Bot bot) { 13 | super(message, jo, bot); 14 | } 15 | 16 | @Override 17 | public String getClassName() { 18 | return "GroupDelRobotEvent"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/v2/BaseGroupEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message.v2; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.v2.GroupEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | import io.github.kloping.qqbot.entities.qqpd.v2.Group; 8 | import io.github.kloping.qqbot.network.Events; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | public abstract class BaseGroupEvent implements GroupEvent { 14 | 15 | private final Group group; 16 | private final JSONObject rawData; 17 | private final Bot bot; 18 | 19 | public BaseGroupEvent(RawMessage message, JSONObject jo, Bot bot) { 20 | this.rawData = jo; 21 | this.bot = bot; 22 | this.group = new Group(getMetadata()); 23 | } 24 | 25 | @Override 26 | public JSONObject getMetadata() { 27 | return rawData; 28 | } 29 | 30 | @Override 31 | public Bot getBot() { 32 | return bot; 33 | } 34 | 35 | @Override 36 | public Group getGroup() { 37 | return group; 38 | } 39 | 40 | @Override 41 | public String getGroupId() { 42 | return getGroup().getOpenid(); 43 | } 44 | 45 | @Override 46 | public String getId() { 47 | return rawData.getString(Events.EXTEND_ID); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/v2/BaseGroupOpRobotEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message.v2; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.v2.GroupOpRobotEvent; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | 8 | /** 9 | * @author github.kloping 10 | */ 11 | public abstract class BaseGroupOpRobotEvent extends BaseGroupEvent implements GroupOpRobotEvent { 12 | public BaseGroupOpRobotEvent(RawMessage message, JSONObject jo, Bot bot) { 13 | super(message, jo, bot); 14 | } 15 | 16 | @Override 17 | public String getOpMemberOpenid() { 18 | return getMetadata().getString("op_member_openid"); 19 | } 20 | 21 | @Override 22 | public Long getTimestamp() { 23 | return getMetadata().getLong("timestamp"); 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return String.format("op robot in %s from %s", getOpMemberOpenid(), getGroupId()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/message/v2/BaseMessageEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.message.v2; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.alibaba.fastjson.annotation.JSONField; 5 | import io.github.kloping.qqbot.api.message.MessageEvent; 6 | import io.github.kloping.qqbot.api.v2.MessageV2Event; 7 | import io.github.kloping.qqbot.entities.Bot; 8 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 9 | import io.github.kloping.qqbot.entities.ex.msg.MessageChain; 10 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 11 | import io.github.kloping.qqbot.entities.qqpd.v2.Contact; 12 | import io.github.kloping.qqbot.utils.BaseUtils; 13 | import lombok.Getter; 14 | 15 | /** 16 | * @author github.kloping 17 | */ 18 | @Getter 19 | public abstract class BaseMessageEvent implements MessageEvent, MessageV2Event { 20 | public BaseMessageEvent(RawMessage message, JSONObject jo, Bot bot) { 21 | this.bot = bot; 22 | this.metadata = jo; 23 | this.rawMessage = message; 24 | this.rawMessage.setEnvType(EnvType.GROUP); 25 | this.msgId = getMetadata().getString("id"); 26 | } 27 | 28 | protected RawMessage rawMessage; 29 | protected Bot bot; 30 | protected JSONObject metadata; 31 | protected String msgId; 32 | 33 | public abstract Contact getSender(); 34 | 35 | @Override 36 | public String toString() { 37 | return String.format("[type(%s) %s].%s:%s" 38 | , EnvType.GROUP.name() 39 | , getSubject().getId() 40 | , getSender().getId() 41 | , getRawMessage().toString0() 42 | ); 43 | } 44 | 45 | protected MessageChain chain; 46 | 47 | @Override 48 | public MessageChain getMessage() { 49 | return chain == null ? chain = BaseUtils.parseToMessageChain(getRawMessage(), filters) : chain; 50 | } 51 | 52 | @JSONField(serialize = false, deserialize = false) 53 | private Class[] filters = null; 54 | 55 | @Override 56 | public void setFilter(Class[] filters) { 57 | this.filters = filters; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/ChannelEventsRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.spt.annotations.AutoStand; 5 | import io.github.kloping.spt.annotations.AutoStandAfter; 6 | import io.github.kloping.spt.annotations.Entity; 7 | import io.github.kloping.qqbot.api.event.Event; 8 | import io.github.kloping.qqbot.entities.Bot; 9 | import io.github.kloping.qqbot.entities.qqpd.Common; 10 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 11 | import io.github.kloping.qqbot.impl.BaseChannelUpdateEvent; 12 | import io.github.kloping.qqbot.network.Events; 13 | 14 | /** 15 | * @author github.kloping 16 | */ 17 | @Entity 18 | public class ChannelEventsRegister implements Events.EventRegister { 19 | 20 | public static final String CHANNEL_CREATE = "CHANNEL_CREATE"; 21 | public static final String CHANNEL_DELETE = "CHANNEL_DELETE"; 22 | 23 | @AutoStandAfter 24 | private void r8(Events events) { 25 | events.register("CHANNEL_UPDATE", this).register(CHANNEL_CREATE, this).register(CHANNEL_DELETE, this); 26 | } 27 | 28 | @AutoStand 29 | Bot bot; 30 | 31 | @Override 32 | public Event handle(String t, JSONObject mateData, RawMessage message) { 33 | BaseChannelUpdateEvent event = new BaseChannelUpdateEvent(mateData, bot); 34 | if (CHANNEL_CREATE.equals(t)) { 35 | Common.GUILD_CHANNEL_TEMP.get(event.getChannel().getGuildId()).put(event.getChannel().getId(), event.getChannel()); 36 | } else if (CHANNEL_DELETE.equals(t)) { 37 | Common.GUILD_CHANNEL_TEMP.get(event.getChannel().getGuildId()).remove(event.getChannel().getId()); 38 | } 39 | return event; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/FriendEventsRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.qqbot.api.event.Event; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | import io.github.kloping.qqbot.impl.message.v2.BaseFriendAdd; 8 | import io.github.kloping.qqbot.impl.message.v2.BaseFriendMessageEvent; 9 | import io.github.kloping.qqbot.network.Events; 10 | import io.github.kloping.spt.annotations.AutoStand; 11 | import io.github.kloping.spt.annotations.AutoStandAfter; 12 | import io.github.kloping.spt.annotations.Entity; 13 | 14 | /** 15 | * @author github.kloping 16 | */ 17 | @Entity 18 | public class FriendEventsRegister implements Events.EventRegister { 19 | 20 | public static final String C2C_MESSAGE_CREATE = "C2C_MESSAGE_CREATE"; 21 | public static final String FRIEND_ADD = "FRIEND_ADD"; 22 | 23 | @AutoStandAfter 24 | private void rN(Events events) { 25 | events.register(C2C_MESSAGE_CREATE, this) 26 | .register(FRIEND_ADD, this); 27 | } 28 | 29 | @AutoStand 30 | Bot bot; 31 | 32 | @Override 33 | public Event handle(String t, JSONObject mateData, RawMessage message) { 34 | Event event = null; 35 | if (C2C_MESSAGE_CREATE.equals(t)) { 36 | event = new BaseFriendMessageEvent(message, mateData, bot); 37 | } else if (FRIEND_ADD.equals(t)) { 38 | event = new BaseFriendAdd(message, mateData, bot); 39 | } 40 | return event; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/GroupEventsRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.spt.annotations.AutoStand; 5 | import io.github.kloping.spt.annotations.AutoStandAfter; 6 | import io.github.kloping.spt.annotations.Entity; 7 | import io.github.kloping.spt.interfaces.Logger; 8 | import io.github.kloping.qqbot.api.event.Event; 9 | import io.github.kloping.qqbot.entities.Bot; 10 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 11 | import io.github.kloping.qqbot.impl.message.v2.BaseGroupMessageEvent; 12 | import io.github.kloping.qqbot.network.Events; 13 | 14 | /** 15 | * @author github.kloping 16 | */ 17 | @Entity 18 | public class GroupEventsRegister implements Events.EventRegister { 19 | public static final String GROUP_AT_MESSAGE_CREATE = "GROUP_AT_MESSAGE_CREATE"; 20 | 21 | @AutoStandAfter 22 | private void r4(Events events) { 23 | events.register(GROUP_AT_MESSAGE_CREATE, this); 24 | } 25 | 26 | @AutoStand 27 | Bot bot; 28 | 29 | @AutoStand 30 | Logger logger; 31 | 32 | @Override 33 | public Event handle(String t, JSONObject mateData, RawMessage message) { 34 | Event event = null; 35 | if (GROUP_AT_MESSAGE_CREATE.equals(t)) { 36 | event = new BaseGroupMessageEvent(message, mateData, bot); 37 | } else { 38 | } 39 | return event; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/GroupRobotEventRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.spt.annotations.AutoStand; 5 | import io.github.kloping.spt.annotations.AutoStandAfter; 6 | import io.github.kloping.spt.annotations.Entity; 7 | import io.github.kloping.qqbot.api.event.Event; 8 | import io.github.kloping.qqbot.entities.Bot; 9 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 10 | import io.github.kloping.qqbot.impl.message.v2.BaseGroupAddRobotEvent; 11 | import io.github.kloping.qqbot.impl.message.v2.BaseGroupDelRobotEvent; 12 | import io.github.kloping.qqbot.network.Events; 13 | 14 | /** 15 | * @author github.kloping 16 | */ 17 | @Entity 18 | public class GroupRobotEventRegister implements Events.EventRegister { 19 | 20 | public static final String GROUP_DEL_ROBOT = "GROUP_DEL_ROBOT"; 21 | public static final String GROUP_ADD_ROBOT = "GROUP_ADD_ROBOT"; 22 | 23 | @AutoStandAfter 24 | private void r0(Events events) { 25 | events.register(GROUP_ADD_ROBOT, this) 26 | .register(GROUP_DEL_ROBOT, this); 27 | } 28 | 29 | @AutoStand 30 | Bot bot; 31 | 32 | @Override 33 | public Event handle(String t, JSONObject mateData, RawMessage message) { 34 | Event event = null; 35 | if (GROUP_ADD_ROBOT.equals(t)) { 36 | event = new BaseGroupAddRobotEvent(message, mateData, bot); 37 | } else if (GROUP_DEL_ROBOT.equals(t)) { 38 | event = new BaseGroupDelRobotEvent(message, mateData, bot); 39 | } 40 | return event; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/GuildEventsRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.spt.annotations.AutoStand; 5 | import io.github.kloping.spt.annotations.AutoStandAfter; 6 | import io.github.kloping.spt.annotations.Entity; 7 | import io.github.kloping.spt.interfaces.Logger; 8 | import io.github.kloping.qqbot.api.event.Event; 9 | import io.github.kloping.qqbot.entities.Bot; 10 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 11 | import io.github.kloping.qqbot.impl.BaseGuildUpdateEvent; 12 | import io.github.kloping.qqbot.network.Events; 13 | 14 | /** 15 | * @author github.kloping 16 | */ 17 | @Entity 18 | public class GuildEventsRegister implements Events.EventRegister { 19 | public static final String GUILD_CREATE = "GUILD_CREATE"; 20 | public static final String GUILD_DELETE = "GUILD_DELETE"; 21 | 22 | @AutoStandAfter 23 | private void r4(Events events) { 24 | events.register("GUILD_UPDATE", this).register(GUILD_CREATE, this).register(GUILD_DELETE, this); 25 | } 26 | 27 | @AutoStand 28 | Bot bot; 29 | 30 | @AutoStand 31 | Logger logger; 32 | 33 | @Override 34 | public Event handle(String t, JSONObject mateData, RawMessage message) { 35 | BaseGuildUpdateEvent event = null; 36 | event = new BaseGuildUpdateEvent(mateData, bot); 37 | if (GUILD_CREATE.equals(t)) { 38 | logger.info(String.format(t + " Event Bot Join Guild[%s(%s)]", event.getGuild().getName(), event.getGuild().getId())); 39 | } else if (GUILD_DELETE.equals(t)) { 40 | logger.info(String.format(t + " Event Exit From Guild[%s(%s)]", event.getGuild().getName(), event.getGuild().getId())); 41 | bot.delGuild(event.getGuild()); 42 | } 43 | return event; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/InterActionEventRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.spt.annotations.AutoStand; 5 | import io.github.kloping.spt.annotations.AutoStandAfter; 6 | import io.github.kloping.spt.annotations.Entity; 7 | import io.github.kloping.spt.interfaces.Logger; 8 | import io.github.kloping.qqbot.api.event.Event; 9 | import io.github.kloping.qqbot.entities.Bot; 10 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 11 | import io.github.kloping.qqbot.impl.BaseInterActionEvent; 12 | import io.github.kloping.qqbot.network.Events; 13 | 14 | /** 15 | * @author github.kloping 16 | */ 17 | @Entity 18 | public class InterActionEventRegister implements Events.EventRegister { 19 | 20 | /** 21 | *
属性 类型 说明
id string 平台方事件 ID,可以用于被动消息发送
type int 消息按钮: 11,单聊快捷菜单:12
scene string 事件发生的场景:c2c、group、guild
chat_type int 0 频道场景,1 群聊场景,2 单聊场景
timestamp string 触发时间 RFC 3339 格式
guild_id string 频道的 openid ,仅在频道场景提供该字段
channel_id string 文字子频道的 openid,仅在频道场景提供该字段
user_openid string 单聊单聊按钮触发x,的用户 openid,仅在单聊场景提供该字段
group_openid string 群的 openid,仅在群聊场景提供该字段
group_member_openid string 按钮触发用户,群聊的群成员 openid,仅在群聊场景提供该字段
data.resoloved.button_data string 操作按钮的 data 字段值(在发送消息按钮时设置)
data.resoloved.button_id string 操作按钮的 id 字段值(在发送消息按钮时设置)
data.resoloved.user_id string 操作的用户 userid,仅频道场景提供该字段
data.resoloved.feature_id string 操作按钮的 id 字段值,仅自定义菜单提供该字段(在管理端设置)
data.resoloved.message_id string 操作的消息id,目前仅频道场景提供该字段
version int 默认 1
application_id string 机器人的 appid
22 | */ 23 | public static final String INTERACTION_CREATE = "INTERACTION_CREATE"; 24 | 25 | @AutoStandAfter 26 | private void rN(Events events) { 27 | events.register(INTERACTION_CREATE, this); 28 | } 29 | 30 | @AutoStand 31 | Bot bot; 32 | 33 | @AutoStand 34 | Logger logger; 35 | 36 | @Override 37 | public Event handle(String t, JSONObject mateData, RawMessage message) { 38 | Event event = null; 39 | if (t.equals(INTERACTION_CREATE)) { 40 | event = new BaseInterActionEvent(bot, mateData); 41 | } 42 | return event; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/MemberEventRegisters.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.spt.annotations.AutoStand; 5 | import io.github.kloping.spt.annotations.AutoStandAfter; 6 | import io.github.kloping.spt.annotations.Entity; 7 | import io.github.kloping.map.MapUtils; 8 | import io.github.kloping.qqbot.api.event.Event; 9 | import io.github.kloping.qqbot.api.event.MemberUpdateEvent; 10 | import io.github.kloping.qqbot.entities.Bot; 11 | import io.github.kloping.qqbot.entities.qqpd.Common; 12 | import io.github.kloping.qqbot.entities.qqpd.MemberWithGuildID; 13 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 14 | import io.github.kloping.qqbot.impl.BaseMemberRemoveEvent; 15 | import io.github.kloping.qqbot.impl.BaseMemberUpdateEvent; 16 | import io.github.kloping.qqbot.network.Events; 17 | 18 | /** 19 | * @author github.kloping 20 | */ 21 | @Entity 22 | public class MemberEventRegisters implements Events.EventRegister { 23 | 24 | public static final String GUILD_MEMBER_ADD = "GUILD_MEMBER_ADD"; 25 | public static final String GUILD_MEMBER_REMOVE = "GUILD_MEMBER_REMOVE"; 26 | 27 | @AutoStandAfter 28 | private void r5(Events events) { 29 | events.register("GUILD_MEMBER_UPDATE", this).register(GUILD_MEMBER_ADD, this).register(GUILD_MEMBER_REMOVE, this); 30 | } 31 | 32 | @AutoStand 33 | Bot bot; 34 | 35 | @Override 36 | public Event handle(String t,JSONObject mateData, RawMessage message) { 37 | MemberUpdateEvent event; 38 | MemberWithGuildID member; 39 | if (GUILD_MEMBER_REMOVE.equals(t)) { 40 | event = new BaseMemberRemoveEvent(mateData, bot); 41 | member = event.getMember(); 42 | } else { 43 | event = new BaseMemberUpdateEvent(mateData, bot); 44 | member = event.getMember(); 45 | event.getGuild().setMember(member); 46 | } 47 | if (GUILD_MEMBER_ADD.equals(t)) { 48 | MapUtils.append(Common.GUILD_MEMBER_TEMP, member.getGuildId(), member.getUser().getId(), member); 49 | } else if (GUILD_MEMBER_REMOVE.equals(t)) { 50 | Common.GUILD_MEMBER_TEMP.getOrDefault(event.getGuild().getId(), Common.EMPTY_MEMBER_MAP).remove(member.getUser().getId()); 51 | } 52 | return event; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/MessageDeleteEventRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.spt.annotations.AutoStand; 5 | import io.github.kloping.spt.annotations.AutoStandAfter; 6 | import io.github.kloping.spt.annotations.Entity; 7 | import io.github.kloping.qqbot.api.event.Event; 8 | import io.github.kloping.qqbot.entities.Bot; 9 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 10 | import io.github.kloping.qqbot.impl.message.BaseMessageDeleteEvent; 11 | import io.github.kloping.qqbot.network.Events; 12 | 13 | /** 14 | * @author github.kloping 15 | */ 16 | @Entity 17 | public class MessageDeleteEventRegister implements Events.EventRegister { 18 | @AutoStandAfter 19 | private void r3(Events events) { 20 | events.register("MESSAGE_DELETE", this).register("PUBLIC_MESSAGE_DELETE", this); 21 | } 22 | 23 | @AutoStand 24 | Bot bot; 25 | 26 | @Override 27 | public Event handle(String t,JSONObject mateData, RawMessage message) { 28 | Event event = null; 29 | event = new BaseMessageDeleteEvent(message, mateData, bot); 30 | return event; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/MessageEventsRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.spt.annotations.AutoStand; 5 | import io.github.kloping.spt.annotations.AutoStandAfter; 6 | import io.github.kloping.spt.annotations.Entity; 7 | import io.github.kloping.qqbot.api.event.Event; 8 | import io.github.kloping.qqbot.entities.Bot; 9 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 10 | import io.github.kloping.qqbot.impl.message.BaseMessageChannelReceiveEvent; 11 | import io.github.kloping.qqbot.impl.message.BaseMessageContainsAtEvent; 12 | import io.github.kloping.qqbot.impl.message.BaseMessageDirectReceiveEvent; 13 | import io.github.kloping.qqbot.network.Events; 14 | 15 | /** 16 | * @author github.kloping 17 | */ 18 | @Entity 19 | public class MessageEventsRegister implements Events.EventRegister { 20 | @AutoStandAfter 21 | public void r2(Events events) { 22 | events.register(MESSAGE_CREATE, this).register(AT_MESSAGE_CREATE, this).register("DIRECT_MESSAGE_CREATE", this); 23 | } 24 | 25 | public static final String AT_MESSAGE_CREATE = "AT_MESSAGE_CREATE"; 26 | public static final String MESSAGE_CREATE = "MESSAGE_CREATE"; 27 | 28 | @AutoStand 29 | Bot bot; 30 | 31 | private String msgId = null; 32 | 33 | @Override 34 | public Event handle(String t, JSONObject mateData, RawMessage msg) { 35 | if (msg.getId().equals(msgId)) return null; 36 | else msgId = msg.getId(); 37 | Event event = null; 38 | if (msg.getMentions() != null && msg.getMentions().length > 0) { 39 | event = new BaseMessageContainsAtEvent(msg, mateData, bot); 40 | } else if (msg.getSrcGuildId() != null && !msg.getSrcGuildId().isEmpty()) { 41 | event = new BaseMessageDirectReceiveEvent(msg, mateData, bot); 42 | msg.getAuthor().setBot(false); 43 | msg.getMember().setNick(msg.getAuthor().getUsername()); 44 | msg.getMember().setUser(msg.getAuthor()); 45 | } else { 46 | event = new BaseMessageChannelReceiveEvent(msg, mateData, bot); 47 | } 48 | return event; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/impl/registers/MessageReactionEventRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.impl.registers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import io.github.kloping.spt.annotations.AutoStand; 5 | import io.github.kloping.spt.annotations.AutoStandAfter; 6 | import io.github.kloping.spt.annotations.Entity; 7 | import io.github.kloping.qqbot.api.event.Event; 8 | import io.github.kloping.qqbot.entities.Bot; 9 | import io.github.kloping.qqbot.entities.ex.enums.EnvType; 10 | import io.github.kloping.qqbot.entities.qqpd.Member; 11 | import io.github.kloping.qqbot.entities.qqpd.data.Emoji; 12 | import io.github.kloping.qqbot.entities.qqpd.message.EmojiReaction; 13 | import io.github.kloping.qqbot.entities.qqpd.message.MessagePack; 14 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 15 | import io.github.kloping.qqbot.impl.message.BaseMessageReactionEvent; 16 | import io.github.kloping.qqbot.network.Events; 17 | 18 | /** 19 | * @author github.kloping 20 | */ 21 | @Entity 22 | public class MessageReactionEventRegister implements Events.EventRegister { 23 | 24 | @AutoStand 25 | Bot bot; 26 | 27 | @AutoStandAfter 28 | private void r7(Events events) { 29 | events.register("MESSAGE_REACTION_ADD", this).register("MESSAGE_REACTION_REMOVE", this); 30 | } 31 | 32 | @Override 33 | public Event handle(String t, JSONObject mateData, RawMessage message) { 34 | BaseMessageReactionEvent event = null; 35 | EmojiReaction reaction = mateData.toJavaObject(EmojiReaction.class); 36 | JSONObject jo = mateData.getJSONObject("emoji"); 37 | Integer type = jo.getInteger("type"); 38 | String id = jo.getString("id"); 39 | reaction.setEmoji(Emoji.valueOf(type, Integer.valueOf(id))); 40 | if (reaction.getTarget().getType().equals("ReactionTargetType_MSG")) { 41 | MessagePack pack = bot.channelBase.getMessageById(reaction.getChannelId(), reaction.getTarget().getId()); 42 | message = pack.getMessage(); 43 | message.setBot(bot); 44 | message.setEnvType(EnvType.GUILD); 45 | } else { 46 | String userId = mateData.getString("user_id"); 47 | Member member = bot.guildBase.getMember(reaction.getGuildId(), userId); 48 | message.setAuthor(member.getUser()); 49 | } 50 | event = new BaseMessageReactionEvent(message, mateData, bot, reaction); 51 | switch (t) { 52 | case "MESSAGE_REACTION_ADD": 53 | event.setAdd(true); 54 | break; 55 | case "MESSAGE_REACTION_REMOVE": 56 | event.setAdd(false); 57 | break; 58 | default: 59 | break; 60 | } 61 | return event; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/interfaces/ImageUploadInterceptor.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.interfaces; 2 | 3 | /** 4 | * @author github.kloping 5 | */ 6 | public interface ImageUploadInterceptor { 7 | String upload(byte[] bytes); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/interfaces/OnCloseListener.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.interfaces; 2 | 3 | import org.java_websocket.client.WebSocketClient; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface OnCloseListener { 9 | /** 10 | * on wss close 11 | * 12 | * @param code wss closed code
含义 是否可以重试 RESUME 是否可以重试 IDENTIFY
4001 无效的 opcode
4002 无效的 payload
4007 seq 错误
4006 无效的 session id,无法继续 resume,请 identify
4008 发送 payload 过快,请重新连接,并遵守连接后返回的频控信息
4009 连接过期,请重连并执行 resume 进行重新连接
4010 无效的 shard
4011 连接需要处理的 guild 过多,请进行合理的分片
4012 无效的 version
4013 无效的 intent
4014 intent 无权限
4014 intent 无权限
4900~4913 内部错误,请重连
4914 机器人已下架,只允许连接沙箱环境,请断开连接,检验当前连接环境
4915 机器人已封禁,不允许连接,请断开连接,申请解封后再连接
13 | * @param wss 14 | */ 15 | void onClose(int code, WebSocketClient wss); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/interfaces/OnPackReceive.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.interfaces; 2 | 3 | import io.github.kloping.qqbot.entities.Pack; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public interface OnPackReceive { 9 | /** 10 | * on wss receive a pack 11 | * 12 | * @return If true is returned, interception continues 13 | * @param pack 14 | */ 15 | boolean onReceive(Pack pack); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/network/WebSocketListener.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.network; 2 | 3 | import org.java_websocket.client.WebSocketClient; 4 | import org.java_websocket.framing.CloseFrame; 5 | import org.java_websocket.handshake.ServerHandshake; 6 | 7 | /** 8 | * WebSocketClient的监听处理 9 | *
根据提示文档自行处理操作 10 | * 11 | * @author github.kloping 12 | */ 13 | public interface WebSocketListener { 14 | /** 15 | * @param client 16 | * @param handshake 17 | * @return 决定是否进行框架接下来的操作 true执行 18 | */ 19 | default boolean onOpen(WebSocketClient client, ServerHandshake handshake) { 20 | return true; 21 | } 22 | 23 | /** 24 | * @param client 25 | * @param msg 26 | * @return 决定是否进行框架接下来的操作 true执行 此处若false则不执行(所有事件无法触发) 27 | */ 28 | default boolean onMessage(WebSocketClient client, String msg) { 29 | return true; 30 | } 31 | 32 | /** 33 | * @param client 34 | * @param msg 35 | * @return 决定是否进行框架接下来的操作 true执行 若为false将无法发送消息 36 | */ 37 | default boolean onSend(WebSocketClient client, String msg) { 38 | return true; 39 | } 40 | 41 | /** 42 | * Called after the websocket connection has been closed. 43 | * 44 | * @param client 45 | * @param code The codes can be looked up here: {@link CloseFrame} 46 | * @param reason Additional information string 47 | * @param remote Returns whether or not the closing of the connection was initiated by the remote 48 | * host. 49 | * @return 决定是否进行框架接下来的操作 true执行 若为false将不自动重连 50 | */ 51 | default boolean onClose(WebSocketClient client, int code, String reason, boolean remote) { 52 | return true; 53 | } 54 | 55 | /** 56 | * @param client 57 | * @param e 58 | * @return 同上 框架操作仅日志 59 | */ 60 | default boolean onError(WebSocketClient client, Exception e) { 61 | return true; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/network/hookauth/CustomPrivateKey.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.network.hookauth; 2 | 3 | import java.security.PrivateKey; 4 | import java.util.Arrays; 5 | 6 | public class CustomPrivateKey implements PrivateKey { 7 | 8 | private byte[] encoded; 9 | 10 | public CustomPrivateKey(byte[] encoded) { 11 | this.encoded = Arrays.copyOf(encoded, encoded.length); 12 | } 13 | 14 | @Override 15 | public String getAlgorithm() { 16 | return "Ed25519"; 17 | } 18 | 19 | @Override 20 | public String getFormat() { 21 | return "PKCS#8"; 22 | } 23 | 24 | @Override 25 | public byte[] getEncoded() { 26 | return Arrays.copyOf(encoded, encoded.length); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/network/hookauth/CustomPublicKey.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.network.hookauth; 2 | 3 | import java.security.PublicKey; 4 | import java.util.Arrays; 5 | 6 | public class CustomPublicKey implements PublicKey { 7 | 8 | private byte[] encoded; 9 | 10 | public CustomPublicKey(byte[] encoded) { 11 | this.encoded = Arrays.copyOf(encoded, encoded.length); 12 | } 13 | 14 | @Override 15 | public String getAlgorithm() { 16 | return "Ed25519"; 17 | } 18 | 19 | @Override 20 | public String getFormat() { 21 | return "X.509"; 22 | } 23 | 24 | @Override 25 | public byte[] getEncoded() { 26 | return Arrays.copyOf(encoded, encoded.length); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/utils/InvokeUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.utils; 2 | 3 | 4 | import io.github.kloping.qqbot.impl.ListenerHost; 5 | 6 | import java.lang.reflect.Method; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author github.kloping 12 | */ 13 | public class InvokeUtils { 14 | public static Method[] getAllMethod(ListenerHost listenerHost) { 15 | List methods = new LinkedList<>(); 16 | for (Method declaredMethod : listenerHost.getClass().getDeclaredMethods()) { 17 | if (declaredMethod.getDeclaredAnnotation(ListenerHost.EventReceiver.class) == null) continue; 18 | declaredMethod.setAccessible(true); 19 | methods.add(declaredMethod); 20 | } 21 | return methods.toArray(new Method[0]); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/io/github/kloping/qqbot/utils/PdCode.java: -------------------------------------------------------------------------------- 1 | package io.github.kloping.qqbot.utils; 2 | 3 | import io.github.kloping.arr.ArrDeSerializer; 4 | import io.github.kloping.number.NumberUtils; 5 | import io.github.kloping.qqbot.api.SendAble; 6 | import io.github.kloping.qqbot.entities.ex.At; 7 | import io.github.kloping.qqbot.entities.ex.AtAll; 8 | import io.github.kloping.qqbot.entities.ex.Image; 9 | import io.github.kloping.qqbot.entities.ex.PlainText; 10 | import io.github.kloping.qqbot.entities.ex.msg.MessageChain; 11 | import io.github.kloping.qqbot.entities.qqpd.data.Emoji; 12 | 13 | import java.util.regex.Pattern; 14 | 15 | /** 16 | * @author github.kloping 17 | */ 18 | public class PdCode { 19 | 20 | public static final ArrDeSerializer DE_SERIALIZER = new ArrDeSerializer<>(); 21 | 22 | public static final Pattern AT_PATTERN = Pattern.compile(""); 23 | public static final Pattern AT_ALL_PATTERN = Pattern.compile(""); 24 | public static final Pattern EMOJI_PATTERN = Pattern.compile(""); 25 | public static final Pattern IMAGE_PATTERN = Pattern.compile(""); 26 | 27 | static { 28 | DE_SERIALIZER.add(AT_PATTERN, new ArrDeSerializer.Rule0() { 29 | @Override 30 | public At deserializer(String s) { 31 | return new At(At.MEMBER_TYPE, NumberUtils.findNumberFromString(s)); 32 | } 33 | }); 34 | DE_SERIALIZER.add(AT_ALL_PATTERN, new ArrDeSerializer.Rule0() { 35 | @Override 36 | public AtAll deserializer(String s) { 37 | return new AtAll(); 38 | } 39 | }); 40 | DE_SERIALIZER.add(EMOJI_PATTERN, new ArrDeSerializer.Rule0() { 41 | @Override 42 | public Emoji deserializer(String s) { 43 | return Emoji.valueOf(Integer.valueOf(NumberUtils.findNumberFromString(s))); 44 | } 45 | }); 46 | DE_SERIALIZER.add(IMAGE_PATTERN, new ArrDeSerializer.Rule0() { 47 | @Override 48 | public Image deserializer(String s) { 49 | return new Image(s.substring(7, s.length() - 1)); 50 | } 51 | }); 52 | DE_SERIALIZER.add(ArrDeSerializer.EMPTY_PATTERN, new ArrDeSerializer.Rule0() { 53 | @Override 54 | public PlainText deserializer(String s) { 55 | return new PlainText(s); 56 | } 57 | }); 58 | } 59 | 60 | public static String serializeToPdCode(SendAble e) { 61 | if (e instanceof Emoji) { 62 | Emoji emoji = (Emoji) e; 63 | return (String.format("<emoji:%s>", emoji.getId())); 64 | } else if (e instanceof At) { 65 | At at = (At) e; 66 | return (String.format("<at:%s>", at.getTargetId())); 67 | } else if (e instanceof AtAll) { 68 | AtAll atAll = (AtAll) e; 69 | return ("<atAll>"); 70 | } else if (e instanceof Image) { 71 | Image image = (Image) e; 72 | return (String.format("<image:%s>", image.getUrl().startsWith("http") ? image.getUrl() : "https://" + image.getUrl())); 73 | } else if (e instanceof PlainText) { 74 | PlainText plainText = (PlainText) e; 75 | return (plainText.toString()); 76 | } else return e.toString(); 77 | } 78 | 79 | public static String serializeToPdCode(SendAble[] datas) { 80 | StringBuilder sb = new StringBuilder(); 81 | for (SendAble data : datas) { 82 | sb.append(serializeToPdCode(data)); 83 | } 84 | return sb.toString(); 85 | } 86 | 87 | public static String serializeToPdCode(MessageChain chain) { 88 | StringBuilder sb = new StringBuilder(); 89 | chain.forEach((e) -> { 90 | sb.append(serializeToPdCode(e)); 91 | }); 92 | return sb.toString(); 93 | } 94 | 95 | public static MessageChain deserializePdCode(String pdCode) { 96 | MessageChain chain = new MessageChain(); 97 | for (SendAble sendAble : DE_SERIALIZER.deserializer(pdCode)) { 98 | chain.append(sendAble); 99 | } 100 | return chain; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/EventsRegisterTest.java: -------------------------------------------------------------------------------- 1 | import com.alibaba.fastjson.JSONObject; 2 | import io.github.kloping.qqbot.Starter; 3 | import io.github.kloping.qqbot.api.event.ConnectedEvent; 4 | import io.github.kloping.qqbot.api.event.Event; 5 | import io.github.kloping.qqbot.entities.Bot; 6 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 7 | import io.github.kloping.qqbot.impl.ListenerHost; 8 | import io.github.kloping.qqbot.network.Events; 9 | import io.github.kloping.spt.annotations.AutoStand; 10 | import io.github.kloping.spt.annotations.AutoStandAfter; 11 | import io.github.kloping.spt.annotations.Entity; 12 | import io.github.kloping.spt.interfaces.Logger; 13 | import org.junit.Test; 14 | 15 | /** 16 | * @author github.kloping 17 | */ 18 | public class EventsRegisterTest extends ListenerHost { 19 | private Starter starter; 20 | private Logger logger; 21 | @Test 22 | public void testBefore() throws Throwable { 23 | // String appid = System.getProperty("appid"); 24 | // String token = System.getProperty("token"); 25 | // starter = new Starter(appid, token); 26 | // starter.getConfig().setCode(Intents.PRIVATE_INTENTS.getCode()); 27 | // starter.getConfig().setCode(Intents.PRIVATE_INTENTS.getCode()); 28 | // starter.setReconnect(true); 29 | // starter.registerListenerHost(this); 30 | // test0(); 31 | // starter.run(); 32 | // logger = starter.APPLICATION.logger; 33 | // TimeUnit.SECONDS.sleep(8); 34 | System.out.println("测试通过."); 35 | } 36 | 37 | @Entity 38 | public static class TestEventsRegister implements Events.EventRegister { 39 | 40 | public static final String TEST_EVENT = "TEST_EVENT"; 41 | 42 | @AutoStandAfter 43 | private void r8(Events events) { 44 | events.register(TEST_EVENT, this); 45 | } 46 | 47 | @AutoStand 48 | Bot bot; 49 | 50 | @Override 51 | public Event handle(String t, JSONObject mateData, RawMessage message) { 52 | if (TEST_EVENT.equals(TEST_EVENT)) { 53 | bot.logger.info("====================================="); 54 | bot.logger.waring(TEST_EVENT + " handle for raw " + mateData); 55 | } 56 | return null; 57 | } 58 | } 59 | 60 | private void test0() { 61 | starter.registerEventsRegister(TestEventsRegister.class); 62 | } 63 | 64 | @EventReceiver 65 | public void online(ConnectedEvent event) { 66 | logger.info("bot online start test"); 67 | test(); 68 | } 69 | 70 | public void test() { 71 | starter.getWssWorker().webSocket 72 | .onMessage("{\n" + 73 | " \"op\": 0,\n" + 74 | " \"s\": 3,\n" + 75 | " \"t\": \"TEST_EVENT\",\n" + 76 | " \"d\": {\n" + 77 | " \"application_id\": \"0\",\n" + 78 | " \"guild_id\": \"12345\",\n" + 79 | " \"id\": \"67890\",\n" + 80 | " \"name\": \"TEST NAME\",\n" + 81 | " \"op_user_id\": \"111111\",\n" + 82 | " \"owner_id\": \"2222222\",\n" + 83 | " \"parent_id\": \"33333333\",\n" + 84 | " \"permissions\": \"3\",\n" + 85 | " \"position\": 2,\n" + 86 | " \"private_type\": 0,\n" + 87 | " \"speak_permission\": 1,\n" + 88 | " \"sub_type\": 1,\n" + 89 | " \"type\": 0\n" + 90 | " }\n" + 91 | "}"); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/test/java/test_Intents.java: -------------------------------------------------------------------------------- 1 | import io.github.kloping.qqbot.Starter; 2 | import io.github.kloping.qqbot.api.Intents; 3 | 4 | /** 5 | * 事件订阅 6 | * 7 | * @author github.kloping 8 | */ 9 | public class test_Intents { 10 | public static void main(String[] args) { 11 | Starter starter = test_main.factory(); 12 | //单事件订阅方式 13 | starter.getConfig().setCode(Intents.GUILD_MESSAGES.getCode()); 14 | 15 | //多事件订阅方式 16 | starter.getConfig().setCode(Intents.START.and(Intents.GUILD_MESSAGES, Intents.DIRECT_MESSAGE)); 17 | 18 | // 公域机器人订阅推荐 19 | starter.getConfig().setCode(Intents.PUBLIC_INTENTS.getCode()); 20 | // 私域机器人订阅推荐 21 | starter.getConfig().setCode(Intents.PRIVATE_INTENTS.getCode()); 22 | starter.run(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/test_bot_all.java: -------------------------------------------------------------------------------- 1 | import io.github.kloping.qqbot.Starter; 2 | import io.github.kloping.qqbot.entities.Bot; 3 | import io.github.kloping.qqbot.entities.qqpd.Guild; 4 | import io.github.kloping.qqbot.entities.qqpd.User; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author github.kloping 11 | */ 12 | public class test_bot_all { 13 | public static void main(String[] args) throws Exception { 14 | Starter starter = test_main.factory(); 15 | starter.run(); 16 | Bot bot = starter.getBot(); 17 | //获取 bot 下所有 频道 18 | List<Guild> guilds = new ArrayList<>(bot.guilds()); 19 | Guild guild = null; 20 | //获得 子频道下 所有 子频道 21 | guild.channels(); 22 | //获得bot信息 23 | User user = bot.getInfo(); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/test_channel_create_delete.java: -------------------------------------------------------------------------------- 1 | import io.github.kloping.qqbot.Starter; 2 | import io.github.kloping.qqbot.entities.Bot; 3 | import io.github.kloping.qqbot.entities.ex.ChannelData; 4 | import io.github.kloping.qqbot.entities.qqpd.Channel; 5 | import io.github.kloping.qqbot.entities.qqpd.Guild; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public class test_channel_create_delete { 11 | 12 | public static void main(String[] args) { 13 | Starter starter = test_main.factory(); 14 | starter.run(); 15 | Bot bot = starter.getBot(); 16 | for (Guild guild : bot.guilds()) { 17 | for (Channel channel : guild.channels()) { 18 | if (channel.getName().equals("xxx")) { 19 | //频道删除 20 | channel.delete(); 21 | } 22 | } 23 | //频道创建 创建详细信息 见 ChannelData 文档 24 | guild.create(new ChannelData() 25 | .name("测试创建子频道") 26 | ); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/test_inputSendMessage.java: -------------------------------------------------------------------------------- 1 | import io.github.kloping.qqbot.Starter; 2 | import io.github.kloping.qqbot.entities.qqpd.Channel; 3 | import io.github.kloping.qqbot.entities.qqpd.Guild; 4 | 5 | import java.util.Scanner; 6 | 7 | /** 8 | * @author github.kloping 9 | */ 10 | public class test_inputSendMessage { 11 | public static void main(String[] args) throws Exception { 12 | Starter starter = test_main.factory(); 13 | starter.run(); 14 | Guild[] guilds = starter.getBot().guilds().toArray(new Guild[0]); 15 | Channel[] channels = starter.getBot().guildBase.getChannels(guilds[0].getId()); 16 | Channel channel = null; 17 | for (Channel channel1 : channels) { 18 | if (channel1.getName().equals("游戏大厅")) { 19 | channel = channel1; 20 | } 21 | } 22 | Thread.sleep(5000); 23 | String line = null; 24 | Scanner sc = new Scanner(System.in); 25 | while (true) { 26 | line = sc.nextLine(); 27 | if (line == null || line.isEmpty()) continue; 28 | channel.send(line); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/test_main.java: -------------------------------------------------------------------------------- 1 | import io.github.kloping.qqbot.Starter; 2 | import io.github.kloping.qqbot.api.Intents; 3 | import io.github.kloping.qqbot.entities.qqpd.Dms; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public class test_main { 9 | 10 | public static void main(String[] args) { 11 | Starter starter = factory(); 12 | //事件订阅 私域机器人 13 | // 推荐Intents.PRIVATE_INTENTS 公域机器人推荐 Intents.PUBLIC_INTENTS 14 | starter.getConfig().setCode(Intents.PRIVATE_INTENTS.getCode()); 15 | //重连 16 | starter.setReconnect(true); 17 | starter.run(); 18 | // 设置日志等级 一般情况无需设置 19 | // starter.APPLICATION.logger.setLogLevel(0); 20 | } 21 | 22 | public static Starter factory() { 23 | Starter starter = new Starter("appid", "token"); 24 | starter.getConfig().setCode(Intents.PRIVATE_INTENTS.getCode()); 25 | return starter; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/test_mute.java: -------------------------------------------------------------------------------- 1 | import io.github.kloping.qqbot.Starter; 2 | import io.github.kloping.qqbot.entities.Bot; 3 | import io.github.kloping.qqbot.entities.qqpd.Guild; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public class test_mute { 9 | public static void main(String[] args) throws Exception { 10 | Starter starter = test_main.factory(); 11 | starter.run(); 12 | Bot bot = starter.getBot(); 13 | Guild guild = null; 14 | guild.getMemberWithGuildId("xxx").mute(1); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/test_onError.java: -------------------------------------------------------------------------------- 1 | import io.github.kloping.qqbot.Starter; 2 | import io.github.kloping.qqbot.api.Intents; 3 | import io.github.kloping.qqbot.network.AuthAndHeartbeat; 4 | import io.github.kloping.qqbot.network.WebSocketListener; 5 | import io.github.kloping.spt.annotations.AutoStand; 6 | import org.java_websocket.client.WebSocketClient; 7 | 8 | /** 9 | * 将 wss error 加入重连 10 | * @author github.kloping 11 | */ 12 | public class test_onError implements WebSocketListener { 13 | 14 | @AutoStand 15 | AuthAndHeartbeat authAndHeartbeat; 16 | 17 | @AutoStand 18 | Starter starter; 19 | 20 | @Override 21 | public boolean onError(WebSocketClient client, Exception e) { 22 | //尝试重连 23 | authAndHeartbeat.identifyConnect(0, client); 24 | return WebSocketListener.super.onError(client, e); 25 | } 26 | 27 | public static void main(String[] args) throws Exception { 28 | Starter starter = new Starter("xxx", "xxx"); 29 | starter.getConfig().setCode(Intents.PRIVATE_INTENTS.getCode()); 30 | //设置websocket 监听 31 | starter.getConfig().setWebSocketListener(new test_onError()); 32 | //切换沙盒 33 | starter.getConfig().sandbox(); 34 | starter.run(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/test_onMessage.java: -------------------------------------------------------------------------------- 1 | import io.github.kloping.qqbot.Starter; 2 | import io.github.kloping.qqbot.api.message.MessageChannelReceiveEvent; 3 | import io.github.kloping.qqbot.api.message.MessageDirectReceiveEvent; 4 | import io.github.kloping.qqbot.api.message.MessageEvent; 5 | import io.github.kloping.qqbot.entities.ex.At; 6 | import io.github.kloping.qqbot.entities.ex.AtAll; 7 | import io.github.kloping.qqbot.entities.ex.Image; 8 | import io.github.kloping.qqbot.entities.ex.PlainText; 9 | import io.github.kloping.qqbot.entities.ex.msg.MessageChain; 10 | import io.github.kloping.qqbot.entities.qqpd.data.Emoji; 11 | import io.github.kloping.qqbot.entities.qqpd.message.RawMessage; 12 | import io.github.kloping.qqbot.impl.ListenerHost; 13 | 14 | /** 15 | * @author github.kloping 16 | */ 17 | public class test_onMessage { 18 | public static void main(String[] args) throws Exception { 19 | Starter starter = test_main.factory(); 20 | starter.run(); 21 | starter.registerListenerHost(new ListenerHost() { 22 | 23 | @EventReceiver 24 | private void event(MessageEvent event) { 25 | RawMessage message = event.getRawMessage(); 26 | message.send("回复测试"); 27 | } 28 | }); 29 | starter.registerListenerHost(new ListenerHost() { 30 | 31 | @EventReceiver 32 | public void onEvent(MessageEvent event) { 33 | event.send("测试"); 34 | } 35 | 36 | @EventReceiver 37 | public void onEvent(MessageDirectReceiveEvent event) { 38 | event.send("测试通过"); 39 | } 40 | 41 | @EventReceiver 42 | public void onMessage(MessageChannelReceiveEvent event) { 43 | //消息类型遍历 44 | MessageChain chain = event.getMessage(); 45 | chain.forEach((e) -> { 46 | if (e instanceof Emoji) { 47 | Emoji emoji = (Emoji) e; 48 | } else if (e instanceof At) { 49 | At at = (At) e; 50 | } else if (e instanceof AtAll) { 51 | AtAll atAll = (AtAll) e; 52 | } else if (e instanceof Image) { 53 | Image image = (Image) e; 54 | } else if (e instanceof PlainText) { 55 | PlainText plainText = (PlainText) e; 56 | } 57 | }); 58 | } 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/test_sendMessage.java: -------------------------------------------------------------------------------- 1 | import io.github.kloping.qqbot.Starter; 2 | import io.github.kloping.qqbot.entities.qqpd.Channel; 3 | import io.github.kloping.qqbot.entities.qqpd.Guild; 4 | 5 | /** 6 | * @author github.kloping 7 | */ 8 | public class test_sendMessage { 9 | public static void main(String[] args) throws Exception { 10 | Starter starter = test_main.factory(); 11 | starter.run(); 12 | Guild[] guilds = starter.getBot().guilds().toArray(new Guild[0]); 13 | Channel[] channels = starter.getBot().guildBase.getChannels(guilds[0].getId()); 14 | Channel channel = null; 15 | for (Channel channel1 : channels) { 16 | if (channel1.getName().equals("游戏大厅")) { 17 | channel = channel1; 18 | } 19 | } 20 | Thread.sleep(5000); 21 | channel.send("测试消息"); 22 | } 23 | } 24 | --------------------------------------------------------------------------------