Skip to content

BOT应用后端开发

1.1 BOT应用与开发者交互流程图

BOT应用与开发者交互流程图

1.2 开发者承接用户发给BOT应用的消息

用户给BOT应用发消息后,MosApp会将消息通过开发者配置的webhook透传给开发者。

1.2.1 webhook参数说明

属性类型必填说明
reqIdString请求id,每个请求唯一
eventTypeString事件类型: message/callbackQuery
timestampLong事件发生时间戳
botAppIdStringbot应用id
sender发送者信息对象
nicknameString用户昵称
conversation会话信息对象
conversationIdString会话id
message用户发送的消息内容(Message 对象),仅在 eventType 为 message 时存在
messageIdString用户发送的消息的消息id
textString发送文本
timestampLong消息发送时间
callbackQuery内联按钮点击事件的详细信息(CallbackQuery 对象),仅在 eventType 为 callback_query 时存在
dataString回调数据(通常由开发者定义)
inlineMessageIdString内联消息id
miniApp微应用信息对象 BotApp绑定了微应用,该实体有值
openidString用户在对应微应用中的openid

1.2.2 Java使用范例

请求入参

java
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 点击内联按钮入参
 * @author admin001
 * @date 2025/7/8 19:55
 */
@Data
@Accessors(chain = true)
public class WebhookParam implements Serializable {

    private static final long serialVersionUID = 6142195922243220516L;

    /**
     * 请求id,每个请求唯一
     */
    private String reqId;

    /**
     * 事件类型: message/callbackQuery
     */
    private String eventType;

    /**
     * 事件发生时间戳
     */
    private Long timestamp;

    /**
     * botApp id
     */
    private String botAppId;

    /**
     * 发送者信息,表示发起事件的用户。
     */
    private UserInfo sender;

    /**
     * 会话信息
     */
    private Conversation conversation;

    /**
     * 用户发送的消息内容(Message 对象),仅在 eventType 为 message 时存在
     */
    private Message message;

    /**
     * 内联按钮点击事件的详细信息(CallbackQuery 对象),仅在 eventType 为 callback_query 时存在。
     */
    private CallbackQuery callbackQuery;

    /**
     * 微应用信息 BotApp绑定了微应用,该实体有值
     */
    private MiniApp miniApp;


    // 嵌套类: 用户信息
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Data
    public static class UserInfo implements Serializable {
        private static final long serialVersionUID = 1L;

        /**
         * 用户昵称
         */
        private String nickname;
    }

    // 嵌套类: 会话信息
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Data
    public static class Conversation implements Serializable {
        private static final long serialVersionUID = 1L;

        /**
         * 会话id
         */
        private String conversationId;
    }

    // 嵌套类: 消息信息
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Data
    public static class Message implements Serializable {
        private static final long serialVersionUID = 1L;

        /**
         * 用户发送的消息的消息id
         */
        private String messageId;
        /**
         * 发送文本
         */
        private String text;
        /**
         * 消息发送时间
         */
        private Long timestamp;

    }

    // 嵌套类: 回调查询(内联按钮点击)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Data
    public static class CallbackQuery implements Serializable {
        private static final long serialVersionUID = 1L;

        /**
         * 回调数据(通常由开发者定义)
         */
        private String data;
        /**
         * 内联消息id
         */
        private String inlineMessageId;

    }

    // 嵌套类: 微应用信息
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Data
    public static class MiniApp implements Serializable {
        private static final long serialVersionUID = 1L;

        /**
         * 用户在对应微应用中的openid
         */
        private String openid;

    }

}

控制器类

java
@RestController
@RequestMapping("/botApp")
@Slf4j
public class BotAppController {

    @PostMapping("/webhook")
    public Void miniAppLogin(@RequestBody WebhookParam webhookParam) {
        log.info("webhookParam: {}", webhookParam);
        // other code
    }
}

1.3 开发者响应用户消息

1.3.1 MosApp open api地址

https://mos-test.mos.me/open-apis/botApp/v1/sendMessage/{token}

token为创建应用后唯一生成的字符串,请到bot应用详情中进行查看与复制,需妥善保管,不可泄露。

1.3.2 入参说明

属性类型必填说明
reqIdString请求id,每个请求唯一
conversationIdString会话id
editCurrentBoolean是否编辑单条消息
inlineMessageIdString内联消息id
textString消息内容
textString按钮文案
typeString按钮类型(callback/url/miniApp)详细说明见下"内联按钮类型说明"
dataString按钮键值 详细说明见下"内联按钮键值详细说明"

内联按钮类型说明:

  1. callback : 回调类型,用户点击触发一条eventType=callbackQuery的消息发送至webhook,消息不显示在会话上,消息会将将按钮data值发给开发者
  2. url : 跳转url,点击打开浏览器显示指定链接(如果是内部链接如用户、群组、频道等链接,点击将MosApp应用内直接进入)
  3. miniApp: 微应用跳转按钮,用过BOT应用绑定了微应用,点击将打开绑定的微应用

内联按钮键值说明:

  1. 内联按钮类型是callback类型,则data为开发者配置的字符串,用户点击按钮式,MosApp会将data内容透传给开发者,方便开发者区分用户点击哪个按钮
  2. 内联按钮类型是url类型,则data为开发者配置的外部url链接或MosApp内部链接
  3. 内联按钮类型miniApp类型,则data无需配置

1.3.3 Java使用范例

请求入参

java
package com.wecloud.modules.openapi.bot.ao;

import lombok.Data;

import java.util.List;

@Data
public class BotAppMessageAo {

    /**
     * 请求id
     */
    private String reqId;

    /**
     * 会话id
     */
    private String conversationId;

    /**
     * 消息内容
     */
    private String text;

    /**
     * 内联按钮 二维数组
     */
    private List<List<InlineButton>> inlineButtons;

    /**
     * 是否编辑单条消息
     */
    private Boolean editCurrent;

    /**
     * 内联消息id
     */
    private String inlineMessageId;

    @Data
    public static class InlineButton {
        /**
         * 按钮文案
         */
        private String text;
    
        /**
         * 按钮类型
         */
        private String type;
    
        /**
         * 按钮键值 开发者用来区分是哪个按钮
         */
        private String data;
    }
}

处理用户消息并响应

java
@RestController
@RequestMapping("/botApp")
@Slf4j
public class BotAppController {

    // bot app token
    private static final String token = "bot app token";
    // open api base Request
    private static final String openApiBaseUrl = "https://mos.mos.me/open-apis/botApp/v1/sendMessage/";

    // envet type
    private static final String EVENT_TYPE_CALLBACK_QUERY = "CALLBACK_QUERY";
    private static final String EVENT_TYPE_MESSAGE = "MESSAGE";

    @Autowired
    private RestTemplate restTemplate;

    @PostMapping("/webhook")
    public Void miniAppLogin(@RequestBody WebhookParam webhookParam) {
        log.info("webhookParam: {}", webhookParam);
        BotAppMessageAo botAppMessageAo = new BotAppMessageAo();
        WebhookParam.Conversation conversation = webhookParam.getConversation();
        botAppMessageAo.setReqId(webhookParam.getReqId());
        botAppMessageAo.setConversationId(conversation.getConversationId());
        // 内联按钮请求
        if (EVENT_TYPE_CALLBACK_QUERY.equals(webhookParam.getEventType())) {
            WebhookParam.CallbackQuery callbackQuery = webhookParam.getCallbackQuery();
            String data = callbackQuery.getData();
            botAppMessageAo.setText(data);
            // 内联按钮
            List<List<InlineButton>> inlineButtons = new ArrayList<>();
            // 第一行
            List<InlineButton> inlineButtonRow1 = new ArrayList<>();
            InlineButton row1Column1 = new InlineButton();
            row1Column1.setText("row1Column1");
            row1Column1.setType("callback");
            row1Column1.setData("row1Column1");
            inlineButtonRow1.add(row1Column1);
            InlineButton row2Column2 = new InlineButton();
            row2Column2.setText("row2Column2");
            row2Column2.setType("callback");
            row2Column2.setData("row2Column2");
            inlineButtonRow1.add(row2Column2);
            inlineButtons.add(inlineButtonRow1);
            // 第二行
            List<InlineButton> inlineButtonRow2 = new ArrayList<>();
            InlineButton row2Column1 = new InlineButton();
            row2Column1.setText("row2Column1");
            row2Column1.setType("url");
            row2Column1.setData("https://www.google.com/");
            inlineButtonRow2.add(row2Column1);
            inlineButtons.add(inlineButtonRow2);
            // 第三行
            List<InlineButton> inlineButtonRow3 = new ArrayList<>();
            InlineButton row3Column1 = new InlineButton();
            row3Column1.setText("row3Column1");
            row3Column1.setType("miniApp");
            row3Column1.setData("https://www.google.com/");
            inlineButtonRow3.add(row3Column1);
            inlineButtons.add(inlineButtonRow3);
            botAppMessageAo.setInlineButtons(inlineButtons);
            botAppMessageAo.setEditCurrent(true);
            botAppMessageAo.setInlineMessageId(callbackQuery.getInlineMessageId());
        }
        // 消息请求
        else if (EVENT_TYPE_MESSAGE.equals(webhookParam.getEventType())) {
            WebhookParam.Message message = webhookParam.getMessage();
            String data = message.getText();
            if ("/start".equals(data)) {
                botAppMessageAo.setText(data);
                // 内联按钮
                List<List<InlineButton>> inlineButtons = new ArrayList<>();
                // 第一行
                List<InlineButton> inlineButtonRow1 = new ArrayList<>();
                InlineButton row1Column1 = new InlineButton();
                row1Column1.setText("row1Column1");
                row1Column1.setType("callback");
                row1Column1.setData("row1Column1");
                inlineButtonRow1.add(row1Column1);
                InlineButton row2Column2 = new InlineButton();
                row2Column2.setText("row2Column2");
                row2Column2.setType("callback");
                row2Column2.setData("row2Column2");
                inlineButtonRow1.add(row2Column2);
                inlineButtons.add(inlineButtonRow1);
                // 第二行
                List<InlineButton> inlineButtonRow2 = new ArrayList<>();
                InlineButton row2Column1 = new InlineButton();
                row2Column1.setText("row2Column1");
                row2Column1.setType("url");
                row2Column1.setData("https://www.google.com/");
                inlineButtonRow2.add(row2Column1);
                inlineButtons.add(inlineButtonRow2);
                // 第三行
                List<InlineButton> inlineButtonRow3 = new ArrayList<>();
                InlineButton row3Column1 = new InlineButton();
                row3Column1.setText("row3Column1");
                row3Column1.setType("miniApp");
                row3Column1.setData("https://www.google.com/");
                inlineButtonRow3.add(row3Column1);
                inlineButtons.add(inlineButtonRow3);
        
                botAppMessageAo.setInlineButtons(inlineButtons);
                botAppMessageAo.setEditCurrent(false);
                botAppMessageAo.setInlineMessageId("");
            } else {
                botAppMessageAo.setText(data);
                botAppMessageAo.setEditCurrent(false);
                botAppMessageAo.setInlineMessageId("");
            }
        }
        try {
            String url = openApiBaseUrl + token;
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<BotAppMessageAo> requestEntity = new HttpEntity<>(botAppMessageAo, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
        } catch (Exception e) {
            log.error("error ", e);
        }
    }
}