generated from bing/readnotes
feat 添加微信测试
This commit is contained in:
parent
43a9ee0038
commit
9d64a57c6c
14
go.mod
14
go.mod
|
@ -4,7 +4,9 @@ go 1.17
|
|||
|
||||
require (
|
||||
github.com/coreos/go-oidc/v3 v3.1.0
|
||||
github.com/gin-gonic/gin v1.8.1
|
||||
github.com/spf13/cobra v1.3.0
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
k8s.io/api v0.23.1
|
||||
k8s.io/apimachinery v0.23.1
|
||||
k8s.io/client-go v0.23.1
|
||||
|
@ -12,7 +14,12 @@ require (
|
|||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-logr/logr v1.2.0 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.10.0 // indirect
|
||||
github.com/goccy/go-json v0.9.7 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
|
@ -21,18 +28,21 @@ require (
|
|||
github.com/imdario/mergo v0.3.5 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
|
42
go.sum
42
go.sum
|
@ -131,6 +131,10 @@ github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWp
|
|||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
|
@ -146,7 +150,17 @@ github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34
|
|||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
|
@ -287,10 +301,15 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
|||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
|
@ -305,6 +324,7 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
|||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
|
@ -327,7 +347,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
|
|||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
|
@ -342,8 +361,12 @@ github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
|||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
@ -366,6 +389,9 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
|
|||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
||||
|
@ -391,10 +417,15 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
@ -424,6 +455,7 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3
|
|||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -832,14 +864,16 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
|||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package curl
|
||||
|
||||
import "net/http"
|
||||
|
||||
type CURL interface {
|
||||
DoRequest(string, string, interface{}, http.Header) (*http.Response, error)
|
||||
DoRequestReturnBytes(string, string, interface{}, http.Header) ([]byte, error)
|
||||
Get(string, interface{}, http.Header) ([]byte, error)
|
||||
Put(string, interface{}, http.Header) ([]byte, error)
|
||||
Post(string, interface{}, http.Header) ([]byte, error)
|
||||
Delete(string, interface{}, http.Header) ([]byte, error)
|
||||
Patch(string, interface{}, http.Header) ([]byte, error)
|
||||
}
|
||||
|
||||
var curl CURL
|
||||
|
||||
func init() {
|
||||
curl = V1(http.Header{})
|
||||
}
|
||||
|
||||
func DoRequest(method, url string, body interface{}, header http.Header) (*http.Response, error) {
|
||||
return curl.DoRequest(method, url, body, header)
|
||||
}
|
||||
|
||||
func DoRequestReturnBytes(method, url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return curl.DoRequestReturnBytes(method, url, body, header)
|
||||
}
|
||||
|
||||
func Get(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return curl.Get(url, body, header)
|
||||
}
|
||||
|
||||
func Put(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return curl.Put(url, body, header)
|
||||
}
|
||||
|
||||
func Post(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return curl.Post(url, body, header)
|
||||
}
|
||||
|
||||
func Patch(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return curl.Patch(url, body, header)
|
||||
}
|
||||
|
||||
func Delete(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return curl.Delete(url, body, header)
|
||||
}
|
||||
|
||||
func SimpleGet(url string) ([]byte, error) {
|
||||
return curl.Get(url, nil, nil)
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
package curl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
netURL "net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type curlV1 struct {
|
||||
DefaultHeader http.Header
|
||||
}
|
||||
|
||||
func V1(defaultHeader http.Header) *curlV1 {
|
||||
return &curlV1{
|
||||
DefaultHeader: defaultHeader,
|
||||
}
|
||||
}
|
||||
|
||||
func (v1 *curlV1) getDomain(url string) string {
|
||||
strs := strings.Split(url, "//")
|
||||
if len(strs) < 2 {
|
||||
return ""
|
||||
}
|
||||
schema := v1.getSchema(url)
|
||||
paths := strings.Split(strs[1], "/")
|
||||
switch schema {
|
||||
case "unix":
|
||||
tmpstrs := []string{}
|
||||
for _, p := range paths {
|
||||
tmpstrs = append(tmpstrs, p)
|
||||
if strings.Contains(p, ".sock") {
|
||||
break
|
||||
}
|
||||
}
|
||||
return strings.Join(tmpstrs, "/")
|
||||
case "http":
|
||||
return paths[0]
|
||||
case "https":
|
||||
return paths[0]
|
||||
default:
|
||||
return paths[0]
|
||||
}
|
||||
}
|
||||
|
||||
func (v1 *curlV1) getSchema(url string) string {
|
||||
strs := strings.Split(url, ":")
|
||||
return strs[0]
|
||||
}
|
||||
|
||||
func (v1 *curlV1) getPath(url string) string {
|
||||
schema := v1.getSchema(url)
|
||||
domain := v1.getDomain(url)
|
||||
s := fmt.Sprintf("%s://%s", schema, domain)
|
||||
if len(url) <= len(s) {
|
||||
return ""
|
||||
}
|
||||
return url[len(s):]
|
||||
}
|
||||
|
||||
func (v1 *curlV1) NewClient(url string) (*http.Client, string) {
|
||||
schema := v1.getSchema(url)
|
||||
domain := v1.getDomain(url)
|
||||
path := v1.getPath(url)
|
||||
if schema == "unix" {
|
||||
defaultTimeout := 60 * time.Second
|
||||
tr := new(http.Transport)
|
||||
tr.DisableCompression = true
|
||||
tr.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
|
||||
return net.DialTimeout("unix", domain, defaultTimeout)
|
||||
}
|
||||
tr.TLSClientConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
return client, path
|
||||
}
|
||||
// 绕过github等可能因为特征码返回503问题
|
||||
// https://www.imwzk.com/posts/2021-03-14-why-i-always-get-503-with-golang/
|
||||
defaultCipherSuites := []uint16{0xc02f, 0xc030, 0xc02b, 0xc02c, 0xcca8, 0xcca9, 0xc013, 0xc009,
|
||||
0xc014, 0xc00a, 0x009c, 0x009d, 0x002f, 0x0035, 0xc012, 0x000a}
|
||||
client := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
CipherSuites: append(defaultCipherSuites[8:], defaultCipherSuites[:8]...),
|
||||
},
|
||||
},
|
||||
// 获取301重定向
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
return client, path
|
||||
}
|
||||
|
||||
func (v1 *curlV1) DoRequest(method, url string, body interface{}, header http.Header) (*http.Response, error) {
|
||||
var reqBody io.Reader
|
||||
contentType := "application/json"
|
||||
switch v := body.(type) {
|
||||
case string:
|
||||
reqBody = strings.NewReader(v)
|
||||
contentType = "text/plain"
|
||||
case []byte:
|
||||
reqBody = bytes.NewReader(v)
|
||||
case map[string]string:
|
||||
val := netURL.Values{}
|
||||
for k, v := range v {
|
||||
val.Set(k, v)
|
||||
}
|
||||
reqBody = strings.NewReader(val.Encode())
|
||||
contentType = "application/x-www-form-urlencoded"
|
||||
default:
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reqBody = bytes.NewReader(data)
|
||||
}
|
||||
if header == nil {
|
||||
header = http.Header{}
|
||||
}
|
||||
if header.Get("Content-Type") == "" {
|
||||
header.Set("Content-Type", contentType)
|
||||
}
|
||||
for k, values := range v1.DefaultHeader {
|
||||
if header.Get(k) == "" {
|
||||
for _, v := range values {
|
||||
header.Add(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
client, location := v1.NewClient(url)
|
||||
schema := v1.getSchema(url)
|
||||
req, err := http.NewRequest(method, location, reqBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.URL.Scheme = schema
|
||||
if schema == "unix" {
|
||||
req.URL.Scheme = "http"
|
||||
}
|
||||
req.URL.Host = v1.getDomain(url)
|
||||
req.Header = header
|
||||
return client.Do(req)
|
||||
}
|
||||
|
||||
func (v1 *curlV1) DoRequestReturnBytes(method, url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
resp, err := v1.DoRequest(method, url, body, header)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
res, err := ioutil.ReadAll(resp.Body)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (v1 *curlV1) Get(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return v1.DoRequestReturnBytes(http.MethodGet, url, body, header)
|
||||
}
|
||||
|
||||
func (v1 *curlV1) Put(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return v1.DoRequestReturnBytes(http.MethodPut, url, body, header)
|
||||
}
|
||||
|
||||
func (v1 *curlV1) Post(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return v1.DoRequestReturnBytes(http.MethodPost, url, body, header)
|
||||
}
|
||||
|
||||
func (v1 *curlV1) Patch(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return v1.DoRequestReturnBytes(http.MethodPatch, url, body, header)
|
||||
}
|
||||
|
||||
func (v1 *curlV1) Delete(url string, body interface{}, header http.Header) ([]byte, error) {
|
||||
return v1.DoRequestReturnBytes(http.MethodDelete, url, body, header)
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
appID = "wxc39301065b66300c"
|
||||
secret = "7fee3a1cba8c555cf6c4caec4f05844c"
|
||||
token = "qwertyuiopasdfghjkl"
|
||||
)
|
||||
|
||||
//////
|
||||
type messageEntity struct {
|
||||
Signature string `form:"signature"`
|
||||
Timestamp string `form:"timestamp"`
|
||||
Nonce string `form:"nonce"`
|
||||
EchoStr string `form:"echostr"`
|
||||
}
|
||||
|
||||
func (m *messageEntity) CheckSignature(token string) bool {
|
||||
item := []string{token, m.Timestamp, m.Nonce}
|
||||
sort.Strings(item)
|
||||
itemByte := strings.Join(item, "")
|
||||
signature := fmt.Sprintf("%x", sha1.Sum([]byte(itemByte)))
|
||||
return signature == m.Signature
|
||||
}
|
||||
|
||||
func Check(c *gin.Context) {
|
||||
me := &messageEntity{}
|
||||
me.Signature = c.Query("signature")
|
||||
me.Timestamp = c.Query("timestamp")
|
||||
me.Nonce = c.Query("nonce")
|
||||
me.EchoStr = c.Query("echostr")
|
||||
log.Println("signature:", me.Signature, "timestamp:", me.Timestamp, "noce:", me.Nonce, "echostr:", me.EchoStr)
|
||||
if !me.CheckSignature(token) {
|
||||
log.Println("token is not ok")
|
||||
c.AbortWithError(http.StatusForbidden, fmt.Errorf("token invalid"))
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
|
||||
////
|
||||
type foucsData struct {
|
||||
ToUserName string `xml:"ToUserName"`
|
||||
FromUserName string `xml:"FromUserName"`
|
||||
CreateTime int64 `xml:"CreateTime"`
|
||||
MsgType string `xml:"MsgType"`
|
||||
Event string `xml:"Event"`
|
||||
}
|
||||
|
||||
////
|
||||
type textMessage struct {
|
||||
ToUserName string `xml:"ToUserName"`
|
||||
FromUserName string `xml:"FromUserName"`
|
||||
CreateTime int64 `xml:"CreateTime"`
|
||||
MsgType string `xml:"MsgType"`
|
||||
Content string `xml:"Content"`
|
||||
}
|
||||
|
||||
func cdata(data string)string{
|
||||
return fmt.Sprintf(`<![CDATA[%s]]>`, data)
|
||||
}
|
||||
|
||||
func handleGet(c *gin.Context) {
|
||||
me := &messageEntity{}
|
||||
me.Signature = c.Query("signature")
|
||||
me.Timestamp = c.Query("timestamp")
|
||||
me.Nonce = c.Query("nonce")
|
||||
me.EchoStr = c.Query("echostr")
|
||||
log.Println("signature:", me.Signature, "timestamp:", me.Timestamp, "noce:", me.Nonce, "echostr:", me.EchoStr)
|
||||
log.Println("token is ok")
|
||||
c.String(http.StatusOK, me.EchoStr)
|
||||
}
|
||||
func handlePost(c *gin.Context) {
|
||||
data := foucsData{}
|
||||
err := c.BindXML(&data)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println("data: ", data)
|
||||
openID := c.Query("openid")
|
||||
log.Println("openid is ", openID)
|
||||
t := textMessage{
|
||||
ToUserName: cdata(data.FromUserName),
|
||||
FromUserName: cdata(data.ToUserName),
|
||||
CreateTime: time.Now().Unix(),
|
||||
MsgType: cdata("text"),
|
||||
Content: cdata("你关注了我!"),
|
||||
}
|
||||
d, err := xml.Marshal(&t)
|
||||
if err != nil {
|
||||
log.Println("marshar message faild", err)
|
||||
}
|
||||
c.String(http.StatusOK, string(d))
|
||||
}
|
||||
|
||||
func handlePut(c *gin.Context) {
|
||||
data :=foucsData{}
|
||||
err := c.BindXML(&data)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println("data: ", data)
|
||||
c.String(http.StatusOK, "success")
|
||||
}
|
||||
|
||||
func handleDelete(c *gin.Context) {
|
||||
data := foucsData{}
|
||||
err := c.BindXML(&data)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println("data: ", data)
|
||||
c.String(http.StatusOK, "success")
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
engine := gin.Default()
|
||||
engine.Use(Check)
|
||||
engine.GET("/api/wechat/signature", handleGet)
|
||||
engine.POST("/api/wechat/signature", handlePost)
|
||||
engine.PUT("/api/wechat/signature", handlePut)
|
||||
engine.DELETE("/api/wechat/signature", handleDelete)
|
||||
engine.Run("0.0.0.0:15043")
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package wechat
|
||||
|
||||
const (
|
||||
APIGetAccessToken = "https://api.weixin.qq.com/cgi-bin/token"
|
||||
APISendMessage= "https://api.weixin.qq.com/cgi-bin/message/custom/send"
|
||||
)
|
||||
|
||||
type MessageType string
|
||||
|
||||
const (
|
||||
MessageTypeText = "text"
|
||||
)
|
||||
|
||||
type TextMessage struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
ToUser string `json:"touser"`
|
||||
Type MessageType `json:"msgtype"`
|
||||
Text TextMessage `json:"text"`
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package wechat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"blog.bing89.com/go/wechat/curl"
|
||||
)
|
||||
|
||||
type Token struct {
|
||||
Token string `json:"access_token"`
|
||||
ExpiresIn int64 `json:"expires_in"`
|
||||
ExpiredAt int64 `json:"expiredAt"`
|
||||
ErrCode int `json:"errcode"`
|
||||
ErrMsg string `json:"errmsg"`
|
||||
}
|
||||
|
||||
type Wechat struct {
|
||||
AppID string
|
||||
AppSecret string
|
||||
token Token
|
||||
}
|
||||
|
||||
func NewWechat(id, secret string) *Wechat {
|
||||
w := Wechat{
|
||||
AppID: id,
|
||||
AppSecret: secret,
|
||||
}
|
||||
w.checkToken()
|
||||
return &w
|
||||
}
|
||||
|
||||
func (w *Wechat) checkToken() {
|
||||
if w.token.Token == "" || w.token.ExpiredAt < time.Now().Unix() {
|
||||
w.getToken()
|
||||
}
|
||||
}
|
||||
|
||||
func (w *Wechat) queryStr() string {
|
||||
return fmt.Sprintf("appid=%s&secret=%s", w.AppID, w.AppSecret)
|
||||
}
|
||||
|
||||
func (w *Wechat)queryToken()string {
|
||||
w.checkToken()
|
||||
return fmt.Sprintf("access_token=%s", w.token.Token)
|
||||
}
|
||||
|
||||
func (w *Wechat) getToken() error {
|
||||
url := fmt.Sprintf("%s??grant_type=client_credential&%s", APIGetAccessToken, w.queryStr())
|
||||
data, err := curl.SimpleGet(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(data, &w.token)
|
||||
if err == nil {
|
||||
w.token.ExpiredAt = w.token.ExpiresIn + time.Now().Unix()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *Wechat) SendText(to, text string) ([]byte, error) {
|
||||
msg := Message{
|
||||
ToUser: to,
|
||||
Type: MessageTypeText,
|
||||
Text: TextMessage{
|
||||
Content: text,
|
||||
},
|
||||
}
|
||||
url := fmt.Sprintf("%s?%s", APISendMessage, w.queryToken())
|
||||
data, err := curl.Post(url, &msg, nil)
|
||||
return data ,err
|
||||
}
|
Loading…
Reference in New Issue