Skip to content

Commit

Permalink
init project
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackHole1 committed May 18, 2019
0 parents commit f607aae
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .gitignore
@@ -0,0 +1,20 @@
# Created by .ignore support plugin (hsz.mobi)
### Go template
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# IDE
.idea
133 changes: 133 additions & 0 deletions entry.go
@@ -0,0 +1,133 @@
package wxwork_message_sdk

import (
"encoding/json"
"encoding/xml"
"fmt"
"io/ioutil"
"log"
"net/http"
"strconv"
"strings"
)

import (
"github.com/julienschmidt/httprouter"
"github.com/sbzhu/weworkapi_golang/wxbizmsgcrypt"
)

type ErrorInfo struct {
Code int `json:"code"`
Msg string `json:"msg"`
}

type MsgContent struct {
ToUsername string `xml:"ToUserName"`
FromUsername string `xml:"FromUserName"`
CreateTime uint32 `xml:"CreateTime"`
MsgType string `xml:"MsgType"`
Content string `xml:"Content"`
Msgid string `xml:"MsgId"`
Agentid uint32 `xml:"AgentId"`
}

type Wx struct {
WxCrypt *wxbizmsgcrypt.WXBizMsgCrypt
Path string
Port string
RegistryHandle map[string]func(textContent string) (content string, err error)
Delimiters []string
}

func verifyController(wxCrypt *wxbizmsgcrypt.WXBizMsgCrypt) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
params := r.URL.Query()
msgSignature := params.Get("msg_signature")
timestamp := params.Get("timestamp")
nonce := params.Get("nonce")
echostr := params.Get("echostr")

// 进行解密
sEchoStr, cryptErr := wxCrypt.VerifyURL(msgSignature, timestamp, nonce, echostr)
if nil != cryptErr {
resultBytes, _ := json.Marshal(ErrorInfo{
Code: cryptErr.ErrCode,
Msg: cryptErr.ErrMsg,
})
_, _ = fmt.Fprintf(w, string(resultBytes))
return
}

_, _ = fmt.Fprintf(w, string(sEchoStr))
}
}

func receiveController(wx *Wx) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
params := r.URL.Query()
msgSignature := params.Get("msg_signature")
timestamp := params.Get("timestamp")
nonce := params.Get("nonce")
xmlData, _ := ioutil.ReadAll(r.Body)
// 进行解密
msg, cryptErr := wx.WxCrypt.DecryptMsg(msgSignature, timestamp, nonce, xmlData)
if nil != cryptErr {
return
}

var msgContent MsgContent
err := xml.Unmarshal(msg, &msgContent)
if nil != err {
return
}
content := strings.ToLower(msgContent.Content)
result := "没有匹配到相应结果"

prefix, content := formatContext(content, wx.Delimiters)

fmt.Println(prefix)
fmt.Println(content)

switch {
case nil != wx.RegistryHandle[prefix]:
result, err = wx.RegistryHandle[prefix](content)
if nil != err {
result = err.Error()
}
}

responseData := "<xml><ToUserName><![CDATA[" + msgContent.ToUsername + "]]></ToUserName><FromUserName><![CDATA[" + msgContent.FromUsername + "]]></FromUserName><CreateTime>" + strconv.FormatUint(uint64(msgContent.CreateTime), 10) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + result + "]]></Content><MsgId>" + msgContent.Msgid + "</MsgId><AgentID>" + strconv.FormatUint(uint64(msgContent.Agentid), 10) + "</AgentID></xml>"

sEncryptMsg, cryptErr := wx.WxCrypt.EncryptMsg(responseData, timestamp, nonce)
if nil != cryptErr {
return
}

_, _ = fmt.Fprint(w, string(sEncryptMsg))
}
}

func Create(token string, corpId string, encodingAesKey string) func(path string, port string, delimiters []string) *Wx {
return func(path string, port string, delimiters []string) *Wx {
wxCrypt := wxbizmsgcrypt.NewWXBizMsgCrypt(token, encodingAesKey, corpId, wxbizmsgcrypt.XmlType)
return &Wx{
RegistryHandle: make(map[string]func(textContent string) (content string, err error)),
WxCrypt: wxCrypt,
Path: path,
Port: port,
Delimiters: delimiters,
}
}
}

func (w *Wx) Run() {
router := httprouter.New()
router.GET(w.Path, verifyController(w.WxCrypt))
router.POST(w.Path, receiveController(w))
fmt.Println("Server Started!")
log.Fatal(http.ListenAndServe(w.Port, router))
}

func (w *Wx) Registry(handel func(textContent string) (content string, err error), levels ...string) {
w.RegistryHandle[strings.ToLower(strings.Join(levels, " "))] = handel
}
85 changes: 85 additions & 0 deletions utils.go
@@ -0,0 +1,85 @@
package wxwork_message_sdk

import (
"strings"
)

// 正确获取中文下标,从0开始
func unicodeIndex(str, substr string) int {
result := strings.Index(str, substr)
if result >= 0 {
prefix := []byte(str)[0:result]
rs := []rune(string(prefix))
result = len(rs)
}

return result
}

// 获取当前句子的标记符下标(针对多个标记符的情况)
func getDelimiterIndexForMultiple(content string, delimiters []string) int {
index := len([]rune(content))

for _, delimiter := range delimiters {
currentDelimiterIndex := unicodeIndex(content, delimiter) + 1

// 开始和最后的标识符不理会
// 如果没有标记符也不理会
if currentDelimiterIndex > 1 && currentDelimiterIndex < index && index != 0 {
index = currentDelimiterIndex
}
}

if index == len([]rune(content)) {
return 0
}

return index
}

// 获取当前句子的标记符下标(针对单个标记符的情况)
func getDelimiterIndex(content string, delimiter string) int {
index := unicodeIndex(content, delimiter) + 1
if index > 1 {
return index
}
return index
}

// 格式化句子
func formatContext(content string, delimiters []string) (string, string) {
index := 0

if len(delimiters) == 1 {
index = getDelimiterIndex(content, delimiters[0])
} else {
index = getDelimiterIndexForMultiple(content, delimiters)
}

if index == 0 {
return content, content
}

// 当前句子的标识符
delimiter := string([]rune(content)[index-1 : index])

// 后面是否还有
behind := strings.Index(string([]rune(content)[:index]), delimiter)

if behind == -1 {
return strings.ToLower(string([]rune(content)[:index-1])), content
}

prefix := string([]rune(content)[:index - 1])
content = string([]rune(content)[index:])

nextPrefix, nextContent := formatContext(content, []string{delimiter})

content = nextContent
if nextPrefix != nextContent {
prefix = prefix + " " + nextPrefix
content = nextContent
}

return strings.Trim(prefix, " "), strings.Trim(content, " ")
}

0 comments on commit f607aae

Please sign in to comment.