From 6274873ecdafebcdede1bb5fdd2db883fa38577f Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 21 Jul 2024 02:13:35 +0800 Subject: [PATCH] first --- .idea/.gitignore | 8 ++ .idea/modules.xml | 8 ++ .idea/udesk.iml | 9 +++ .idea/vcs.xml | 6 ++ Dockerfile | 13 ++++ email.json | 18 +++++ exceldeal/exceldeal.go | 125 +++++++++++++++++++++++++++++++ exceldeal/notify.go | 56 ++++++++++++++ go.mod | 17 +++++ go.sum | 48 ++++++++++++ main.go | 51 +++++++++++++ standby.xlsx | Bin 0 -> 12296 bytes udesk/auth/base.go | 35 +++++++++ udesk/auth/function.go | 90 ++++++++++++++++++++++ udesk/auth/geturl.go | 17 +++++ udesk/auth/method.go | 37 +++++++++ udesk/modifystate/modifystate.go | 46 ++++++++++++ wechatwebhook.json | 3 + 18 files changed, 587 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/udesk.iml create mode 100644 .idea/vcs.xml create mode 100644 Dockerfile create mode 100644 email.json create mode 100644 exceldeal/exceldeal.go create mode 100644 exceldeal/notify.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 standby.xlsx create mode 100644 udesk/auth/base.go create mode 100644 udesk/auth/function.go create mode 100644 udesk/auth/geturl.go create mode 100644 udesk/auth/method.go create mode 100644 udesk/modifystate/modifystate.go create mode 100644 wechatwebhook.json diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..83eb8ba --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/udesk.iml b/.idea/udesk.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/udesk.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7d30d9f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM alpine:latest +ENV TZ=Asia/Shanghai +USER root + +# 合并复制指令 +COPY udeskstate /usr/local/bin/ \ +./*.json /conf/ + +# 设置执行权限 +RUN chmod +x /usr/local/bin/udeskstate + +# ENTRYPOINT 指令只有一条,已经是最优 +ENTRYPOINT ["udeskstate"] \ No newline at end of file diff --git a/email.json b/email.json new file mode 100644 index 0000000..3eb9939 --- /dev/null +++ b/email.json @@ -0,0 +1,18 @@ +{ + "吴彬": "binwu@alauda.io", + "冯浪": "langfeng@alauda.io", + "李斌": "binli@alauda.io", + "杨学成": "xcyang@alauda.io", + "罗舒文": "swluo@alauda.io", + "杨慧": "huiyang1@alauda.io", + "吴舒汀": "stwu@alauda.io", + "王硕": "shuowang@alauda.io", + "崔星林": "xlcui@alauda.io", + "孙嘉彤": "jtsun@alauda.io", + "王奥": "aowang@alauda.io", + "霍佳琦": "jqhuo@alauda.io", + "王培伦": "plwang@alauda.io", + "李晓升": "xsli@alauda.io", + "孙凯": "kaisun@alauda.io", + "王杭渝": "hywang@alauda.io" +} \ No newline at end of file diff --git a/exceldeal/exceldeal.go b/exceldeal/exceldeal.go new file mode 100644 index 0000000..6f7d935 --- /dev/null +++ b/exceldeal/exceldeal.go @@ -0,0 +1,125 @@ +package exceldeal + +import ( + "encoding/json" + "github.com/xuri/excelize/v2" + "log" + "os" + "strings" + "time" +) + +var nowMouth = time.Now().Month().String() +var nowDay = time.Now().Day() +var M = dateToChinese(nowMouth) + +func JsonDeal(file string, remindList []string, closeList []string) (r, c []string) { + emailJson, err := os.ReadFile(file) + if err != nil { + log.Printf("打开邮箱json文件失败,错误是:%v\n", err) + return + } + var email map[string]string + err = json.Unmarshal(emailJson, &email) + if err != nil { + log.Printf("json反序列化失败:%v\n", err) + return nil, nil + } + + for k, v := range email { + for _, m := range remindList { + if k == m { + r = append(r, v) + } + } + for _, m := range closeList { + if k == m { + c = append(c, v) + } + } + + } + + return r, c +} + +// 寻找当前月的值班表,并且得到应该提醒的传值和关闭的传值 + +func GetSheetName(file string) (remindList, closeList []string, err error) { + f, err := excelize.OpenFile(file) + if err != nil { + return + } + defer f.Close() + //遍历所有工作表的A2格 + sheets := f.GetSheetMap() + var sheetName string + for _, s := range sheets { + //// 读取A2单元格的值 + a2value, err := f.GetCellValue(s, "A2") + if err != nil { + log.Println(err) + return nil, nil, err + } + //检查月份是否与当前月份相等 + //如果与当前时间的月份相等则记录工作表名称 + if a2value == M { + sheetName = s + } + } + rows, _ := f.GetRows(sheetName) + for i, row := range rows { + log.Printf("按行读取excel中的值:索引:%v,行值:%v\n", i, row) + if i == nowDay { + nowRow := cleanSlice(row) + remindList = append(remindList, nowRow[2], nowRow[3]) + + } else if i == nowDay-1 { + yesterdayRow := cleanSlice(row) + closeList = append(closeList, yesterdayRow[2], yesterdayRow[3]) + } + } + + return remindList, closeList, nil + +} + +func dateToChinese(m string) (M string) { + switch m { + case "January": + M = "一月" + case "February": + M = "二月" + case "March": + M = "三月" + case "April": + M = "四月" + case "May": + M = "五月" + case "June": + M = "六月" + case "July": + M = "七月" + case "August": + M = "八月" + case "September": + M = "九月" + case "October": + M = "十月" + case "November": + M = "十一月" + case "December": + M = "十二月" + } + return M +} + +func cleanSlice(strSlice []string) (cleanedSlice []string) { + for _, s := range strSlice { + cleaned := strings.TrimSpace(s) + if cleaned != "" { + cleanedSlice = append(cleanedSlice, cleaned) + } + } + return cleanedSlice +} diff --git a/exceldeal/notify.go b/exceldeal/notify.go new file mode 100644 index 0000000..a91d277 --- /dev/null +++ b/exceldeal/notify.go @@ -0,0 +1,56 @@ +package exceldeal + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + "net/http" + "os" +) + +var webhookURL = getWebhook() + +type webHook struct { + WebHookURL string `json:"webhook"` +} + +func getWebhook() string { + wb, err := os.ReadFile("./wechatwebhook.json") + fmt.Println(string(wb)) + if err != nil { + log.Printf("打开webhook文件失败:%v\n", err) + return "" + } + var webhook webHook + err = json.Unmarshal(wb, &webhook) + if err != nil { + log.Printf("webhook config 反序列化失败: %v\n", err) + return "" + } + hook := webhook.WebHookURL + return hook +} + +func Send(repContent string) { + // 替换为你的企业微信机器人Webhook URL + + // 创建消息体 + requestBody := []byte(`{ + "msgtype": "text", + "text": { + "content": "` + repContent + `" + } + }`) + + // 发送HTTP POST请求到企业微信机器人Webhook + resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(requestBody)) + if err != nil { + log.Fatalf("发送消息失败: %v", err) + return + } + defer resp.Body.Close() + + log.Println("发送企业微信机器人成功!") + +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..12c8f17 --- /dev/null +++ b/go.mod @@ -0,0 +1,17 @@ +module udesk + +go 1.22 + +require ( + github.com/google/uuid v1.6.0 // indirect + github.com/jasonlvhit/gocron v0.0.1 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/richardlehane/mscfb v1.0.4 // indirect + github.com/richardlehane/msoleps v1.0.3 // indirect + github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect + github.com/xuri/excelize/v2 v2.8.1 // indirect + github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/text v0.16.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ce06a91 --- /dev/null +++ b/go.sum @@ -0,0 +1,48 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU= +github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= +github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= +github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= +github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY= +github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.8.1 h1:pZLMEwK8ep+CLIUWpWmvW8IWE/yxqG0I1xcN6cVMGuQ= +github.com/xuri/excelize/v2 v2.8.1/go.mod h1:oli1E4C3Pa5RXg1TBXn4ENCXDV5JUMlBluUhG7c+CEE= +github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A= +github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go new file mode 100644 index 0000000..b864b57 --- /dev/null +++ b/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "fmt" + "github.com/jasonlvhit/gocron" + "log" + "udesk/exceldeal" + "udesk/udesk/modifystate" +) + +func main() { + log.Printf("准备执行...") + // 定义任务 + //gocron.Every(5).Second().Do(job) + gocron.Every(1).Day().At("09:30").Do(job) + //gocron.Every(1).Minutes().Do(job) + // 开始定时任务 + <-gocron.Start() +} + +// 定义执行的job +func job() { + fmt.Println("任务开始") + remindList, closeList, err := exceldeal.GetSheetName("./standby.xlsx") + if err != nil { + log.Fatalf("打开值班表失败:%v", err) + } + log.Println("应在线人员名字:", remindList) + log.Println("应离线人员名字:", closeList) + remindEmail, closeEmail := exceldeal.JsonDeal("./email.json", remindList, closeList) + log.Println("应在线人员邮箱:", remindEmail) + log.Println("应离线人员邮箱:", closeEmail) + + for _, rEmail := range closeEmail { + err = modifystate.PostToModifyState(rEmail, "offline") + if err != nil { + return + } + } + + for _, rEmail := range remindEmail { + err = modifystate.PostToModifyState(rEmail, "idle") + if err != nil { + return + } + } + + message := fmt.Sprintf("今日小雀: %v,备班1: %v\n昨日小雀: %v,备班1: %v\nudesk呼叫状态已修改。", remindList[0], remindList[1], closeList[0], closeList[1]) + exceldeal.Send(message) + fmt.Println("任务结束") +} diff --git a/standby.xlsx b/standby.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..70d7257b923c758e03454e7c0745e44c951fadb2 GIT binary patch literal 12296 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 literal 0 HcmV?d00001 diff --git a/udesk/auth/base.go b/udesk/auth/base.go new file mode 100644 index 0000000..b516929 --- /dev/null +++ b/udesk/auth/base.go @@ -0,0 +1,35 @@ +package auth + +const ( + Email = "hbqi@alauda.io" + Sign_version = "v2" + Password = "Ye_qiu@123" + Auth_token_url = "https://servicecenter-alauda.udesk.cn/open_api_v1/log_in" +) + +//获取鉴权token的账号密码请求体对象 + +type RequestUdeskBody struct { + Email string `json:"email"` + Password string `json:"password"` +} + +//udesk鉴权接口返回token对象 + +type UdeskToken struct { + Code string `json:"code"` + Open_api_auth_token string `json:"open_api_auth_token"` +} + +// 定义认证对象 +type Authobj struct { + Email, + Timestamp, + Sign, + Nonce, + Sign_version string +} + +//全局声明返回体对象 + +var u = newRespUdeskBody() diff --git a/udesk/auth/function.go b/udesk/auth/function.go new file mode 100644 index 0000000..11d57e0 --- /dev/null +++ b/udesk/auth/function.go @@ -0,0 +1,90 @@ +package auth + +import ( + "bytes" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "github.com/google/uuid" + "io" + "net/http" + "strconv" + "time" +) + +//新建请求体对象 + +func newReqUdeskToken() RequestUdeskBody { + return RequestUdeskBody{ + Email: Email, + Password: Password, + } +} + +// 新建返回体对象 +func newRespUdeskBody() UdeskToken { + return UdeskToken{ + Code: "", + Open_api_auth_token: "", + } +} + +//获取Unix时间戳 + +func GetTimeStamp() string { + return strconv.FormatInt(time.Now().Unix(), 10) +} + +//获取nonce + +func GetNonce() string { + randomUUID := uuid.New() + nonce := randomUUID.String() + return nonce +} + +// sha256转换函数 +func calculateSHA256(input string) string { + // 将字符串转换为字节数组 + inputBytes := []byte(input) + + // 创建SHA-256哈希对象 + hasher := sha256.New() + + // 将字节数组写入哈希对象 + hasher.Write(inputBytes) + + // 计算哈希值并返回 + hashInBytes := hasher.Sum(nil) + hashString := hex.EncodeToString(hashInBytes) + + return hashString +} + +// 获取鉴权token对象 + +func GetUdeskAuthToken() UdeskToken { + reqBody := newReqUdeskToken() + jsonData, err := json.Marshal(reqBody) + if err != nil { + fmt.Printf("获取udesk管理员token过程中转换请求体json失败,错误是:%v", err) + } + payload := bytes.NewBufferString(string(jsonData)) + resp, err := http.Post(Auth_token_url, "application/json", payload) + if err != nil { + fmt.Printf("获取udesk管理员token过程中请求获取token接口失败,错误是:%v", err) + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + return + } + }(resp.Body) + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Printf("获取udesk管理员token过程中获取token接口响应失败,错误是:%v", err) + } + json.Unmarshal(body, &u) + return u +} diff --git a/udesk/auth/geturl.go b/udesk/auth/geturl.go new file mode 100644 index 0000000..0a7904b --- /dev/null +++ b/udesk/auth/geturl.go @@ -0,0 +1,17 @@ +package auth + +import "strings" + +//最终请求的url后缀拼接 + +func Geturlstring(url string) string { + var authobj = u.getAuthobj() //必须要同步处理timestamp和sign的关系,否则会鉴权失败,所以从同一个结构体中取值 + var builder strings.Builder + builder.WriteString(url) + builder.WriteString("email=" + authobj.Email) + builder.WriteString("×tamp=" + authobj.Timestamp) + builder.WriteString("&sign=" + authobj.Sign) + builder.WriteString("&nonce=" + authobj.Nonce) + builder.WriteString("&sign_version=" + authobj.Sign_version) + return builder.String() +} diff --git a/udesk/auth/method.go b/udesk/auth/method.go new file mode 100644 index 0000000..e26baa8 --- /dev/null +++ b/udesk/auth/method.go @@ -0,0 +1,37 @@ +package auth + +import ( + "strings" +) + +//获取token字符串 + +func (UdeskToken) getTokenString() string { + token := GetUdeskAuthToken().Open_api_auth_token + return token +} + +//计算sign并返回authobj + +func (UdeskToken) getAuthobj() Authobj { + token := u.getTokenString() + timestamp := GetTimeStamp() + nonce := GetNonce() + var builder strings.Builder + builder.WriteString(Email + "&") + builder.WriteString(token + "&") + builder.WriteString(timestamp + "&") + builder.WriteString(nonce + "&") + builder.WriteString(Sign_version) + str2sha256 := builder.String() + hashResult := calculateSHA256(str2sha256) + //fmt.Println(str2sha256) + return Authobj{ + Email: Email, + Timestamp: timestamp, + Sign: hashResult, + Nonce: nonce, + Sign_version: Sign_version, + } + +} diff --git a/udesk/modifystate/modifystate.go b/udesk/modifystate/modifystate.go new file mode 100644 index 0000000..0afc07a --- /dev/null +++ b/udesk/modifystate/modifystate.go @@ -0,0 +1,46 @@ +package modifystate + +import ( + "fmt" + "io" + "log" + "net/http" + "strings" + "udesk/udesk/auth" +) + +func PostToModifyState(email, state string) error { + // 获取 URL + url := fmt.Sprintf("https://servicecenter-alauda.udesk.cn/open_api_v1/callcenter/agent_state?email=%s&", email) + url = auth.Geturlstring(url) + + // 请求体 + bodystring := fmt.Sprintf("{\"agent_email\": \"%s\",\"agent_work_state\": \"%s\"}", email, state) + + // 创建请求 + req, err := http.NewRequest("POST", url, strings.NewReader(bodystring)) + if err != nil { + return err + } + + // 设置请求头 + req.Header.Set("Content-Type", "application/json") + + // 发送请求 + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + // 读取响应体 + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + // 打印响应体 + log.Printf("send udesk to modify state,Response is: %s", string(respBody)) + return nil +} diff --git a/wechatwebhook.json b/wechatwebhook.json new file mode 100644 index 0000000..5e58a04 --- /dev/null +++ b/wechatwebhook.json @@ -0,0 +1,3 @@ +{ + "webhook": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=9e27f428-7fb9-4771-8e48-231f59eb1ec4" +}