Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rfancn committed Dec 6, 2024
0 parents commit a1da5bd
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .gitignore
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*

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# hd third party libraries
third party libraries
14 changes: 14 additions & 0 deletions go.mod
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
)
38 changes: 38 additions & 0 deletions go.sum
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=
2 changes: 2 additions & 0 deletions smsforwarder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# SmsForwarder

73 changes: 73 additions & 0 deletions smsforwarder/raw_message.go
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
//}
32 changes: 32 additions & 0 deletions smsforwarder/smsforwarder.go
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
}
77 changes: 77 additions & 0 deletions smsforwarder/wechat_message.go
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
}

0 comments on commit a1da5bd

Please sign in to comment.