Make a QQ robot with JAVA, help me remind the goddess to drink water on time and chat with her ~ (with source code)

Wechat robot will have the chance to be granted a title and will not open the tutorial for the time being

1. Foreword

The average daily water consumption of normal people is 2000-2500 ml, and the oxidation of substances in the body can produce 300 ml of water. Therefore, 2200 ml of water should be added every day, including the water content in the diet. In summer, the daily supplement of water is about 3000 ml in order to meet the needs of the human body.
If only a robot could remind us to drink water on time

2. Create a springboot project

(this step is for Xiaobai, and the bosses jump to the third step directly)

2.1. New project

2.2. Select the springboot project



2.3. The created project structure is as follows

3. Introducing simple robot robot dependency

3.1. In POM XML file introduces simple robot dependency

<properties>
    <java.version>1.8</java.version>
    <simbot.version>2.0.3</simbot.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>love.forte.simple-robot</groupId>
            <artifactId>parent</artifactId>
            <version>${simbot.version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>
<!--java Robot frame-->
<dependency>
    <groupId>love.forte.simple-robot</groupId>
    <artifactId>component-mirai-spring-boot-starter</artifactId>
</dependency>

3.2. Configure application YML file, using ANDROID_PAD protocol can keep mobile QQ and robot online at the same time

simbot:
  core:
    # QQ account and password of robot (account: password)
    bots: 6013505:yinfeng
  component:
    mirai:
      # mirai heartbeat cycle Too long will cause the server to disconnect In milliseconds.
      heartbeat-period-millis: 30000
      # The time to wait for results at each heartbeat Once the heartbeat times out, the whole network service will restart (it will take about 1 s) Events and plug-ins are not affected except that ongoing tasks (such as image upload) will be interrupted
      heartbeat-timeout-millis: 5000
      # Waiting time before the first reconnection after heartbeat failure
      first-reconnect-delay-millis: 5000
      # Waiting time of each attempt after reconnection failure
      reconnect-period-millis: 5000
      # How many reconnections can I try at most
      reconnection-retry-times: 2147483647
      # Use protocol type. Note: this value is the enumeration class net mamoe. mirai. utils. BotConfiguration. Element value of miraiprotocol,
      # The optional value is ANDROID_PHONE,ANDROID_PAD,ANDROID_WATCH
      protocol: ANDROID_PAD
      # Close mirai bot logger
      no-bot-log: true
      # Close mirai Weblog
      no-network-log: true
      # mirai bot log switch the log using simbot
      use-simbot-bot-log: true
      # mirai network log switch uses simbot log
      use-simbot-network-log: true
      # mirai is a random seed used when configuring custom deviceInfoSeed. The default is 1
      device-info-seed: 1
      # Mirai image caching strategy, enumerating love forte. simbot. component. mirai. configuration. Element value of miraicachetype,
      # The options are FILE and MEMORY
      cache-type: MEMORY
      # If the configuration item simbot mirai. The value of cachetype is FILE. Here is the saving directory of the cache FILE. If it is blank, it is the system temporary folder by default.
      cache-directory:
      # The login verification code processor may be used when the login needs to enter the verification code.
      login-solver-type: DEFAULT
      # If it is not empty, it means to specify a json file path of deviceInfo.
      dispatcher:
        # In the mirai component, the thread pool parameter for scheduling events: the maximum number of threads.
        core-pool-size: 8
        # In the mirai component, the thread pool parameter for scheduling events: the maximum number of threads.
        maximum-pool-size: 8
        # Thread pool parameter for event scheduling in mirai component: thread lifetime (MS)
        keep-alive-time: 1000

3.3 add @ EnableSimbot annotation to springboot startup class

/**
* @author yinfeng
* @description Startup class
* @since 2021/12/22 22:50
*/
@EnableSimbot
@EnableScheduling
@SpringBootApplication
@Slf4j
public class RobotApplication {

   public static void main(String[] args) {
       SpringApplication.run(RobotApplication.class, args);
       log.info("The robot starts successfully~~~~");
   }

}

3.4 official documents of simple robot

https://www.yuque.com/simpler...

4. Write scheduled tasks

4.1. Create a drinknotify Java class

/**
 * @author yinfeng
 * @description Regular drinking reminder
 * @since 2021/12/22 23:32
 */
@Component
@Slf4j
public class DrinkNotify {

    @Resource
    private BotManager botManager;

    @Value("${bello.qq}")
    private Set<String> qqSet;

    /**
     * Drinking water Quotes
     */
    static List<String> content;

    /**
     * Drinking water picture
     */
    static List<String> images;

    static {
        content = new ArrayList<>();
        images = new ArrayList<>();
        log.info("Start loading water Quotes~~~");
        // Drinking water Quotes
        content.add("it is said that\"Women are made of water\",Therefore, as a girl, you should always drink water, so that you can maintain sufficient moisture, and your skin and hair will be more shiny~");
        content.add("Drinking more water can also keep fit, because water promotes the circulation of our body~");
        content.add("It's time to drink water. Drink more water and you'll look radiant as a whole~");
        content.add("It's time to drink water. Take good care of yourself, drink more water, eat more fresh fruits and vegetables, and try to ensure enough sleep. come on.");
        content.add("It's easy to drink more water. Drinking more water is good for your health! Only those who are worried about you will say what your family always says: you should drink more water!!~");
        content.add("The weather is cold and dry. Drink plenty of water and keep warm. Smoke less, drink less and eat spicy food. Miss me so much~");
        log.info("Start loading water pictures~~~");
        // Drinking water picture
        images.add("https://gitee.com/yinfeng-code/study-image/raw/master/image/20211224221637.jpeg");
        images.add("https://gitee.com/yinfeng-code/study-image/raw/master/image/20211224221739.jpeg");
        images.add("https://gitee.com/yinfeng-code/study-image/raw/master/image/20211224221758.jpeg");
        images.add("https://gitee.com/yinfeng-code/study-image/raw/master/image/20211224221815.jpeg");
        images.add("https://gitee.com/yinfeng-code/study-image/raw/master/image/20211224221834.jpeg");
        images.add("https://gitee.com/yinfeng-code/study-image/raw/master/image/20211224221913.jpeg");
        images.add("https://gitee.com/yinfeng-code/study-image/raw/master/image/20211224221925.jpeg");
    }

    /**
     * Remind once every minute: 0 0 / 1 * * *?
     * Remind once every hour: 0 / 1 * *?
     */
    @Scheduled(cron = "0 0 0/1 * * ?")
    public void handler() {
        Calendar calendar = Calendar.getInstance();
        // Get current hour
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        // Send a message reminder only from 9 a.m. to 8 p.m
        if (hour < 9 || hour > 20) {
            return;
        }
        qqSet.forEach(qq -> {
            try {
                final String msg = content.get(new Random().nextInt(content.size()));
                final String img = String.format("[CAT:image,url=%s,flash=false]", images.get(new Random().nextInt(content.size())));
                // Send random drinking Quotes
                botManager.getDefaultBot().getSender().SENDER.sendPrivateMsg(qq, msg);
                // Send random drinking pictures
                botManager.getDefaultBot().getSender().SENDER.sendPrivateMsg(qq, img);
                log.info("Sending water reminder, currently qq={}, Quotations={}, img={}", qq, msg, img);
            } catch (Exception e) {
                log.error("Sending water drinking reminder exception, qq={}", qq, e);
            }

        });
    }

}

4.2. Configure the QQ number of the goddess in the yml file

#Configure the QQ numbers of the goddesses. Multiple QQS are separated by commas
bello:
 qq: 1332483344,52000012

5. Add intelligent chat function

5.1. Here we mainly use the api of Qingyun guest to chat. The official website

http://api.qingyunke.com/

5.2. Encapsulating http tool classes

/**
 * @author yinfeng
 * @description http Tool class
 * @since 2021/12/23 23:21
 */
public class HttpUtil {
    /**
     * Sends a request for the GET method to the specified URL
     *
     * @param url   URL to send the request
     * @param param Request parameter. The request parameter should be in the form of name1 = value1 & Name2 = Value2.
     * @return URL The response result of the remote resource represented
     */
    public static String sendGet(String url, String param) {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try {
            String urlNameString = url;
            if (!StringUtils.isEmpty(param)) {
                urlNameString += "?" + param;
            }
            URL realUrl = new URL(urlNameString);
            // Open connection between and URL
            URLConnection connection = realUrl.openConnection();
            // Set common request properties
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1");
            // Establish actual connection
            connection.connect();
            // Define BufferedReader input stream to read the response of URL
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            System.out.println("send out GET Exception in request!" + e);
            e.printStackTrace();
        }
        // Use the finally block to close the input stream
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result.toString();
    }
}

5.3. Create a message monitoring class to support intelligent chat of private chat messages and group messages

/**
 * @author yinfeng
 * @description Robot monitoring
 * @since 2021/11/6 20:51
 */
@Component
@Slf4j
public class MessageListener {

    static final String URL = "http://api.qingyunke.com/api.php";

    /**
     * Monitor private chat messages
     */
    @OnPrivate
    public void privateMsg(PrivateMsg privateMsg, MsgSender sender) {
        sendMsg(privateMsg, sender, false);
    }

    /**
     * Listen for group messages
     */
    @OnGroup
    public ReplyAble groupMsg(GroupMsg groupMsg, MsgSender sender) {
        // The group chat mode is turned off by default, and the comments are removed if necessary
        // return sendMsg(groupMsg, sender, true);
        return null;
    }

    /**
     * Encapsulate intelligent chat through Qingke cloud
     *
     * @param commonMsg commonMsg
     * @param sender    sender
     */
    private ReplyAble sendMsg(MessageGet commonMsg, MsgSender sender, boolean group) {
        log.info("In smart chat~~~,Receive message: qq={}, msg={}", commonMsg.getAccountInfo().getAccountCode(),
                commonMsg.getMsgContent().getMsg());
        // There are three major senders in MsgSender and many overloaded methods.
        // Call chat interface through get request
        final String result = HttpUtil.sendGet(URL,
                "key=free&appid=0&msg=".concat(commonMsg.getMsgContent().getMsg()));
        if (!StringUtils.isEmpty(result)) {
            final JSONObject json = JSONObject.parseObject(result);
            if (json.getInteger("result") == 0 && !StringUtils.isEmpty(json.getString("content"))) {
                final String msg = json.getString("content").replace("{br}", "\n");
                log.info("In smart chat~~~,Send message: qq={}, msg={}", commonMsg.getAccountInfo().getAccountCode(), msg);
                //Send group message
                if (group) {
                    // Parameter 1: reply message parameter 2: Yes No
                    return Reply.reply(msg, true);
                }
                //Send private chat message
                sender.SENDER.sendPrivateMsg(commonMsg, msg);
            }
        }
        return null;
    }

}

6. Test it

6.1. Start project

6.2. Drinking water reminder test


You can see that both QQS have received reminder messages, and the background log is no problem

6.3. Intelligent chat test

You can see that the chat function is also normal, and the background log is also normal

7. Source address

Temporarily unable to monitor the message = = single friend = = news, old fellow download their own source code to play.

// Source address, download and run
// You can also make a jar package and put it on the server to run all the time
https://gitee.com/yinfeng-code/java-robot.git

The liver is not easy. The old fellow thank you for your support.
The old fellow iron source under the source code points star ha.

8. Common problem handling

8.1. Password error exception

Error(title=Login failed, message=Wrong account or password, please re-enter., errorInfo=)

The screenshot of the exception is as follows

Solution: in application Configure your qq account and password in YML

8.2. Slider validation exception

UnsupportedSliderCaptchaException: Mirai Unable to complete slider validation. Use agreement ANDROID_PHONE Mandatory slider verification, Please replace the agreement and try again. See also 

The screenshot of the exception is as follows

Solution: in application Replace the protocol in YML with PAD protocol or watch protocol

If not, you can refer to the document on the official website of the robot framework Slider login exception

  1. Try Slider verification
  2. Try switching accounts
  3. Open or close the device lock and try it in all cases
  4. Change the network environment, such as switching to hotspot
  5. Use the computer or mobile phone to hang up the account you want to use, and keep the account number before trying
  6. None of the above methods will necessarily succeed, or the probability will not succeed. But for now, it will basically become normal after a period of time. This period of time may be a few days, good luck may be a few hours.

8.3 abnormal idea import after downloading the project


Solution: upgrade your IDEA to 2021 or above. Specific reference Abnormal error of IDEA package Guide

8.4 other robot problems Solution reference

Keywords: Java Spring Spring Boot Back-end

Added by CK9 on Fri, 28 Jan 2022 17:54:49 +0200