新增修改注册流程
This commit is contained in:
@@ -68,3 +68,25 @@ func (*Twitter) Register(ctx *gin.Context) {
|
|||||||
"data": res.Data,
|
"data": res.Data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Twitter) Register1(ctx *gin.Context) {
|
||||||
|
var res *libs.ErrorInfo
|
||||||
|
var paramsJson RegisterParams
|
||||||
|
if err := ctx.ShouldBindJSON(¶msJson); err != nil {
|
||||||
|
res = libs.ErrorCode["ParamsError"]
|
||||||
|
fmt.Println(err)
|
||||||
|
ctx.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"code": res.Code,
|
||||||
|
"msg": res.Msg,
|
||||||
|
"data": res.Data,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var TwitterService services.TwitterService
|
||||||
|
res = TwitterService.Register()
|
||||||
|
ctx.JSON(http.StatusOK, gin.H{
|
||||||
|
"code": res.Code,
|
||||||
|
"msg": res.Msg,
|
||||||
|
"data": res.Data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
9
go.mod
9
go.mod
@@ -3,6 +3,9 @@ module go-account-register
|
|||||||
go 1.24.3
|
go 1.24.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/PuerkitoBio/goquery v1.10.3
|
||||||
|
github.com/emersion/go-imap v1.2.1
|
||||||
|
github.com/emersion/go-message v0.18.2
|
||||||
github.com/fatih/structs v1.1.0
|
github.com/fatih/structs v1.1.0
|
||||||
github.com/gin-gonic/gin v1.10.1
|
github.com/gin-gonic/gin v1.10.1
|
||||||
github.com/go-resty/resty/v2 v2.16.5
|
github.com/go-resty/resty/v2 v2.16.5
|
||||||
@@ -10,6 +13,7 @@ require (
|
|||||||
github.com/go-rod/stealth v0.4.9
|
github.com/go-rod/stealth v0.4.9
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
|
github.com/pquerna/otp v1.5.0
|
||||||
github.com/redis/go-redis/v9 v9.14.0
|
github.com/redis/go-redis/v9 v9.14.0
|
||||||
golang.org/x/image v0.31.0
|
golang.org/x/image v0.31.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
@@ -19,16 +23,15 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/edwards25519 v1.1.0 // indirect
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
github.com/PuerkitoBio/goquery v1.10.3 // indirect
|
|
||||||
github.com/andybalholm/cascadia v1.3.3 // indirect
|
github.com/andybalholm/cascadia v1.3.3 // indirect
|
||||||
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||||
github.com/bytedance/sonic v1.11.6 // indirect
|
github.com/bytedance/sonic v1.11.6 // indirect
|
||||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||||
|
github.com/corpix/uarand v0.2.0 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/emersion/go-imap v1.2.1 // indirect
|
|
||||||
github.com/emersion/go-message v0.18.2 // indirect
|
|
||||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
|
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
|
|||||||
14
go.sum
14
go.sum
@@ -4,6 +4,8 @@ github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiU
|
|||||||
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
|
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
|
||||||
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
|
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
|
||||||
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
||||||
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
||||||
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||||
@@ -18,6 +20,8 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/
|
|||||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
|
github.com/corpix/uarand v0.2.0 h1:U98xXwud/AVuCpkpgfPF7J5TQgr7R5tqT8VZP5KWbzE=
|
||||||
|
github.com/corpix/uarand v0.2.0/go.mod h1:/3Z1QIqWkDIhf6XWn/08/uMHoQ8JUoTIKc2iPchBOmM=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -60,8 +64,7 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
|||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
@@ -89,6 +92,8 @@ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6
|
|||||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/pquerna/otp v1.5.0 h1:NMMR+WrmaqXU4EzdGJEE1aUUI0AMRzsp96fFFWNPwxs=
|
||||||
|
github.com/pquerna/otp v1.5.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||||
github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE=
|
github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE=
|
||||||
github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
@@ -133,7 +138,6 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
|||||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||||
@@ -152,7 +156,6 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
|||||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
|
||||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||||
@@ -174,7 +177,6 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
@@ -208,8 +210,6 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
|||||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package libs
|
|||||||
import (
|
import (
|
||||||
browserfingerprint "go-account-register/libs/browser-fingerprint"
|
browserfingerprint "go-account-register/libs/browser-fingerprint"
|
||||||
paramsTypes "go-account-register/types"
|
paramsTypes "go-account-register/types"
|
||||||
|
"go-account-register/utils"
|
||||||
"go-account-register/utils/external"
|
"go-account-register/utils/external"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@@ -10,7 +11,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/corpix/uarand"
|
||||||
"github.com/go-rod/rod"
|
"github.com/go-rod/rod"
|
||||||
|
"github.com/go-rod/rod/lib/devices"
|
||||||
"github.com/go-rod/rod/lib/launcher"
|
"github.com/go-rod/rod/lib/launcher"
|
||||||
"github.com/go-rod/rod/lib/proto"
|
"github.com/go-rod/rod/lib/proto"
|
||||||
"github.com/go-rod/stealth"
|
"github.com/go-rod/stealth"
|
||||||
@@ -139,6 +142,8 @@ func (c *Chrome) Create(accountId int, params *Fingerprint) (*rod.Browser, strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chrome) TemporaryCreate(params *Fingerprint) (*rod.Browser, string, *rod.Page) {
|
func (c *Chrome) TemporaryCreate(params *Fingerprint) (*rod.Browser, string, *rod.Page) {
|
||||||
|
userDataDir := "user-data/" + utils.RandString(5)
|
||||||
|
absPath, _ := filepath.Abs(userDataDir)
|
||||||
path, _ := launcher.LookPath() // 获取当前系统的浏览器目录
|
path, _ := launcher.LookPath() // 获取当前系统的浏览器目录
|
||||||
// 判断是否传递代理
|
// 判断是否传递代理
|
||||||
// var proxyHandle utils.ProxyHandle
|
// var proxyHandle utils.ProxyHandle
|
||||||
@@ -152,6 +157,7 @@ func (c *Chrome) TemporaryCreate(params *Fingerprint) (*rod.Browser, string, *ro
|
|||||||
Delete("use-mock-keychain"). // delete flag "--use-mock-keychain"
|
Delete("use-mock-keychain"). // delete flag "--use-mock-keychain"
|
||||||
Set("disable-blink-features", "AutomationControlled"). // 绕过自动化检测
|
Set("disable-blink-features", "AutomationControlled"). // 绕过自动化检测
|
||||||
// Set("incognito"). // 无痕模式
|
// Set("incognito"). // 无痕模式
|
||||||
|
Set("user-data-dir", absPath). // 数据持久化目录
|
||||||
Set("window-size", "1920,1480"). // 窗口尺寸
|
Set("window-size", "1920,1480"). // 窗口尺寸
|
||||||
Set("disable-infobars", "true"). // 隐藏自动化提示栏
|
Set("disable-infobars", "true"). // 隐藏自动化提示栏
|
||||||
Set("no-sandbox", "true").
|
Set("no-sandbox", "true").
|
||||||
@@ -186,6 +192,20 @@ func (c *Chrome) TemporaryCreate(params *Fingerprint) (*rod.Browser, string, *ro
|
|||||||
Set("timezone", ipInfo.Timezone).
|
Set("timezone", ipInfo.Timezone).
|
||||||
Set("geolocation", ipInfo.Lat+","+ipInfo.Lon)
|
Set("geolocation", ipInfo.Lat+","+ipInfo.Lon)
|
||||||
|
|
||||||
|
ua := uarand.GetRandom()
|
||||||
|
screen := devices.Device{
|
||||||
|
Title: "Laptop with MDPI screen",
|
||||||
|
Capabilities: []string{"touch", "mobile"},
|
||||||
|
UserAgent: ua,
|
||||||
|
AcceptLanguage: "en-US,en;q=0.9",
|
||||||
|
Screen: devices.Screen{
|
||||||
|
DevicePixelRatio: 1,
|
||||||
|
Horizontal: devices.ScreenSize{
|
||||||
|
Width: 1920,
|
||||||
|
Height: 1480,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
// if errProxy == nil {
|
// if errProxy == nil {
|
||||||
// if strings.Contains(protocol, "http") {
|
// if strings.Contains(protocol, "http") {
|
||||||
// log.Println(protocol + "://" + ip + ":" + port)
|
// log.Println(protocol + "://" + ip + ":" + port)
|
||||||
@@ -197,8 +217,9 @@ func (c *Chrome) TemporaryCreate(params *Fingerprint) (*rod.Browser, string, *ro
|
|||||||
|
|
||||||
browser := rod.New().
|
browser := rod.New().
|
||||||
ControlURL(uri).
|
ControlURL(uri).
|
||||||
MustConnect().NoDefaultDevice()
|
MustConnect().DefaultDevice(screen)
|
||||||
browser.MustIgnoreCertErrors(true)
|
browser.MustIgnoreCertErrors(true)
|
||||||
|
|
||||||
// if errProxy == nil {
|
// if errProxy == nil {
|
||||||
// if strings.Contains(protocol, "http") {
|
// if strings.Contains(protocol, "http") {
|
||||||
// log.Println(username, password)
|
// log.Println(username, password)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ func unlockWork(task *paramsTypes.Task, id int64) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
log.Printf("Goroutine panic: %v\nStack: %s", r, debug.Stack())
|
log.Printf("Goroutine panic: %v\nStack: %s", r, debug.Stack())
|
||||||
// AccountService.ChangeAccountLoginStatus(int(id), "账号下线")
|
AccountService.ChangeAccountLoginStatus(int(id), "账号下线")
|
||||||
// TwitterService.Logout(int(id))
|
// TwitterService.Logout(int(id))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -15,4 +15,5 @@ func (*Twitter) TwitterRouterInit(app *gin.Engine) {
|
|||||||
twitter.POST("/register", twitterApi.Register)
|
twitter.POST("/register", twitterApi.Register)
|
||||||
twitter.GET("/login", twitterApi.Login) // 登录账号
|
twitter.GET("/login", twitterApi.Login) // 登录账号
|
||||||
twitter.GET("/logout", twitterApi.Logout) // 退出登录
|
twitter.GET("/logout", twitterApi.Logout) // 退出登录
|
||||||
|
twitter.POST("/register1", twitterApi.Register1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,24 +35,64 @@ type BitCookieParam struct {
|
|||||||
|
|
||||||
func (*BitBrowserService) CreateBrowser(proxy *models.Proxy, cookies []*proto.NetworkCookieParam) string {
|
func (*BitBrowserService) CreateBrowser(proxy *models.Proxy, cookies []*proto.NetworkCookieParam) string {
|
||||||
fingerprint := map[string]interface{}{
|
fingerprint := map[string]interface{}{
|
||||||
"name": fmt.Sprintf(`推特注册%s`, utils.RandString(10)),
|
"name": fmt.Sprintf(`推特注册%s`, utils.RandString(10)),
|
||||||
"proxyMethod": 2,
|
"proxyMethod": 2,
|
||||||
"proxyType": "noproxy",
|
"proxyType": "noproxy",
|
||||||
"host": "",
|
"host": "",
|
||||||
"port": 0,
|
"port": 0,
|
||||||
"proxyUserName": "",
|
"proxyUserName": "",
|
||||||
"proxyPassword": "",
|
"proxyPassword": "",
|
||||||
"randomFingerprint": true,
|
"randomFingerprint": true,
|
||||||
"syncTabs": false,
|
"syncTabs": false,
|
||||||
"syncCookies": false,
|
"syncCookies": false,
|
||||||
"browserFingerPrint": map[string]interface{}{
|
"browserFingerPrint": map[string]interface{}{
|
||||||
"coreVersion": "130",
|
// "coreVersion": "130",
|
||||||
"ostype": "PC",
|
// "ostype": "PC",
|
||||||
"os": "Win32",
|
// "os": "Win32",
|
||||||
"osVersion": "11,10",
|
// "osVersion": "11,10",
|
||||||
"openWidth": 1920,
|
// "openWidth": 1920,
|
||||||
"openHeight": 1480,
|
// "openHeight": 1480,
|
||||||
"resolutionType": "0",
|
// "resolutionType": "0",
|
||||||
|
// "userAgent": "", // ua,不填则自动生成
|
||||||
|
// "isIpCreateTimeZone": true, // 基于IP生成对应的时区
|
||||||
|
// "timeZone": "", // 时区,isIpCreateTimeZone 为false时,参考附录中的时区列表
|
||||||
|
// "timeZoneOffset": 0, // isIpCreateTimeZone 为false时设置,时区偏移量
|
||||||
|
// "webRTC": "3", //webrtc 0 => 替换, 1 => 允许, 2 => 禁止, 3 => 隐私
|
||||||
|
// "ignoreHttpsErrors": false, // 忽略https证书错误,true, false
|
||||||
|
// "position": "1", //地理位置 0 => 询问, 1 => 允许, 2 => 禁止
|
||||||
|
// "isIpCreatePosition": true, // 是否基于IP生成对应的地理位置
|
||||||
|
// "lat": "", // 纬度 isIpCreatePosition 为false时设置
|
||||||
|
// "lng": "", // 经度 isIpCreatePosition 为false时设置
|
||||||
|
// "precisionData": "", //精度米 isIpCreatePosition 为false时设置
|
||||||
|
// "isIpCreateLanguage": true, // 是否基于IP生成对应国家的浏览器语言
|
||||||
|
// "languages": "", // isIpCreateLanguage 为false时设置,值参考附录
|
||||||
|
// "isIpCreateDisplayLanguage": true, // 是否基于IP生成对应国家的浏览器界面语言
|
||||||
|
// "displayLanguages": "", // isIpCreateDisplayLanguage 为false时设置,默认为空,即跟随系统,值参考附录
|
||||||
|
// "windowSizeLimit": true, // 分辨率类型为自定义,且ostype为PC时,此项有效,约束窗口最大尺寸不超过分辨率
|
||||||
|
// "devicePixelRatio": 1, // 显示缩放比例,默认1,填写时,建议 1, 1.5, 2, 2.5, 3
|
||||||
|
// "fontType": "2", // 字体生成类型 0 => 系统默认 | 2 => 随机
|
||||||
|
// "canvas": "0", //canvas 0随机|1关闭
|
||||||
|
// "webGL": "0", //webGL图像,0随机|1关闭
|
||||||
|
// "webGLMeta": "0", //webgl元数据 0自定义|1关闭
|
||||||
|
// "webGLManufacturer": "", // webGLMeta 自定义时,webGL厂商值,建议留空会自动生成
|
||||||
|
// "webGLRender": "", // webGLMeta自定义时,webGL渲染值,建议留空自动生成
|
||||||
|
// "audioContext": "0", // audioContext值,0随机|1关闭
|
||||||
|
// "mediaDevice": "0", // 媒体设备,0 随机 | 1 关闭
|
||||||
|
// "speechVoices": "0", // Speech Voices,0随机|1关闭
|
||||||
|
// "hardwareConcurrency": "4", // 硬件并发数
|
||||||
|
// "deviceMemory": "8", // 设备内存,4,8,不要传入大于8的值
|
||||||
|
// "doNotTrack": "1", // doNotTrack 1开启|0关闭
|
||||||
|
// "clientRectNoiseEnabled": true, // ClientRects true使用相匹配的值代替您真实的ClientRects | false每个浏览器使用当前电脑默认的ClientRects
|
||||||
|
// "portScanProtect": "0", // 端口扫描保护 0开启|1关闭,注意默认开启保护,组织所有本地127的ws链接,比如某些打印机之类的,如有连接本地服务需求,建议关闭,或者在 portWhiteList 中,填写对应端口,加入白名单
|
||||||
|
// "portWhiteList": "", // 端口扫描保护开启时的白名单,逗号分隔
|
||||||
|
// "deviceInfoEnabled": true, // 自定义设备信息,默认开启
|
||||||
|
// "computerName": "", // deviceInfoEnabled 为true时设置,建议留空系统自动生成即可
|
||||||
|
// "macAddr": "", // deviceInfoEnabled 为true时设置,建议留空系统自动生成即可
|
||||||
|
// "disableSslCipherSuitesFlag": false, // ssl是否禁用特性,默认不禁用,注意开启后自定义设置时,有可能会导致某些网站无法访问
|
||||||
|
// "disableSslCipherSuites": nil, // ssl 禁用特性,序列化的ssl特性值,参考附录
|
||||||
|
// "enablePlugins": false, // 是否启用插件指纹
|
||||||
|
// "plugins": "", // enablePlugins为true时,序列化的插件值,插件指纹值参考附录
|
||||||
|
// "launchArgs": "", // 启动参数,如无痕模式打开,那么设置启动参数为 "--incognito", 多个启动参数用逗号分隔,如 "--incognito,--no-sandbox"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if cookies != nil {
|
if cookies != nil {
|
||||||
@@ -228,16 +268,31 @@ func (bit *BitBrowserService) Register() *libs.ErrorInfo {
|
|||||||
// 随机生成生日
|
// 随机生成生日
|
||||||
dateParams := utils.RandDate(18, 80)
|
dateParams := utils.RandDate(18, 80)
|
||||||
dateSelects, _ := page.Timeout(5 * time.Second).Elements(`select.r-30o5oe.r-1niwhzg.r-17gur6a.r-1yadl64.r-18jsvk2.r-1loqt21.r-1inkyih.r-rjixqe.r-crgep1.r-1wzrnnt.r-1ny4l3l.r-t60dpp.r-xd6kpl.r-is05cd.r-ttdzmv`)
|
dateSelects, _ := page.Timeout(5 * time.Second).Elements(`select.r-30o5oe.r-1niwhzg.r-17gur6a.r-1yadl64.r-18jsvk2.r-1loqt21.r-1inkyih.r-rjixqe.r-crgep1.r-1wzrnnt.r-1ny4l3l.r-t60dpp.r-xd6kpl.r-is05cd.r-ttdzmv`)
|
||||||
// 月份
|
log.Println(dateSelects)
|
||||||
|
fmt.Println(strconv.Itoa(dateParams.Month))
|
||||||
|
fmt.Println(strconv.Itoa(dateParams.Day))
|
||||||
|
fmt.Println(strconv.Itoa(dateParams.Year))
|
||||||
|
/// 月份
|
||||||
dateSelects[0].WaitVisible()
|
dateSelects[0].WaitVisible()
|
||||||
dateSelects[0].MustSelect(strconv.Itoa(dateParams.Month))
|
opts, _ := dateSelects[0].Elements("option")
|
||||||
// 日期
|
for i, opt := range opts {
|
||||||
dateSelects[1].WaitVisible()
|
txt, _ := opt.Text()
|
||||||
dateSelects[1].MustSelect(strconv.Itoa(dateParams.Day))
|
val, _ := opt.Attribute("value")
|
||||||
|
log.Printf("option[%d] text=%s value=%s\n", i, txt, *val)
|
||||||
|
if i != 0 && i == dateParams.Month {
|
||||||
|
dateSelects[0].MustSelect(txt)
|
||||||
|
}
|
||||||
|
}
|
||||||
// 年份
|
// 年份
|
||||||
dateSelects[2].WaitVisible()
|
dateSelects[2].WaitVisible()
|
||||||
dateSelects[2].MustSelect(strconv.Itoa(dateParams.Year))
|
dateSelects[2].MustSelect(strconv.Itoa(dateParams.Year))
|
||||||
|
// 日期
|
||||||
|
dateSelects[1].WaitVisible()
|
||||||
|
dateSelects[1].MustSelect(strconv.Itoa(dateParams.Day))
|
||||||
|
// dateSelects[0].MustClick()
|
||||||
|
// monthOption := dateSelects[0].MustElement(fmt.Sprintf(`option[value="%d"]`, dateParams.Month))
|
||||||
|
// monthOption.MustClick()
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
// 点击下一步
|
// 点击下一步
|
||||||
ocfSignupNextLink := page.Timeout(5 * time.Second).MustElement(`button[data-testid="ocfSignupNextLink"]`)
|
ocfSignupNextLink := page.Timeout(5 * time.Second).MustElement(`button[data-testid="ocfSignupNextLink"]`)
|
||||||
ocfSignupNextLink.MustClick()
|
ocfSignupNextLink.MustClick()
|
||||||
@@ -282,7 +337,7 @@ func (bit *BitBrowserService) Register() *libs.ErrorInfo {
|
|||||||
page.MustNavigate("https://x.com").MustWaitLoad()
|
page.MustNavigate("https://x.com").MustWaitLoad()
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
// 获取cookie
|
// 获取cookie
|
||||||
cookieArr := getPageCookie(page, "https://x.com")
|
cookieArr := GetPageCookie(page, "https://x.com")
|
||||||
// 创建用户
|
// 创建用户
|
||||||
twitterAccountService := InitTwitterAccountService()
|
twitterAccountService := InitTwitterAccountService()
|
||||||
twitterAccountService.Create(&models.TwitterAccount{
|
twitterAccountService.Create(&models.TwitterAccount{
|
||||||
@@ -303,14 +358,51 @@ func (bit *BitBrowserService) Register() *libs.ErrorInfo {
|
|||||||
emailService.Update(emailInfo.Email, models.Email{
|
emailService.Update(emailInfo.Email, models.Email{
|
||||||
UseStatus: 1,
|
UseStatus: 1,
|
||||||
})
|
})
|
||||||
// 删除浏览器
|
// 设置fa2
|
||||||
bit.DeleteBrowser(browserId)
|
page.MustNavigate("https://x.com/settings/account/login_verification").MustWaitLoad()
|
||||||
return libs.ErrorCode["RegisterSuccessful"]
|
// 点击fa2按钮
|
||||||
|
inputCheckbox := page.Timeout(5 * time.Second).MustElement(`input[aria-describedby="CHECKBOX_2_LABEL"]`)
|
||||||
|
inputCheckbox.MustClick()
|
||||||
|
// 等待2秒
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
// 设置密码
|
||||||
|
inpurPassword, errPassword := page.Timeout(5 * time.Second).Element(`input[name="password"]`)
|
||||||
|
if errPassword == nil {
|
||||||
|
inpurPassword.MustInput(emailInfo.Password)
|
||||||
|
// 点击确认
|
||||||
|
faConfirm := page.Timeout(5 * time.Second).MustElement(`button[data-testid="LoginForm_Login_Button"]`)
|
||||||
|
faConfirm.MustClick()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待2秒
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
ActionListNextButton := page.Timeout(5 * time.Second).MustElement(`button[data-testid="ActionListNextButton"]`)
|
||||||
|
ActionListNextButton.MustClick()
|
||||||
|
// 点击无法扫描二维码
|
||||||
|
queryCode := page.Timeout(5 * time.Second).MustElement("div.css-175oi2r.r-1awozwy.r-w7s2jr>div.css-175oi2r.r-95jzfe>div.css-146c3p1.r-bcqeeo.r-1ttztb7.r-qvutc0.r-37j5jr.r-a023e6.r-rjixqe.r-16dba41>button.css-1jxf684.r-bcqeeo.r-qvutc0.r-poiln3.r-fdjqy7")
|
||||||
|
queryCode.MustClick()
|
||||||
|
fa2Code := page.Timeout(5 * time.Second).MustElement(`div.css-146c3p1.r-bcqeeo.r-qvutc0.r-37j5jr.r-1blvdjr.r-vrz42v.r-b88u0q.r-x572qd.r-ywje51.r-1oqcu8e.r-q4m81j.r-13qz1uu`)
|
||||||
|
fa2CodeText := fa2Code.MustText()
|
||||||
|
log.Println("当前账号的二步验证码,", fa2CodeText)
|
||||||
|
ocfShowCodeNextLink := page.Timeout(5 * time.Second).MustElement(`button[data-testid="ocfShowCodeNextLink"]`)
|
||||||
|
ocfShowCodeNextLink.MustClick()
|
||||||
|
codeText, _ := utils.GetFA2Code(fa2CodeText)
|
||||||
|
ocfEnterTextTextInput := page.Timeout(5 * time.Second).MustElement(`input[data-testid="ocfEnterTextTextInput"]`)
|
||||||
|
ocfEnterTextTextInput.MustInput(codeText)
|
||||||
|
ocfEnterTextNextButton := page.Timeout(5 * time.Second).MustElement(`button[data-testid="ocfEnterTextNextButton"]`)
|
||||||
|
ocfEnterTextNextButton.MustClick()
|
||||||
|
OCF_CallToAction_Button, errOCF := page.Timeout(5 * time.Second).Element(`button[data-testid="OCF_CallToAction_Button"]`)
|
||||||
|
if errOCF == nil {
|
||||||
|
OCF_CallToAction_Button.MustClick()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除浏览器
|
||||||
|
// bit.DeleteBrowser(browserId)
|
||||||
|
return libs.ErrorCode["RegisterSuccessful"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取指定页面的cookie列表
|
// 获取指定页面的cookie列表
|
||||||
func getPageCookie(page *rod.Page, url string) []*proto.NetworkCookieParam {
|
func GetPageCookie(page *rod.Page, url string) []*proto.NetworkCookieParam {
|
||||||
cookieArr, _ := page.Cookies([]string{url})
|
cookieArr, _ := page.Cookies([]string{url})
|
||||||
var cookies []*proto.NetworkCookieParam
|
var cookies []*proto.NetworkCookieParam
|
||||||
for _, cookie := range cookieArr {
|
for _, cookie := range cookieArr {
|
||||||
|
|||||||
@@ -5,11 +5,15 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go-account-register/libs"
|
"go-account-register/libs"
|
||||||
|
"go-account-register/models"
|
||||||
|
"go-account-register/utils"
|
||||||
"log"
|
"log"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-rod/rod"
|
"github.com/go-rod/rod"
|
||||||
"github.com/go-rod/rod/lib/cdp"
|
"github.com/go-rod/rod/lib/cdp"
|
||||||
|
"github.com/go-rod/rod/lib/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TwitterService struct{}
|
type TwitterService struct{}
|
||||||
@@ -26,8 +30,28 @@ func (*TwitterService) Login(id int) *libs.ErrorInfo {
|
|||||||
|
|
||||||
err3 := rod.Try(func() {
|
err3 := rod.Try(func() {
|
||||||
// 创建 Cookie 对象
|
// 创建 Cookie 对象
|
||||||
cookies := user.Cookies
|
// cookies := user.Cookies
|
||||||
log.Println("获取cookie", cookies)
|
// log.Println("获取cookie", cookies)
|
||||||
|
// b, _ := json.MarshalIndent(cookies, "", " ")
|
||||||
|
// log.Println(string(b))
|
||||||
|
var token string
|
||||||
|
for _, v := range user.Cookies {
|
||||||
|
if v.Name == "auth_token" {
|
||||||
|
token = v.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println("当前账号Token", token)
|
||||||
|
cookies := []*proto.NetworkCookieParam{
|
||||||
|
{
|
||||||
|
Name: "auth_token",
|
||||||
|
Value: token,
|
||||||
|
Domain: ".x.com",
|
||||||
|
Path: "/",
|
||||||
|
Expires: proto.TimeSinceEpoch(time.Now().Add(24 * time.Hour).Unix()), // 过期时间
|
||||||
|
HTTPOnly: true, // 禁止 JS 访问
|
||||||
|
Secure: true, // 仅 HTTPS 传输
|
||||||
|
},
|
||||||
|
}
|
||||||
// 全局设置
|
// 全局设置
|
||||||
browser.SetCookies(cookies)
|
browser.SetCookies(cookies)
|
||||||
page.MustNavigate("https://x.com/home").MustWaitLoad()
|
page.MustNavigate("https://x.com/home").MustWaitLoad()
|
||||||
@@ -86,3 +110,171 @@ func (*TwitterService) Login(id int) *libs.ErrorInfo {
|
|||||||
func (*TwitterService) Logout(id int) {
|
func (*TwitterService) Logout(id int) {
|
||||||
Browser.CancelBrowser(id)
|
Browser.CancelBrowser(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bit *TwitterService) Register() *libs.ErrorInfo {
|
||||||
|
// 随机获取代理
|
||||||
|
proxyService := InitProxyService()
|
||||||
|
proxy := proxyService.GetInfo()
|
||||||
|
|
||||||
|
// 获取一个邮箱
|
||||||
|
emailService := InitEmailService()
|
||||||
|
|
||||||
|
emailInfo := emailService.GetEmailOne()
|
||||||
|
log.Println("当前邮箱信息", emailInfo)
|
||||||
|
obj := Browser.GetNewBrowser(&libs.Fingerprint{})
|
||||||
|
page := obj.Page
|
||||||
|
page.MustNavigate("https://x.com/").MustWaitLoad()
|
||||||
|
// 点击创建账号
|
||||||
|
createAccountA := page.Timeout(5 * time.Second).MustElement(`a[data-testid="signupButton"]`)
|
||||||
|
createAccountA.MustClick()
|
||||||
|
|
||||||
|
// // 点击创建账号
|
||||||
|
// createAccount := page.Timeout(5 * time.Second).MustElement(`button.css-175oi2r.r-sdzlij.r-1phboty.r-rs99b7.r-lrvibr.r-ywje51.r-184id4b.r-13qz1uu.r-2yi16.r-1qi8awa.r-3pj75a.r-1loqt21.r-o7ynqc.r-6416eg.r-1ny4l3l`)
|
||||||
|
// createAccount.MustClick()
|
||||||
|
// 判断当前是否是邮箱注册
|
||||||
|
// _, err := page.Element(`input[name="email"]`)
|
||||||
|
// if err != nil {
|
||||||
|
switchButton := page.Timeout(5 * time.Second).MustElement(`button.css-146c3p1.r-bcqeeo.r-qvutc0.r-37j5jr.r-1ff274t.r-a023e6.r-rjixqe.r-16dba41`)
|
||||||
|
switchButton.MustClick()
|
||||||
|
// }
|
||||||
|
// 获取邮箱输入框
|
||||||
|
inputEmail := page.Timeout(5 * time.Second).MustElement(`input[name="email"]`)
|
||||||
|
inputEmail.MustFocus()
|
||||||
|
inputEmail.MustInput(emailInfo.Email)
|
||||||
|
// 获取名称输入框
|
||||||
|
inputName := page.Timeout(5 * time.Second).MustElement(`input[name="name"]`)
|
||||||
|
inputName.MustFocus()
|
||||||
|
nameStr := emailInfo.Name
|
||||||
|
if emailInfo.Name == "" {
|
||||||
|
nameStr = utils.RandString(12)
|
||||||
|
}
|
||||||
|
inputName.MustInput(nameStr)
|
||||||
|
// 随机生成生日
|
||||||
|
dateParams := utils.RandDate(18, 80)
|
||||||
|
dateSelects, _ := page.Timeout(5 * time.Second).Elements(`select.r-30o5oe.r-1niwhzg.r-17gur6a.r-1yadl64.r-18jsvk2.r-1loqt21.r-1inkyih.r-rjixqe.r-crgep1.r-1wzrnnt.r-1ny4l3l.r-t60dpp.r-xd6kpl.r-is05cd.r-ttdzmv`)
|
||||||
|
log.Println(dateSelects)
|
||||||
|
fmt.Println(strconv.Itoa(dateParams.Month))
|
||||||
|
fmt.Println(strconv.Itoa(dateParams.Day))
|
||||||
|
fmt.Println(strconv.Itoa(dateParams.Year))
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
// 月份
|
||||||
|
dateSelects[0].WaitVisible()
|
||||||
|
opts, _ := dateSelects[0].Elements("option")
|
||||||
|
for i, opt := range opts {
|
||||||
|
txt, _ := opt.Text()
|
||||||
|
val, _ := opt.Attribute("value")
|
||||||
|
log.Printf("option[%d] text=%s value=%s\n", i, txt, *val)
|
||||||
|
if i != 0 && i == dateParams.Month {
|
||||||
|
dateSelects[0].MustSelect(txt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 年份
|
||||||
|
dateSelects[2].WaitVisible()
|
||||||
|
dateSelects[2].MustSelect(strconv.Itoa(dateParams.Year))
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
// 日期
|
||||||
|
dateSelects[1].WaitVisible()
|
||||||
|
dateSelects[1].MustSelect(strconv.Itoa(dateParams.Day))
|
||||||
|
// dateSelects[0].MustClick()
|
||||||
|
// monthOption := dateSelects[0].MustElement(fmt.Sprintf(`option[value="%d"]`, dateParams.Month))
|
||||||
|
// monthOption.MustClick()
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
// 点击下一步
|
||||||
|
ocfSignupNextLink := page.Timeout(5 * time.Second).MustElement(`button[data-testid="ocfSignupNextLink"]`)
|
||||||
|
ocfSignupNextLink.MustClick()
|
||||||
|
// 判断是否需要验证码
|
||||||
|
time.Sleep(4 * time.Second)
|
||||||
|
_, err1 := page.Timeout(5 * time.Second).Element(`input[name="verfication_code"]`)
|
||||||
|
if err1 != nil {
|
||||||
|
// res := getApiResponse(page, "")
|
||||||
|
}
|
||||||
|
//TODO 对接获取邮箱信息接口
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
codeValue := LoopGetEmailCode("pop.dragonsmail.com:993", emailInfo.Email, emailInfo.Password)
|
||||||
|
if codeValue == "0" {
|
||||||
|
emailService.Update(emailInfo.Email, models.Email{
|
||||||
|
Status: 0,
|
||||||
|
})
|
||||||
|
return libs.ErrorCode["MailboxUnavailable"]
|
||||||
|
}
|
||||||
|
// 获取邮箱验证码
|
||||||
|
log.Println("获取当前验证码", codeValue)
|
||||||
|
codeInput1, _ := page.Timeout(5 * time.Second).Element(`input[name="verfication_code"]`)
|
||||||
|
codeInput1.MustInput(codeValue)
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
// 点击下一步
|
||||||
|
codeNextButton := page.Timeout(5 * time.Second).MustElement(`button.css-175oi2r.r-sdzlij.r-1phboty.r-rs99b7.r-lrvibr.r-19yznuf.r-64el8z.r-1fkl15p.r-1loqt21.r-o7ynqc.r-6416eg.r-1ny4l3l`)
|
||||||
|
codeNextButton.MustClick()
|
||||||
|
// // 点击验证按钮
|
||||||
|
// verifyButton := page.Timeout(5 * time.Second).MustElement(`button[data-theme="home.verifyButton"]`)
|
||||||
|
// verifyButton.MustClick()
|
||||||
|
// 输入密码
|
||||||
|
passwordInput, err2 := page.Timeout(5 * time.Second).Element(`input[name="password"]`)
|
||||||
|
if err2 != nil {
|
||||||
|
// res := getApiResponse(page, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordInput.MustInput(emailInfo.Password)
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
// 点击下一步
|
||||||
|
loginButton := page.Timeout(5 * time.Second).MustElement(`button[data-testid="LoginForm_Login_Button"]`)
|
||||||
|
loginButton.MustClick()
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
page.MustNavigate("https://x.com").MustWaitLoad()
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
// 获取cookie
|
||||||
|
cookieArr := GetPageCookie(page, "https://x.com")
|
||||||
|
// 创建用户
|
||||||
|
twitterAccountService := InitTwitterAccountService()
|
||||||
|
twitterAccountService.Create(&models.TwitterAccount{
|
||||||
|
Name: nameStr,
|
||||||
|
Email: emailInfo.Email,
|
||||||
|
Password: emailInfo.Password,
|
||||||
|
Birthday: strconv.Itoa(dateParams.Year) + "-" + strconv.Itoa(dateParams.Month) + "-" + strconv.Itoa(dateParams.Day),
|
||||||
|
Cookies: cookieArr,
|
||||||
|
Status: "注册成功",
|
||||||
|
LoginStatus: "登录成功",
|
||||||
|
Proxy: func() string {
|
||||||
|
if proxy != nil && proxy.Type != "" {
|
||||||
|
return proxy.Type + "://" + proxy.Proxy
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}(),
|
||||||
|
})
|
||||||
|
emailService.Update(emailInfo.Email, models.Email{
|
||||||
|
UseStatus: 1,
|
||||||
|
})
|
||||||
|
// 设置fa2
|
||||||
|
page.MustNavigate("https://x.com/settings/account/login_verification").MustWaitLoad()
|
||||||
|
// 点击fa2按钮
|
||||||
|
inputCheckbox := page.Timeout(5 * time.Second).MustElement(`input[aria-describedby="CHECKBOX_2_LABEL"]`)
|
||||||
|
inputCheckbox.MustClick()
|
||||||
|
// 等待2秒
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
// 设置密码
|
||||||
|
inpurPassword := page.Timeout(5 * time.Second).MustElement(`input[name="password"]`)
|
||||||
|
inpurPassword.MustInput(emailInfo.Password)
|
||||||
|
// 点击确认
|
||||||
|
faConfirm := page.Timeout(5 * time.Second).MustElement(`button[data-testid="LoginForm_Login_Button"]`)
|
||||||
|
faConfirm.MustClick()
|
||||||
|
// 等待2秒
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
ActionListNextButton := page.Timeout(5 * time.Second).MustElement(`button[data-testid="ActionListNextButton"]`)
|
||||||
|
ActionListNextButton.MustClick()
|
||||||
|
// 点击无法扫描二维码
|
||||||
|
queryCode := page.Timeout(5 * time.Second).MustElement("div.css-175oi2r.r-1awozwy.r-w7s2jr>div.css-175oi2r.r-95jzfe>div.css-146c3p1.r-bcqeeo.r-1ttztb7.r-qvutc0.r-37j5jr.r-a023e6.r-rjixqe.r-16dba41>button.css-1jxf684.r-bcqeeo.r-qvutc0.r-poiln3.r-fdjqy7")
|
||||||
|
queryCode.MustClick()
|
||||||
|
fa2Code := page.Timeout(5 * time.Second).MustElement(`div.css-146c3p1.r-bcqeeo.r-qvutc0.r-37j5jr.r-1blvdjr.r-vrz42v.r-b88u0q.r-x572qd.r-ywje51.r-1oqcu8e.r-q4m81j.r-13qz1uu`)
|
||||||
|
fa2CodeText := fa2Code.MustText()
|
||||||
|
log.Println("当前账号的二步验证码,", fa2CodeText)
|
||||||
|
ocfShowCodeNextLink := page.Timeout(5 * time.Second).MustElement(`button[data-testid="ocfShowCodeNextLink"]`)
|
||||||
|
ocfShowCodeNextLink.MustClick()
|
||||||
|
codeText, _ := utils.GetFA2Code(fa2CodeText)
|
||||||
|
ocfEnterTextTextInput := page.Timeout(5 * time.Second).MustElement(`input[data-testid="ocfEnterTextTextInput"]`)
|
||||||
|
ocfEnterTextTextInput.MustInput(codeText)
|
||||||
|
ocfEnterTextNextButton := page.Timeout(5 * time.Second).MustElement(`button[data-testid="ocfEnterTextNextButton"]`)
|
||||||
|
ocfEnterTextNextButton.MustClick()
|
||||||
|
// 删除浏览器
|
||||||
|
return libs.ErrorCode["RegisterSuccessful"]
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pquerna/otp/totp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RandDateParams struct {
|
type RandDateParams struct {
|
||||||
@@ -73,3 +76,18 @@ func RandDate(minAge, maxAge int) RandDateParams {
|
|||||||
Day: day,
|
Day: day,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取FA2码
|
||||||
|
func GetFA2Code(secret string) (string, error) {
|
||||||
|
// 去除多余的字符串
|
||||||
|
replacer := strings.NewReplacer(
|
||||||
|
"-", "",
|
||||||
|
" ", "",
|
||||||
|
)
|
||||||
|
result := replacer.Replace(secret)
|
||||||
|
code, err := totp.GenerateCode(result, time.Now())
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return code, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user