新增修改注册流程

This commit is contained in:
zyj
2025-09-30 11:19:39 +08:00
parent 22e21f6eb8
commit dbf8b5bcca
9 changed files with 391 additions and 42 deletions

View File

@@ -68,3 +68,25 @@ func (*Twitter) Register(ctx *gin.Context) {
"data": res.Data,
})
}
func (*Twitter) Register1(ctx *gin.Context) {
var res *libs.ErrorInfo
var paramsJson RegisterParams
if err := ctx.ShouldBindJSON(&paramsJson); 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
View File

@@ -3,6 +3,9 @@ module go-account-register
go 1.24.3
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/gin-gonic/gin v1.10.1
github.com/go-resty/resty/v2 v2.16.5
@@ -10,6 +13,7 @@ require (
github.com/go-rod/stealth v0.4.9
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/google/uuid v1.6.0
github.com/pquerna/otp v1.5.0
github.com/redis/go-redis/v9 v9.14.0
golang.org/x/image v0.31.0
gopkg.in/yaml.v3 v3.0.1
@@ -19,16 +23,15 @@ require (
require (
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/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudwego/base64x v0.1.4 // 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/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/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect

14
go.sum
View File

@@ -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/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
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/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
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/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
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/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/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
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/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
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/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
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.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.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
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/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.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
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.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
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.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.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
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/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.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-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/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

View File

@@ -3,6 +3,7 @@ package libs
import (
browserfingerprint "go-account-register/libs/browser-fingerprint"
paramsTypes "go-account-register/types"
"go-account-register/utils"
"go-account-register/utils/external"
"log"
"os"
@@ -10,7 +11,9 @@ import (
"strconv"
"strings"
"github.com/corpix/uarand"
"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/proto"
"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) {
userDataDir := "user-data/" + utils.RandString(5)
absPath, _ := filepath.Abs(userDataDir)
path, _ := launcher.LookPath() // 获取当前系统的浏览器目录
// 判断是否传递代理
// 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"
Set("disable-blink-features", "AutomationControlled"). // 绕过自动化检测
// Set("incognito"). // 无痕模式
Set("user-data-dir", absPath). // 数据持久化目录
Set("window-size", "1920,1480"). // 窗口尺寸
Set("disable-infobars", "true"). // 隐藏自动化提示栏
Set("no-sandbox", "true").
@@ -186,6 +192,20 @@ func (c *Chrome) TemporaryCreate(params *Fingerprint) (*rod.Browser, string, *ro
Set("timezone", ipInfo.Timezone).
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 strings.Contains(protocol, "http") {
// log.Println(protocol + "://" + ip + ":" + port)
@@ -197,8 +217,9 @@ func (c *Chrome) TemporaryCreate(params *Fingerprint) (*rod.Browser, string, *ro
browser := rod.New().
ControlURL(uri).
MustConnect().NoDefaultDevice()
MustConnect().DefaultDevice(screen)
browser.MustIgnoreCertErrors(true)
// if errProxy == nil {
// if strings.Contains(protocol, "http") {
// log.Println(username, password)

View File

@@ -78,7 +78,7 @@ func unlockWork(task *paramsTypes.Task, id int64) {
defer func() {
if r := recover(); r != nil {
log.Printf("Goroutine panic: %v\nStack: %s", r, debug.Stack())
// AccountService.ChangeAccountLoginStatus(int(id), "账号下线")
AccountService.ChangeAccountLoginStatus(int(id), "账号下线")
// TwitterService.Logout(int(id))
}
}()

View File

@@ -15,4 +15,5 @@ func (*Twitter) TwitterRouterInit(app *gin.Engine) {
twitter.POST("/register", twitterApi.Register)
twitter.GET("/login", twitterApi.Login) // 登录账号
twitter.GET("/logout", twitterApi.Logout) // 退出登录
twitter.POST("/register1", twitterApi.Register1)
}

View File

@@ -46,13 +46,53 @@ func (*BitBrowserService) CreateBrowser(proxy *models.Proxy, cookies []*proto.Ne
"syncTabs": false,
"syncCookies": false,
"browserFingerPrint": map[string]interface{}{
"coreVersion": "130",
"ostype": "PC",
"os": "Win32",
"osVersion": "11,10",
"openWidth": 1920,
"openHeight": 1480,
"resolutionType": "0",
// "coreVersion": "130",
// "ostype": "PC",
// "os": "Win32",
// "osVersion": "11,10",
// "openWidth": 1920,
// "openHeight": 1480,
// "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 Voices0随机1关闭
// "hardwareConcurrency": "4", // 硬件并发数
// "deviceMemory": "8", // 设备内存48不要传入大于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 {
@@ -228,16 +268,31 @@ func (bit *BitBrowserService) Register() *libs.ErrorInfo {
// 随机生成生日
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))
/// 月份
dateSelects[0].WaitVisible()
dateSelects[0].MustSelect(strconv.Itoa(dateParams.Month))
// 日期
dateSelects[1].WaitVisible()
dateSelects[1].MustSelect(strconv.Itoa(dateParams.Day))
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))
// 日期
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()
@@ -282,7 +337,7 @@ func (bit *BitBrowserService) Register() *libs.ErrorInfo {
page.MustNavigate("https://x.com").MustWaitLoad()
time.Sleep(10 * time.Second)
// 获取cookie
cookieArr := getPageCookie(page, "https://x.com")
cookieArr := GetPageCookie(page, "https://x.com")
// 创建用户
twitterAccountService := InitTwitterAccountService()
twitterAccountService.Create(&models.TwitterAccount{
@@ -303,14 +358,51 @@ func (bit *BitBrowserService) Register() *libs.ErrorInfo {
emailService.Update(emailInfo.Email, models.Email{
UseStatus: 1,
})
// 删除浏览器
bit.DeleteBrowser(browserId)
return libs.ErrorCode["RegisterSuccessful"]
// 设置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, 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列表
func getPageCookie(page *rod.Page, url string) []*proto.NetworkCookieParam {
func GetPageCookie(page *rod.Page, url string) []*proto.NetworkCookieParam {
cookieArr, _ := page.Cookies([]string{url})
var cookies []*proto.NetworkCookieParam
for _, cookie := range cookieArr {

View File

@@ -5,11 +5,15 @@ import (
"errors"
"fmt"
"go-account-register/libs"
"go-account-register/models"
"go-account-register/utils"
"log"
"strconv"
"time"
"github.com/go-rod/rod"
"github.com/go-rod/rod/lib/cdp"
"github.com/go-rod/rod/lib/proto"
)
type TwitterService struct{}
@@ -26,8 +30,28 @@ func (*TwitterService) Login(id int) *libs.ErrorInfo {
err3 := rod.Try(func() {
// 创建 Cookie 对象
cookies := user.Cookies
log.Println("获取cookie", cookies)
// cookies := user.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)
page.MustNavigate("https://x.com/home").MustWaitLoad()
@@ -86,3 +110,171 @@ func (*TwitterService) Login(id int) *libs.ErrorInfo {
func (*TwitterService) Logout(id int) {
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"]
}

View File

@@ -2,7 +2,10 @@ package utils
import (
"math/rand"
"strings"
"time"
"github.com/pquerna/otp/totp"
)
type RandDateParams struct {
@@ -73,3 +76,18 @@ func RandDate(minAge, maxAge int) RandDateParams {
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
}