Loading ...

Robot WeChat message push implementation scheme

Author: , Created: 2020-07-24 09:52:33, Updated:

WeChat group is a public place where like-minded friends gather, and the WeChat group in the quantitative trading circle is no exception. Recently, many FMZ users ask how they can push messages to the WeChat group. For example, their strategy sends out a trading signal, but they don’t want to automate the transaction. They hope that the signal provided by the robot can be sent to the WeChat group as a reference.

For this reason, I probably looked at the WeChat interface and found that an official account is needed, which is not particularly convenient. So I decided to take a different approach and tried the following solutions. Due to the limited capacity of me, only the most basic function of this requirement can be completed, and it is for reference only.

Implementation plan

I decided to use Golang to write, need to use a Golang library github.com/go-vgo/robotgo, basically the requirements of the solution is achieved by this library.

First we run a service program on our computer, the code is as follows:

package main 
import (
    "fmt"
    "time"
    "github.com/go-vgo/robotgo" 
    "net/http"
    "io/ioutil"
)

func postMsg (msg string) {    
    fmt.Println("Start the mission!") 
    // process ids
    processIds := "WeChat"
    fpid, err3 := robotgo.FindIds(processIds)
    robotgo.ActivePID(fpid[0])
    time.Sleep(time.Millisecond * 2000)
    if err3 == nil {
        fmt.Println(fmt.Sprintf("find %s", processIds), "ids:", fpid)
        /* Use image recognition method to get the coordinates of the click area
        arrPicFileName := []string{"pic1.png", "pic2.png", "pic3.png"}
        for _, name := range arrPicFileName {
            picPath := fmt.Sprintf("/xxx/xxx/Desktop/xxx/%s", name)
            fmt.Println("picPath:", fmt.Sprintf("/xxx/xxx/Desktop/xxx/%s", name))
            fx, fy := robotgo.FindPic(picPath)
            fmt.Println("move to :", fx+10, fy+10)
            robotgo.MoveMouseSmooth(fx+10, fy+10)
            time.Sleep(time.Millisecond * 2000)
            robotgo.MouseClick("left", false)
            robotgo.TypeStr(msg)
            time.Sleep(time.Second)
            robotgo.KeyTap("enter")
            time.Sleep(time.Second)
        }
        */

        // /* Fixed area coordinates, the coordinates of the upper right corner of the screen are 0,0
        arrArea := []map[string]int{
            map[string]int{
                "x" : 190,
                "y" : 200,
            },
            map[string]int{
                "x" : 190,
                "y" : 200+70,
            },
            map[string]int{
                "x" : 190,
                "y" : 200+70+70,
            },
        }
        for _, area := range arrArea {
            robotgo.MoveMouseSmooth(area["x"], area["y"])
            time.Sleep(time.Millisecond * 2000)
            robotgo.MouseClick("left", false)
            robotgo.TypeStr(msg)
            time.Sleep(time.Second)
            robotgo.KeyTap("enter")
            time.Sleep(time.Second)
        }
        // */
    }
    fmt.Println("The mission is complete!") 
}



func Handle (w http.ResponseWriter, r *http.Request) {
    b, err := ioutil.ReadAll(r.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println("req body:", string(b)) 
    postMsg(string(b))
    w.Write([]byte("finished!"))
}

func main () {
    fmt.Println("listen http://127.0.0.1:9090")
    http.HandleFunc("/data", Handle)
    http.ListenAndServe("127.0.0.1:9090", nil)
}

The function of this service program is to wait for the request. After receiving the request, call the postMsg function to perform a series of simulated mouse movement clicks and input operations to open the WeChat software window, click on the predefined area, enter the information in the request, and send To the WeChat group.

Click the area on the WeChat window to confirm and test two scenarios. The first is to save the name image of the WeChat group, load the image comparison screen when postMsg is triggered, and find the coordinates to click. The recognition rate of this method is not very high, and sometimes it can’t be recognized. So the second solution is used, which is more reliable. It is to fix the click area and plan a set of coordinates of the click area, that is: the coordinates recorded by the arrArea variable in the above code. Where is the coordinates? Answer: Look at the pixel coordinates of the screenshot and measure T_T.

The FMZ platform strategy test program:

function main() {
    var msg = {
        "type" : "msg",
        "robotId" : _G(),
        "msg" : "hello fmz!"
    }
    var n = 0 
    while(true) {
        if(n == 20) {
            var ret = HttpQuery("http://127.0.0.1:9090/data", JSON.stringify(msg))
            Log("Exit")
            break    
        }
        n++
        LogStatus(_D(), "n:", n)
        Sleep(1000)
    }
}

This strategy simulates sending a transaction signal (when n==20, assuming that the transaction signal is triggered at this time, and it is considered possible to trade), it sends a request to the local service at http://127.0.0.1:9090/data.

Test

The FMZ robot operation (the docker also runs locally):

img

img

WeChat window

img

The push message is:

{"type":"msg","robotId":130350,"msg":"hello fmz!"}

This plan is just to start with, and if you have a better plan, you are welcome to discuss it.


More