修改账号注册方法,以及邮箱协议对接
This commit is contained in:
244
utils/bit_browser_request.go
Normal file
244
utils/bit_browser_request.go
Normal file
@@ -0,0 +1,244 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"go-account-register/config"
|
||||
"log"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
type BitBrowserRequest struct {
|
||||
client *resty.Client
|
||||
}
|
||||
|
||||
func NewBitBrowserRequest() *BitBrowserRequest {
|
||||
appConfig, _ := config.LoadConfig()
|
||||
client := resty.New()
|
||||
client.SetBaseURL(appConfig.BitBrowser.ApiUrl)
|
||||
|
||||
// 响应拦截器 (类似 axios 拦截器)
|
||||
client.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error {
|
||||
if resp.StatusCode() != 200 {
|
||||
log.Println("请求失败,检查网络")
|
||||
return errors.New("request failed")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return &BitBrowserRequest{client: client}
|
||||
}
|
||||
|
||||
// Request 发送通用请求
|
||||
func (h *BitBrowserRequest) Request(method, url string, data interface{}) (*resty.Response, error) {
|
||||
resp, err := h.client.R().
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetBody(data).
|
||||
Execute(method, url)
|
||||
|
||||
if err != nil {
|
||||
log.Println("请求失败了:", err)
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 打开浏览器并返回wspoint
|
||||
* @returns {Promise<Object>} Promise<any>
|
||||
* @param {Object} data
|
||||
* @param {String} data.id 窗口id
|
||||
* @param {Array} data.args 启动附加参数,数组类型,比如 ["--headless"]
|
||||
* @param {Boolean} data.loadExtensions 是否加载扩展
|
||||
* @param {Boolean} data.extractIp 是否尝试提取IP
|
||||
*/
|
||||
func (h *BitBrowserRequest) OpenBrowser(data map[string]interface{}) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/open", data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 关闭浏览器
|
||||
* @param {String} id
|
||||
* @returns {Promise}
|
||||
*/
|
||||
func (h *BitBrowserRequest) CloseBrowser(id string) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/close", map[string]interface{}{"id": id})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 创建浏览器
|
||||
* @param {Object} data
|
||||
* @returns {Promise}
|
||||
*/
|
||||
func (h *BitBrowserRequest) CreateBrowser(data map[string]interface{}) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/update", data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 修改browser信息,只修改传入的配置
|
||||
* @param {Object} data 参考创建配置项
|
||||
* @returns {Promise}
|
||||
*/
|
||||
func (h *BitBrowserRequest) UpdatePartial(data map[string]interface{}) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/update/partial", data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 批量删除浏览器
|
||||
* @param {array} ids
|
||||
*/
|
||||
func (h *BitBrowserRequest) DeleteBatchBrowser(ids []string) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/delete/ids", map[string]interface{}{"ids": ids})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 删除浏览器
|
||||
* @param {String} id
|
||||
* @returns {Promise}
|
||||
*/
|
||||
func (h *BitBrowserRequest) DeleteBrowser(id string) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/delete", map[string]interface{}{"id": id})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取浏览器详情
|
||||
* @param {String} id
|
||||
* @returns {Promise}
|
||||
* */
|
||||
func (h *BitBrowserRequest) GetBrowserDetail(id string) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/detail", map[string]interface{}{"id": id})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取浏览器列表
|
||||
* @param {Object} data
|
||||
* @param {Number} data.page // 必传
|
||||
* @param {Number} data.pageSize // 必传
|
||||
* @param {String} data.groupId // 分组ID,非必传
|
||||
* @param {String} data.name // 窗口名称,用于模糊查询,非必传
|
||||
* @param {String} data.sortProperties // 排序参数,默认序号,seq,非必传
|
||||
* @param {String} data.sortDirection // 排序顺序参数,默认desc,可传asc,非必传
|
||||
* @returns {Promise}
|
||||
* */
|
||||
func (h *BitBrowserRequest) GetBrowserList(data map[string]interface{}) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/list", data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取浏览器列表(简洁)
|
||||
*/
|
||||
func (h *BitBrowserRequest) GetBrowserConciseList(data map[string]interface{}) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/list/concise", data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 分组list
|
||||
* @param {Number} page 从0开始
|
||||
* @param {Number} pageSize 例如10
|
||||
* @returns {Promise}
|
||||
* */
|
||||
func (h *BitBrowserRequest) GetGroupList(page, pageSize int) (*resty.Response, error) {
|
||||
return h.Request("POST", "/group/list", map[string]interface{}{"page": page, "pageSize": pageSize})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 添加分组
|
||||
* @param {String} groupName
|
||||
* @param {Number} sortNum
|
||||
* @returns {Promise}
|
||||
* */
|
||||
func (h *BitBrowserRequest) AddGroup(groupName string, sortNum int) (*resty.Response, error) {
|
||||
return h.Request("POST", "/group/add", map[string]interface{}{"groupName": groupName, "sortNum": sortNum})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 修改分组
|
||||
* @param {String} id
|
||||
* @param {String} groupName
|
||||
* @param {Number} sortNum
|
||||
* @returns {Promise}
|
||||
* */
|
||||
func (h *BitBrowserRequest) EditGroup(id, groupName string, sortNum int) (*resty.Response, error) {
|
||||
return h.Request("POST", "/group/edit", map[string]interface{}{"id": id, "groupName": groupName, "sortNum": sortNum})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 删除分组
|
||||
* @param {String} id
|
||||
* @returns {Promise}
|
||||
* */
|
||||
func (h *BitBrowserRequest) DeleteGroup(id string) (*resty.Response, error) {
|
||||
return h.Request("POST", "/group/delete", map[string]interface{}{"id": id})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 分组详情
|
||||
* @param {String} id
|
||||
* */
|
||||
func (h *BitBrowserRequest) GetGroupDetail(id string) (*resty.Response, error) {
|
||||
return h.Request("POST", "/group/detail", map[string]interface{}{"id": id})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取指定窗口的pids
|
||||
* @param {Array} ids
|
||||
* @returns
|
||||
*/
|
||||
func (h *BitBrowserRequest) GetPids(ids []string) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/pids", map[string]interface{}{"ids": ids})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取活着窗口的pids
|
||||
* @param {Array} ids
|
||||
* @returns
|
||||
*/
|
||||
func (h *BitBrowserRequest) GetAlivePids(ids []string) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/pids/alive", map[string]interface{}{"ids": ids})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取所有活着窗口的pids
|
||||
* @returns
|
||||
*/
|
||||
func (h *BitBrowserRequest) GetAliveBrowsersPids() (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/pids/all", nil)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 批量修改窗口备注
|
||||
* @param {String} remark
|
||||
* @param {Array} browserIds
|
||||
* @returns
|
||||
*/
|
||||
func (h *BitBrowserRequest) UpdateBrowserRemark(remark string, browserIds []string) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/remark/update", map[string]interface{}{"remark": remark, "browserIds": browserIds})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 批量修改窗口分组
|
||||
* @param {Object} data
|
||||
* @param {Number} data.groupId
|
||||
* @param {Array} data.browserIds
|
||||
*/
|
||||
func (h *BitBrowserRequest) BatchUpdateBrowserGroup(data map[string]interface{}) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/group/update", data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 通过序号批量关闭浏览器
|
||||
*
|
||||
*/
|
||||
func (h *BitBrowserRequest) CloseBrowsersBySeqs(seqs []int) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/close/byseqs", map[string]interface{}{"seqs": seqs})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 批量修改代理
|
||||
* @param {Object} data
|
||||
* @param {Number} data.proxyMethod //代理类型,2自定义代理,3提取IP
|
||||
* @param {String} data.proxyType // 自定义代理类型
|
||||
*/
|
||||
func (h *BitBrowserRequest) BatchUpdateProxy(data map[string]interface{}) (*resty.Response, error) {
|
||||
return h.Request("POST", "/browser/proxy/update", data)
|
||||
}
|
||||
125
utils/email_imap.go
Normal file
125
utils/email_imap.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/emersion/go-imap"
|
||||
"github.com/emersion/go-imap/client"
|
||||
"github.com/emersion/go-message/mail"
|
||||
)
|
||||
|
||||
type EmailImap struct {
|
||||
}
|
||||
|
||||
// 获取最新一封邮件的正文内容
|
||||
func (*EmailImap) GetLatestMailContent(server, username, password string) (string, error) {
|
||||
// 1. 连接 IMAP 服务器 (SSL/TLS, 端口 993)
|
||||
c, err := client.DialTLS(server, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("连接失败: %v", err)
|
||||
}
|
||||
defer c.Logout()
|
||||
|
||||
// 2. 登录
|
||||
if err := c.Login(username, password); err != nil {
|
||||
return "", fmt.Errorf("登录失败: %v", err)
|
||||
}
|
||||
|
||||
// 3. 选择收件箱
|
||||
mbox, err := c.Select("INBOX", false)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("选择收件箱失败: %v", err)
|
||||
}
|
||||
if mbox.Messages == 0 {
|
||||
return "", nil // 没有邮件
|
||||
}
|
||||
|
||||
// 4. 获取最新一封邮件
|
||||
seqset := new(imap.SeqSet)
|
||||
seqset.AddNum(mbox.Messages)
|
||||
|
||||
section := &imap.BodySectionName{}
|
||||
messages := make(chan *imap.Message, 1)
|
||||
go func() {
|
||||
if err := c.Fetch(seqset, []imap.FetchItem{section.FetchItem()}, messages); err != nil {
|
||||
log.Println("获取邮件失败:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
msg := <-messages
|
||||
if msg == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
r := msg.GetBody(section)
|
||||
if r == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// 5. 解析邮件正文
|
||||
mr, err := mail.CreateReader(r)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("解析邮件失败: %v", err)
|
||||
}
|
||||
|
||||
var content string
|
||||
for {
|
||||
p, err := mr.NextPart()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("读取邮件失败: %v", err)
|
||||
}
|
||||
|
||||
switch p.Header.(type) {
|
||||
case *mail.InlineHeader:
|
||||
b, _ := io.ReadAll(p.Body)
|
||||
content = strings.TrimSpace(string(b))
|
||||
// 只取第一个正文即可
|
||||
return content, nil
|
||||
}
|
||||
}
|
||||
|
||||
return content, nil
|
||||
}
|
||||
|
||||
func (e *EmailImap) GetMailCode(server, username, password string) string {
|
||||
res, err := e.GetLatestMailContent(server, username, password)
|
||||
if err != nil {
|
||||
return "0"
|
||||
}
|
||||
|
||||
htmlStr := res
|
||||
fmt.Println(htmlStr)
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlStr))
|
||||
if err != nil {
|
||||
return "0"
|
||||
}
|
||||
|
||||
code := ""
|
||||
doc.Find("td.h1.black").Each(func(i int, s *goquery.Selection) {
|
||||
if code == "" {
|
||||
code = strings.TrimSpace(s.Text())
|
||||
}
|
||||
})
|
||||
|
||||
if code == "" {
|
||||
return "0"
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
func test() {
|
||||
var emailImap EmailImap
|
||||
content, err := emailImap.GetLatestMailContent("pop.dragonsmail.com:993", "CamilleMathews1u8K@dragonsmail.com", "vDgADn`zga.")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("最新邮件内容:\n", content)
|
||||
}
|
||||
68
utils/firstmail.go
Normal file
68
utils/firstmail.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go-account-register/config"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
type Firstmail struct {
|
||||
}
|
||||
|
||||
type MailResponse struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (f *Firstmail) GetFirstmailMail(username, password string) (*MailResponse, error) {
|
||||
client := resty.New()
|
||||
appConfig, _ := config.LoadConfig()
|
||||
url := fmt.Sprintf("%s?username=%s&password=%s",
|
||||
appConfig.Firstmail.ApiUrl, username, password)
|
||||
|
||||
resp, err := client.R().
|
||||
SetHeader("accept", "application/json").
|
||||
SetHeader("X-API-KEY", appConfig.Firstmail.ApiToken).
|
||||
Get(url)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var data MailResponse
|
||||
if err := json.Unmarshal(resp.Body(), &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &data, nil
|
||||
}
|
||||
|
||||
func (f *Firstmail) GetMailCode(username, password string) string {
|
||||
res, err := f.GetFirstmailMail(username, password)
|
||||
if err != nil {
|
||||
return "0"
|
||||
}
|
||||
|
||||
htmlStr := res.Message
|
||||
fmt.Println(htmlStr)
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlStr))
|
||||
if err != nil {
|
||||
return "0"
|
||||
}
|
||||
|
||||
code := ""
|
||||
doc.Find("td.h1.black").Each(func(i int, s *goquery.Selection) {
|
||||
if code == "" {
|
||||
code = strings.TrimSpace(s.Text())
|
||||
}
|
||||
})
|
||||
|
||||
if code == "" {
|
||||
return "0"
|
||||
}
|
||||
return code
|
||||
}
|
||||
Reference in New Issue
Block a user