機器人微信消息推送實現方案

微信羣是一個彙集志同道合朋友們的公共場所,量化交易圈子的微信羣也不例外。最近有很多發明者量化的用戶老是提問,如何能夠爲所欲爲的向微信羣推送消息,好比本身的策略發出了交易信號,可是又不想自動化交易,但願讓機器人提供的信號做爲參考發到微信羣中。git

爲此大概看了一下微信接口,發現須要公衆號才行,並非特別的方便。因此決定另闢蹊徑,嘗試了一下如下方案。因爲做者水平有限,僅僅只能完成此需求的最基本功能,各位看官僅當參考。github

實現方案

決定使用Golang編寫,須要用到Golang的一個庫github.com/go-vgo/robotgo,基本上方案的需求是靠這個庫實現的。微信

首先咱們運行一個服務程序在本身電腦上,代碼以下:函數

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

func postMsg (msg string) {    
    fmt.Println("開始執行任務!") 
    // 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)
        /* 使用圖片識別方式,獲取點擊區域座標
        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)
        }
        */

        // /* 固定區域座標,屏幕右上角座標是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("任務執行完成!") 
}



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)
}

此服務程序的功能就是等待請求,接收到請求以後,調用postMsg函數執行一系列的模擬鼠標移動點擊,輸入的操做,實現打開微信軟件窗口,點擊預先定義好的區域,輸入請求中的信息,發送到微信羣。post


微信窗口點擊區域肯定,測試了兩種方案。第一種,保存微信羣的名稱圖片,在觸發postMsg時加載圖片對比屏幕,找出座標點擊。此種方法識別率不是很高,有時候識別不出來(多是我太菜,沒用對T_T,有大神請指教)。因此用了第二種方案,更加可靠一點,就是固定點擊區域,規劃好一組點擊區域的座標,即:以上代碼中的arrArea變量記錄的座標,你問我座標值哪兒來的?答曰:看屏幕截圖像素座標,量出來的T_T。測試

發明者量化交易平臺上的策略測試程序:spa

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)
    }
}

該策略模擬發出交易信號(n==20時,假設此時觸發交易信號,認爲能夠交易),向本地服務,地址:http://127.0.0.1:9090/data發送請求。3d

測試

發明者量化交易平臺上的機器人運行(託管者也在本地運行):
code

本地服務運行:
blog

微信窗口

推送的消息爲:

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

這個方案僅僅做爲拋磚引玉,有更好方案的歡迎你們討論。

相關文章
相關標籤/搜索