This article has participated in the activity of “New person creation Ceremony”, and started the road of digging gold creation together.

Wechat robot will have a chance to close the account, temporarily do not open the tutorial

1, the preface

The average daily water consumption of normal people is 2000-2500 ml, and 300 ml of water can be generated by oxidation of substances in the body. Therefore, 2200 ml of water should be added every day, including the water content in the diet. Daily water supplement in summer 3000 ml or so, to meet the needs of the human body. It would be nice if a robot could remind us to drink water on time

2. Create a SpringBoot project

(This step is for the little white, the big guys jump straight to the third step)

2.1. New project

2.2. Select the SpringBoot project

2.3. The structure of the created project is as follows

3. Introduce the dependency of simple-robot

3.1. Introduce the simple-Robot dependency in the POM.xml file

<properties>
    <java.version>1.8</java.version>
    <simbot.version>The 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>
Copy the code
<! -- Java Robot Framework -->
<dependency>
    <groupId>love.forte.simple-robot</groupId>
    <artifactId>component-mirai-spring-boot-starter</artifactId>
</dependency>
Copy the code

3.2. Configure the application.yml fileANDROID_PAD protocol can be used to keep mobile QQ and robotAt the same time online

simbot:
  core:
    # QQ account and password of the robot (Account number: Password)
    bots: 6013505:yinfeng
  component:
    mirai:
      # Mirai heartbeat cycle. If the length is too long, the server will be disconnected. Unit: millisecond.
      heartbeat-period-millis: 30000
      # The amount of time to wait for results at each heartbeat. Once the heartbeat times out, the entire network service will restart (which will take about 1s). Events and plug-ins will not be affected except for ongoing tasks (such as image uploads) that will be interrupted.
      heartbeat-timeout-millis: 5000
      The wait time before the first reconnection after a heartbeat failure.
      first-reconnect-delay-millis: 5000
      # Wait time for each attempt to continue after reconnection fails
      reconnect-period-millis: 5000
      # Maximum number of reconnection attempts
      reconnection-retry-times: 2147483647
      Use the protocol type. Note, this value is enumerated type net. Mamoe. Mirai. Utils. BotConfiguration. MiraiProtocol element value,
      # Optional values are ANDROID_PHONE, ANDROID_PAD, and ANDROID_WATCH
      protocol: ANDROID_PAD
      Whether to close mirai's bot Logger
      no-bot-log: true
      # Turn off the Mirai weblog
      no-network-log: true
      # mirai bot log Switch to simbot log
      use-simbot-bot-log: true
      # Mirai network log Switch to use simbot log
      use-simbot-network-log: true
      # mirai configures a random seed to use when customizing deviceInfoSeed. The default is 1.
      device-info-seed: 1
      # mirai image caching strategies, for the enumeration love.forte.simbot.com ponent. Mirai. Configuration. MiraiCacheType element value,
      # Select FILE and MEMORY
      cache-type: MEMORY
      If simbot.mirai.cacheType is set to FILE, this is the directory where the cache FILE is saved. If it is empty, it is the system temporary folder by default.
      cache-directory:
      # Login verification code processor, which may be used when a verification code is required for login.
      login-solver-type: DEFAULT
      If not empty, this represents the path to a deviceInfo JSON file.
      dispatcher:
        The thread pool parameter for scheduling events in the # mirai component: the maximum number of threads.
        core-pool-size: 8
        The thread pool parameter for scheduling events in the # mirai component: the maximum number of threads.
        maximum-pool-size: 8
        Thread pool parameter for scheduling events in # mirai component: thread lifetime in milliseconds
        keep-alive-time: 1000
Copy the code

3.3 Annotate @enablesimbot in the SpringBoot boot class

/ * * *@author yinfeng
* @descriptionStart the class@since2021/12/22 o * /
@EnableSimbot
@EnableScheduling
@SpringBootApplication
@Slf4j
public class RobotApplication {

   public static void main(String[] args) {
       SpringApplication.run(RobotApplication.class, args);
       log.info("Robot started successfully ~~~~"); }}Copy the code

3.4 Simple-robot Official document

www.yuque.com/simpler-rob…

4. Write scheduled tasks

4.1. Create a drinknotify.java class

/ * * *@author yinfeng
 * @descriptionDrink water regularly *@since2021/12/22 did * /
@Component
@Slf4j
public class DrinkNotify {

    @Resource
    private BotManager botManager;

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

    /** * drink water */
    static List<String> content;

    /** * drink water */
    static List<String> images;

    static {
        content = new ArrayList<>();
        images = new ArrayList<>();
        log.info("Start loading water quotes ~~~");
        // Drink water
        content.add("As the saying goes \" women are made of water \", so as a girl, you should always drink water, so that you can keep hydrated and your skin and hair will be more shiny.);
        content.add("Drinking plenty of water can also help you stay slim because it promotes circulation.");
        content.add("It's time to drink more water, and you'll look great overall.");
        content.add("It's time to drink water. Take care of yourself. Drink lots of water, eat lots of fresh fruits and vegetables, and try to get enough sleep. Come on!");
        content.add("If it's simple, drinking more water is good for you! Only someone who cares about you will say what your family always says: Drink more water! ~");
        content.add("It was cold and dry. Drink plenty of water and keep warm. Cut down on smoking, drinking and spicy food. How much you miss me.");
        log.info("Start loading water image ~~~");
        // Drink water
        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");
    }

    /** * every minute: 0 0/1 ** *? * Hourly reminder: 0 0 0/1 * *? * /
    @Scheduled(cron = "0 0 0/1 * * ?" )
    public void handler(a) {
        Calendar calendar = Calendar.getInstance();
        // Get the current hour
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        // Only send message alerts between 9am and 8pm
        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 pictures of drinking water
                botManager.getDefaultBot().getSender().SENDER.sendPrivateMsg(qq, img);
                log.info("Sending water reminder, current QQ ={}, quotations ={}, img={}", qq, msg, img);
            } catch (Exception e) {
                log.error("Abnormal send water reminder, QQ ={}", qq, e); }}); }}Copy the code

4.2. Configure the QQ numbers of goddesses in the YML file

# Configure the goddess of QQ number, multiple QQ with commas separated
bello:
 qq: 1332483344, 52000012,
Copy the code

5. Add smart chat

5.1. It is mainly used hereWan keAPI for chat, official website

api.qingyunke.com/

5.2. Encapsulate HTTP utility classes

/ * * *@author yinfeng
 * @descriptionHTTP utility classes *@since2021/12/23 vow * /
public class HttpUtil {
    /** * sends a GET request to the specified URL **@paramUrl Indicates the URL of the request *@paramParam Request parameters. The request parameters should be of the form name1=value1&name2=value2. *@returnThe response result of the remote resource represented by the URL */
    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 the connection with the URL
            URLConnection connection = realUrl.openConnection();
            // Set common request attributes
            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 the actual connection
            connection.connect();
            // Define the BufferedReader input stream to read the response to the URL
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while((line = in.readLine()) ! =null) { result.append(line); }}catch (Exception e) {
            System.out.println(Error sending GET request! + e);
            e.printStackTrace();
        }
        // Close the input stream with a finally block
        finally {
            try {
                if(in ! =null) { in.close(); }}catch(Exception e2) { e2.printStackTrace(); }}returnresult.toString(); }}Copy the code

5.3. To createMessage listener class, support private message and group message intelligent chat

/ * * *@author yinfeng
 * @descriptionRobot monitor@since2021/11/6 20:51 * /
@Component
@Slf4j
public class MessageListener {

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

    /** * listen for private 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) {
        // Group chat mode is disabled by default, uncomment 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("Smart chat ~~~, receive messages: QQ ={}, MSG ={}", commonMsg.getAccountInfo().getAccountCode(),
                commonMsg.getMsgContent().getMsg());
        There are three big transmitters in MsgSender and a lot of overloaded methods.
        // Invoke the chat interface with a 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("Smart chat ~~~, send message: qq={}, MSG ={}", commonMsg.getAccountInfo().getAccountCode(), msg);
                // Send a group message
                if (group) {
                    // Parameter 1: reply message parameter 2: at party
                    return Reply.reply(msg, true);
                }
                // Send a private messagesender.SENDER.sendPrivateMsg(commonMsg, msg); }}return null; }}Copy the code

6. Test it out

6.1. Start the project

6.2. Water reminder test

You can see that both QQ have received a reminder messageBackground the logThat’s fine

6.3. Smart Chat test

You can see that the chat function is working as wellBackground the logIt’s normal

7, the source address

Temporarily unable to monitor == single friends == news, old iron you download the source code to play

// Source code address, download and run
// Jar package can also be placed on the server to run
https://gitee.com/yinfeng-code/java-robot.git
Copy the code

Liver text is not easy, the old iron three even a wave of support, thank you ~ under the source of the old iron trouble point star ha

Eight,Common Problem Handling

8.1. Password error

Error(title= login failed, message= wrong account or password, please enter again. , errorInfo=)Copy the code

The exception screenshot is as follows: The solution: Configure your QQ account and password in application.yml

8.2. Slider validation exception

UnsupportedSliderCaptchaException: Mirai couldn't complete the slider. Using the protocol ANDROID_PHONE forces slider authentication, please change the protocol and try again. See alsoCopy the code

The exception screenshot is as follows:

The solution: Change the protocol to PAD or Watch in application.ymlIf not, refer to the documentation on the robot Framework websiteThe slider login is abnormal

  1. Try slider validation
  2. Try switching accounts
  3. Turn on or off the device lock, try everything
  4. Change the network environment, for example, switch to a hotspot
  5. Use your computer or mobile phone to hang up your account number and keep it open before you try again
  6. None of these methods will succeed, or will most likely not. But for now, after a while, it’s going to be pretty much normal. It could be days, or hours if you’re lucky.

8.3 Idea import exception after downloading the project

Solution: Upgrade your IDEA to 2021 or later. Specific referenceIDEA Packet guide error occurs

8.4 Robot otherThe problemSolution Reference