-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a1da5bd
Showing
8 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# 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/ | ||
.idea/ | ||
logs/ | ||
*.err | ||
*.dump | ||
*.proto | ||
*.xlsx | ||
|
||
# Ignore other pb files, only keep used | ||
go.work* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# hd third party libraries | ||
third party libraries |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
module github.com/hdget/hd3rdparty | ||
|
||
go 1.23.1 | ||
|
||
require ( | ||
github.com/golang-module/carbon/v2 v2.3.12 | ||
github.com/hdget/hdutils v0.0.32 | ||
github.com/pkg/errors v0.9.1 | ||
) | ||
|
||
require ( | ||
github.com/spf13/cast v1.6.0 // indirect | ||
golang.org/x/text v0.16.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= | ||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= | ||
github.com/golang-module/carbon/v2 v2.3.12 h1:VC1DwN1kBwJkh5MjXmTFryjs5g4CWyoM8HAHffZPX/k= | ||
github.com/golang-module/carbon/v2 v2.3.12/go.mod h1:HNsedGzXGuNciZImYP2OMnpiwq/vhIstR/vn45ib5cI= | ||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||
github.com/hdget/hdutils v0.0.32 h1:T1G9dPTaMQY0J42iBhzaJMsfYlQ1XjKmrHpkSIbFG3g= | ||
github.com/hdget/hdutils v0.0.32/go.mod h1:arsMf+mKyL/qwlQwGE/4JGsdNs9m8t2a3t1AFkIn6D0= | ||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | ||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | ||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | ||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= | ||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= | ||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= | ||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= | ||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | ||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | ||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= | ||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# SmsForwarder | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package smsforwarder | ||
|
||
import ( | ||
"encoding/json" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
type RawMessage struct { | ||
Content string `json:"content"` | ||
From string `json:"from"` | ||
Sign string `json:"sign"` | ||
Timestamp string `json:"timestamp"` | ||
} | ||
|
||
func NewRawMessage(data []byte, secret string) (*RawMessage, error) { | ||
var msg RawMessage | ||
err := json.Unmarshal(data, &msg) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
valid, err := msg.validate(secret) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if !valid { | ||
return nil, errors.New("invalid raw message") | ||
} | ||
|
||
return &msg, nil | ||
} | ||
|
||
func (m *RawMessage) validate(secret string) (bool, error) { | ||
sign, err := generateSignature(m.Timestamp, secret) | ||
if err != nil { | ||
return false, errors.New("failed to generate signature") | ||
} | ||
|
||
return m.Sign == sign, nil | ||
} | ||
|
||
// | ||
//func (m *RawMessage) parseContent(s string) (*WechatMessage, error) { | ||
// if s == "" { | ||
// return nil, errors.New("empty content") | ||
// } | ||
// | ||
// tokens := strings.Split(s, "\n") | ||
// if len(tokens) != 6 { | ||
// return nil, errors.New("invalid content format") | ||
// } | ||
// | ||
// strTime, scene, content := tokens[4], tokens[2], regexRemoveUnused.ReplaceAllString(tokens[1], "") | ||
// index := strings.Index(content, ":") | ||
// if index == -1 { | ||
// return nil, fmt.Errorf("invalid message content, content: %s", content) | ||
// } | ||
// | ||
// if !carbon.Parse(strTime).IsValid() { | ||
// return nil, fmt.Errorf("invalid message time, time: %s", strTime) | ||
// } | ||
// | ||
// sender := content[:index] | ||
// msgContent := strings.TrimSpace(content[index+1:]) | ||
// | ||
// return &WechatMessage{ | ||
// Created: strTime, | ||
// Scene: scene, | ||
// Sender: sender, | ||
// Content: msgContent, | ||
// }, nil | ||
//} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package smsforwarder | ||
|
||
import ( | ||
"crypto/hmac" | ||
"crypto/sha256" | ||
"encoding/base64" | ||
"fmt" | ||
convertUtils "github.com/hdget/hdutils/convert" | ||
"github.com/pkg/errors" | ||
"net/url" | ||
) | ||
|
||
// GenerateSignature 签名算法 | ||
func generateSignature(timestamp, secret string) (string, error) { | ||
if timestamp == "" || secret == "" { | ||
return "", errors.New("timestamp or secret is empty") | ||
} | ||
|
||
// 构建待签名字符串 | ||
stringToSign := fmt.Sprintf("%s\n%s", timestamp, secret) | ||
stringToSignEnc := []byte(stringToSign) | ||
|
||
// 生成HMAC SHA256签名 | ||
hmacCode := hmac.New(sha256.New, convertUtils.StringToBytes(secret)) | ||
hmacCode.Write(stringToSignEnc) | ||
signature := base64.StdEncoding.EncodeToString(hmacCode.Sum(nil)) | ||
|
||
// 对签名进行URL编码 | ||
encodedSign := url.QueryEscape(signature) | ||
|
||
return encodedSign, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package smsforwarder | ||
|
||
import ( | ||
"fmt" | ||
"github.com/golang-module/carbon/v2" | ||
"github.com/pkg/errors" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
type WechatMessageKind int | ||
|
||
const ( | ||
WechatMessageKindUnknown WechatMessageKind = iota | ||
WechatMessageKindOne2One // 单聊消息 | ||
WechatMessageKindGroup // 群聊消息 | ||
) | ||
|
||
type WechatMessage struct { | ||
Kind WechatMessageKind | ||
Created string | ||
Group string | ||
Sender string | ||
Content string | ||
} | ||
|
||
var ( | ||
regexRemoveUnused = regexp.MustCompile(`^\[[^\]]*\]`) | ||
) | ||
|
||
func NewWechatMessage(data []byte, secret string) (*WechatMessage, error) { | ||
rawMessage, err := NewRawMessage(data, secret) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return parseContent(rawMessage.Content) | ||
} | ||
|
||
func parseContent(s string) (*WechatMessage, error) { | ||
if s == "" { | ||
return nil, errors.New("empty content") | ||
} | ||
|
||
tokens := strings.Split(s, "\n") | ||
if len(tokens) != 6 { | ||
return nil, errors.New("invalid content format") | ||
} | ||
|
||
strTime, scene, content := tokens[4], tokens[2], regexRemoveUnused.ReplaceAllString(tokens[1], "") | ||
index := strings.Index(content, ":") | ||
if index == -1 { | ||
return nil, fmt.Errorf("invalid message content, content: %s", content) | ||
} | ||
|
||
if !carbon.Parse(strTime).IsValid() { | ||
return nil, fmt.Errorf("invalid message time, time: %s", strTime) | ||
} | ||
|
||
sender := content[:index] | ||
|
||
// 如果消息的联系人和发送者是一样,则表示是单聊消息,否则认为是群聊消息 | ||
kind := WechatMessageKindOne2One | ||
group := "" | ||
if scene != sender { | ||
kind = WechatMessageKindGroup | ||
group = scene | ||
} | ||
|
||
return &WechatMessage{ | ||
Kind: kind, | ||
Created: strTime, | ||
Group: group, | ||
Sender: sender, | ||
Content: strings.TrimSpace(content[index+1:]), | ||
}, nil | ||
} |