Commit eca29c2a by 陶腾飞

v1.8.0 合并企业微信推送,转型HTTP服务器,增加活动检测,用户备份升级

parent 5b2c94d2
......@@ -8,39 +8,64 @@
### 1. Users.exe - 域用户使用的程序
UI:在DC上以用户权限且任务栏托盘的方式运行
**启动说明:**由组策略的文件替换功能(在开机时),从文件共享中复制到C:\Windows\System32下,并运行。
**具体功能:**
UI:
在域计算机上以用户权限且任务栏托盘的方式运行
启动说明:
由组策略的文件替换功能(在开机时),从文件共享中复制到C:\Windows\System32下,并运行。
具体功能:
1. 电源选项
2. 软件安装
3. 微盘同步
4. 文件共享
3. 实用工具
3. 文件共享
### 2. Domain Computer Daemon - 域计算机使用的Daemon.exe
### 2. 主控使用的Daemon.exe
**运行方式:**由组策略在计算机启动时运行命令runad.bat daemon来进行循环启动DCD。(管理员权限、无窗口 )
**主要功能:**运行由DCU和ADU提交的程序和与接受处理发送消息(通常处理需要管理员权限的消息)
运行方式:
`go run .\daemon.go`
### 3. ADServer Daemon- 主控使用的Daemon.exe
主要功能:
接收域和企业微信的消息并处理与反馈
**运行方式:**前后台任意
**主要作用:**根据Users.exe的参数设定响应来自DC端的请求
**其他:**使用注册表(HKLM\Software\ADControl)作为数据库的存储
### 3. adct.exe 域控制工具
### 4. adct.exe 域控制工具
作用:
通过adct来控制域用户、域计算机来完成部分功能
**作用:**通过adct来控制域用户、域计算机来完成部分功能
**具体功能:**
1. 定时关机
具体功能:
1. 定时操作
2. 汇报情况
3. 强制备份
## 更新情况
- 2020/05/15 v0.7 加入Error Json,walk.Resouce.Icon()使用绝对路径,修改users.exe的报错机制
- 2020/05/18 v0.8 更新 大屏主机的文件共享,取消TXHD的凌晨关机.
- 2020/05/27 v0.9 新增微盘备份与同步功能,adct能够强制备份用户文件,用注册表来存储信息
- 2020/06/03 v1.0 完善代码,强制备用户文件方法,日志输出到特定目录,优化变量名,输出日志并由filebeat发送到elk,修复一堆错误
- 2020/06/08 v1.0.1 修改函数文件结构,新增部分格式化错误,修改备份方案(一)
- 2020/06/12 v1.0.2 第二版用户备份方案更新完成
- 2020/06/17 v1.1.0 更新在注册表中用户状态记录和修正电源状态的记录
- 2020/06/19 v1.1.1 修复备的Bug
- 2020/07/07 v1.1.2 优化备份策略
- 2020/07/22 v1.3.1 修复文件共享打开失败问题,支持对非域用户的唤醒
- 2020/07/09 v1.2.0 更新批量打开工具
- 2020/07/20 v1.3.0 升级备份,优化注册表值记录,启动企业微信知微运维平台
- 2020/07/22 v1.3.1 修复文件共享打开失败问题,支持对非域用户的唤醒
- 2020/07/27 v1.4.0 更新图标显示/隐藏工具,优化exec消息处理逻辑,优化企业微信知微运维平台
- 2020/07/30 v1.5.0 知微运维平台升级支持开机重启关机、支持批量百度搜索
- 2020/08/05 v1.5.1 update wxwork
- 2020/08/10 v1.5.2 修复文件共享BUG
- 2020/08/11 v1.6.0 域用户备份升级
- 2020/08/12 v1.6.1 优化备份方案
- 2020/08/19 v1.7.0 更新PDF转化工具,优化用户备份
- 2020/08/21 v1.8.0 合并企业微信推送,转型HTTP服务器,增加活动检测,用户备份升级
## 其他说明
### xln/walk的修改
......@@ -68,9 +93,4 @@ UI:在DC上以用户权限且任务栏托盘的方式运行
### 其他问题
1. SlaveAD辅控应启动Daemon,作为备用响应请求程序
2. 托盘中菜单按钮不能实时修改
### 更新情况
v1.0 完善代码
\ No newline at end of file
1. 托盘中菜单按钮不能实时修改
......@@ -4,27 +4,29 @@ import (
"flag"
)
func main(){
func initLog(){
var logpath string
// 作为主控启动
if pub.Adserver() {
logpath = pub.Dir_AD_log
} else {
// 作为PC启动
if pub.RunAsPC(pub.User_computername){
logpath = `C:\windows\system32\`
// 作为用户启动
}else{
logpath = pub.Dir_userprofile + `\`
}
}
pub.Loger = pub.NewLoger(logpath + `adct.log`)
//pub.AutoFillInWeDriveDir()
//pub.PrintLog("start adct")
pub.Loger = pub.NewLoger(logpath)
}
func main(){
initLog()
var backupText = flag.String( pub.Msg_Backup ,"" ,"backup status to AD")
var reportText = flag.String( pub.Msg_Report ,"" ,"report to AD")
var execText = flag.String( pub.Msg_Exec ,"" ,"exec to LocalDaemon")
//var userText = flag.String( "user" ,"" ,"who is running me")
var passText = flag.String( "pass" ,"" ,"input passwork,but not need")
var wolmacText = flag.String( "wolmac" ,"" ,"input mac address for wake pc")
var woluserText = flag.String( "woluser" ,"" ,"input name for walk pc")
......@@ -35,7 +37,6 @@ func main(){
if *hourText { flag_hour( );return}
if *reportText != "" { flag_report( reportText );return}
if *backupText != "" { flag_bakcup( backupText );return}
if *execText != "" { flag_exec( execText );return}
if *wolmacText != "" { flag_wolmac( wolmacText );return}
if *woluserText != "" { flag_woluser( woluserText,passText);return}
......@@ -44,22 +45,10 @@ func main(){
return
}
func flag_report(s *string){
// 预处理 消息
switch *s{
case pub.Msg_Report_OverBak:
chmod := "cacls " + pub.Dir_DCSave + `\` + pub.TrimPrefix(pub.Dir_userprofile,`C:\Users\`) + ` /T /G `+ pub.User_name+":F"
pub.PntInfo(chmod)
pub.Execcmd_wait(chmod)
pub.Execcmd_nowait(pub.Msg_Exec_TurnOffPC_cmd)
}
// 发送消息
pub.SendServerReport(*s)
}
func flag_bakcup(s *string){
;
}
func flag_exec(s * string){
pub.SendServerExec(*s)
}
......@@ -67,8 +56,8 @@ func flag_hour(){
nh := pub.GetHour()
switch nh{
default :
pub.Execcmd_nowait(`即将关机,如需取消,点击小工具-电源管理-取消自动关机 或运行Z:\tools\【工具】取消关机.bat`)
pub.Execcmd_nowait(`shutdown -s -t 300`)
//pub.Execcmd_nowait(`即将关机,如需取消,点击小工具-电源管理-取消自动关机 或运行Z:\tools\【工具】取消关机.bat`)
//pub.Execcmd_nowait(`shutdown -s -t 300`)
break
}
}
......
......@@ -2,60 +2,14 @@ package main
import (
pub "AD-Control/public"
"net"
"bufio"
"net/http"
)
// 守护进程 初始化
func daemonInit(){
if !pub.Adserver(){pub.Exit()}
func main() {
// 写入日志
pub.Loger = pub.NewLoger(pub.Dir_AD_log + `daemon.log`)
}
// 守护进程 运行
func deamonRun(){
listener, err := net.Listen("tcp",pub.DaemonListen)
if err != nil {
pub.PntError("Listen Error ", err)
return
}
defer listener.Close()
pub.PrintLog("start Daemon")
for{
if conn, err := listener.Accept(); err == nil {
// 新建 读取流
bmsg,_:= bufio.NewReader(conn).ReadBytes(pub.EndSign)
if len(bmsg) == 0 {continue}
//pub.PrintLog(string(bmsg))
// 获取ip
ip := pub.GetConnIP(conn.RemoteAddr())
// 获取消息类型
msgtype := pub.GetMsgType(bmsg[0:30])
// 处理消息
rec := pub.DealMsgEnter(ip,msgtype,bmsg)
// 写入连接
conn.Write(rec)
// 关闭连接
if err := conn.Close(); err != nil {
pub.PntInfo(err)
}
}else{
pub.PntError(" Listen Error", err)
}
}
}
func main() {
daemonInit()
deamonRun()
pub.PrintLog("start daemon!")
http.HandleFunc("/", pub.DealMsgEnter)
http.ListenAndServe(pub.DaemonListen,nil)
}
\ No newline at end of file
......@@ -3,12 +3,11 @@ package public
// AD-Control //
const Host_adserver string = "ADSERVER"
const DaemonPort string = "16824"
const DaemonListen string = ":" + DaemonPort
const ADServerDaemon string = Host_adserver + DaemonListen
const WxwrokDaemon string = ":16823"
const RandMax int = 60
const Version string = "1.7.0"
const DaemonListen string = ":16823"
const Version string = "1.8.0"
const Bak_Version string = "0819"
var Active bool = true
// user //
......@@ -64,21 +63,16 @@ var File_Sync_settings_full string = Dir_Sync_Config + "default settings.xml"
const App_adct string = SMB_ADSoftApplication + "adct.exe"
const App_MultiSplit string = SMB_ADSoftOthTool + "win_MultiSplit.exe"
const App_Sync string = `syncappw.exe`
const App_Sync_dir string = `C:\Progra~1\zhiwei\AllWay_Sync\Bin\syncappw.exe`
// backup //
var Bak_Version string = "0811"
const App_SyncExe string = App_Sync + `.exe`
const App_Sync string = `syncappw`
const App_Sync_full string = `C:\Progra~1\zhiwei\AllWay_Sync\Bin\` + App_Sync
// reg info //
const (
HKCU = iota
HKLM
HKU
HKCU = iota
HKLM
HKU
)
const Reg_Root_ac int = HKLM
......@@ -128,13 +122,3 @@ const WxworkCorid string = "ww49cfd580625083c9"
const WxworkCorpSecret string = "ckANI7SsRh0v_zu2uN7gitRHvTwqRAh8oG1a20xJo_I"
const WxWorkAgentID string = "1000014"
// wxwork event key //
const WXEK_zwDevopsPowerWake string = "zwdevops_power_wake"
const WXEK_zwDevopsPowerTurnOFF string = "zwdevops_power_turnoff"
const WXEK_zwDevopsPowerReboot string = "zwdevops_power_reboot"
const WXEK_zwDevopsPowerStatus string = "zwdevops_power_status"
// wxwork answaer //
const WXRec_WakeSuccess string = "主机已启动,一切就绪~"
\ No newline at end of file
......@@ -71,8 +71,6 @@ const Msg_Exec_State_Ack string = "ack"
const Msg_Exec_State_Over string = "over"
const Msg_Exec_TurnOffPC string = TurnOffPC
const Msg_Exec_TurnOffPC_cmd string = "shutdown -s -t 300"
const Msg_Exec_CancelTurnOffPC string = "cancel" + TurnOnPC
const Msg_Exec_CancelTurnOffPC_cmd string = "shutdown -a"
const Msg_Exec_LogOffUser string = LogOutUser
const Msg_Exec_LogOffUser_cmd string = "shutdown -l"
const Msg_Exec_RebootWindows string = "rebootWindows"
......@@ -83,12 +81,14 @@ const Msg_Exec_OpenAdminEXE string = "OpenAdmin"
// msg wxwork type ////////////////////////////////////////////////////////////////
// wxwork event key ////////////////////////////////////////////////////////////////
const WXEK_zwDevopsPowerWake string = "zwdevops_power_wake"
const WXEK_zwDevopsPowerTurnOFF string = "zwdevops_power_turnoff"
const WXEK_zwDevopsPowerReboot string = "zwdevops_power_reboot"
const WXEK_zwDevopsPowerStatus string = "zwdevops_power_status"
const Msg_Wxwork_UserWake string = "UserWake"
const Msg_Wxwork_Reboot string = "Reboot"
const Msg_Wxwork_TurnOFF string = "TurnOFF"
const Msg_Wxwork_Status string = "Status"
// Registry Root
......@@ -139,11 +139,11 @@ type MJerror struct{
MJbase
}
type MJwxwork struct {
MsgType string `json:"msgtype"`
UserID string `json:"userid"`
Name string `json:"name"`
Instruction string `json:"instruction"`
Text string `json:"text"`
Instruction string
UserID string
Name string
Result string
Content string
}
......@@ -163,12 +163,6 @@ func GJreport(s string) interface{}{
rep.init(s)
return rep
}
func GJreport_DCInfo(s string) interface{}{
var rep MJreport
rep.init(Msg_Report_DCInfo)
rep.Explain = s
return rep
}
func (rep * MJreport)Reg_Write_ADDC(key , value string){
Reg_Write_key_one(
Reg_Root_ac,
......@@ -268,21 +262,12 @@ func (err * MJerror)init (e error){
err.MsgType = Msg_Error
err.Instruction = e.Error()
}
func GJwxworkText(name, userid * string,instruction string )interface {}{
var wxwork MJwxwork
wxwork.MsgType = Msg_Wxwork
wxwork.Name = *name
wxwork.UserID = *userid
wxwork.Text = ""
wxwork.Instruction = instruction
return wxwork
}
// wxwork
func (wxwork * MJwxwork)SendTextToAUser() error {
return SendWxworkTextToAUser(wxwork.UserID,wxwork.Text)
func (wxwork * MJwxwork)SendText(text string) {
SendWxworkTextToAUser(wxwork.UserID,text)
}
func (wxwork * MJwxwork)Reg_Query_ADUsers(key string) string{
return Reg_query_key_one(
......@@ -295,4 +280,7 @@ func (wxwork * MJwxwork)Reg_Query_ZhiWeiUsers(key string) string{
Reg_Root_ac,
Reg_Path_home_zhu + wxwork.Name,
key)
}
func (wxwork * MJwxwork)SendResult(){
SendWxworkTextToAUser(wxwork.UserID,wxwork.Result)
}
\ No newline at end of file
......@@ -13,7 +13,8 @@ func NewLoger(s string) * log.Logger{
if Log_file_obj,err = os.OpenFile(
s,os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766);
err !=nil && DomainComputer(){
SendServerErrorf("%s %v-%v",s,Error_Fail_File_Open,err)
SendServerError(fmt.Errorf("%s %v-%v",s,Error_Fail_File_Open,err))
}
return log.New(Log_file_obj,"",log.LstdFlags)
}
......@@ -32,10 +33,6 @@ func PrintLog(v ...interface{}){
log.SetPrefix("Output ")
log.Println(v ...)
}
func PrintLogPre(pre string,v ...interface{}){
log.SetPrefix(pre)
log.Println(v ...)
}
func PntInfo(v ...interface{}){
Loger.SetPrefix("Info ")
Loger.Println(v ...)
......@@ -56,10 +53,7 @@ func PntBackup(v ...interface{}){
Loger.SetPrefix("Bakcup ")
Loger.Println(v ...)
}
func PntReg(v ...interface{}){
Loger.SetPrefix("Reg ")
Loger.Println(v ...)
}
func PntError(v ...interface{}){
Loger.SetPrefix("Error ")
PrintLog(v ...)
......@@ -82,22 +76,16 @@ func PntSend(v ...interface{}){
Loger.SetPrefix("Send ")
Loger.Println(v ...)
}
func PntWxwork(v ...interface{}){
log.SetPrefix("WXWORK")
func PntWXRec(v ...interface{}){
log.SetPrefix("WXRec ")
log.Println(v ...)
Loger.SetPrefix("WXWORK ")
Loger.SetPrefix("WXRec ")
Loger.Println(v ...)
}
func PntWxSendText(v ...interface{}){
Loger.SetPrefix("WxSendText ")
func PntWxSend(v ...interface{}){
Loger.SetPrefix("WxSend ")
Loger.Println(v ...)
log.SetPrefix("WxSendText ")
log.SetPrefix("WxSend ")
log.Println(v ...)
}
func PntWxRecText(v ...interface{}){
Loger.SetPrefix("WxRecText ")
Loger.Println(v ...)
log.SetPrefix("WxRecText ")
log.Println(v ...)
}
\ No newline at end of file
package public
import (
"os"
"encoding/json"
"bytes"
"strings"
"net"
"bufio"
"io/ioutil"
)
// 获取 环境变量
// 如果空 输出错误
// 获取 消息类型
func GetMsgType(b []byte)string{
//{"msgtype":"report","...":"..."}
// 提取第一个冒号后的第二位和第一个逗号的前一位
// 也就是msgtype的内容
......@@ -21,7 +14,7 @@ func GetMsgType(b []byte)string{
}
// 解析Json 并放到变量中
func ParseJsonBody(unmsg []byte,v interface{}){
func ParseJson(unmsg []byte,v interface{}){
// 填写
if err := json.Unmarshal(unmsg,v) ;err != nil{
PntError("Parse Json Error",err)
......@@ -29,108 +22,16 @@ func ParseJsonBody(unmsg []byte,v interface{}){
}
}
// Jsom 转 Byte
func JsonToByte(v interface{}) []byte{
textbyte,err := json.Marshal(v)
// Json 转 Byte
func ReParseJson(v * interface{}) []byte{
textbyte,err := json.Marshal(*v)
if err !=nil {
PntError("Json to String Error ",v,err)
PntError("Json to byte Error ",v,err)
}
return textbyte
}
func WriteBytesFile(file string ,data []byte)error{
return ioutil.WriteFile(file,data,os.ModeSetuid)
}
func CreateSelfXML(homefolder ,filename string,wetype int,weid string) error {
index := strings.Index(weid,"WeDrive")-1
//var ret bytes.Buffer
var user_source_homedir_re = []byte(homefolder)
var wedrive_source_id_re = []byte("")
var wedrive_dist_dept_re = []byte(User_dept)
var wedrive_dist_user_re = []byte(User_name_display)
if weid != "1" {
wedrive_source_id_re = []byte(weid[index-16:index])
}else{
wedrive_source_id_re = []byte("1")
}
var user_source_homedir = []byte("-tengfei-") // 源值,用户文件备份,源地址,家文件名,C:\Users\-tengfei-
//var user_dist_homedir = []byte("-tengfei-") // 源值,用户文件备份,目标地址,家文件名,D:\DomainUserBakcupV2\-tengfei-
//var wedrive_source_homedir = []byte("-tengfei-") // 源值,微盘文件备份,源地址,家文件名,C:\Users\-tengfei-\AppData\Roaming\Tencent\WXWork\Data\1688854025201314\WeDrive\知微数据
var wedrive_source_id = []byte("-1688854025201314-") // 源值,微盘文件备份,源标地址,微信ID,C:\Users\tengfei\AppData\Roaming\Tencent\WXWork\Data\-1688854025201314-\WeDrive\知微数据
var wedrive_dist_dept = []byte("-技术部门-") // 源值,微盘文件备份,目标地址,部门,\\adserver\ADMAIN\-技术-\陶腾飞\wedrive
var wedrive_dist_user = []byte("-陶腾飞-") // 源值,微盘文件备份,目标地址,\\adserver\ADMAIN\技术\-陶腾飞-\wedrive
if obj,err := os.OpenFile(filename,os.O_RDONLY,0755); err ==nil{
defult, err := os.OpenFile(File_Sync_profile_full, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0755)
scanner := bufio.NewScanner(obj)
defer obj.Close()
defer defult.Close()
for scanner.Scan() {
lineText := scanner.Bytes()
if bytes.Contains(lineText,user_source_homedir){
lineText = bytes.Replace(lineText,user_source_homedir, user_source_homedir_re,1)
}else if bytes.Contains(lineText,wedrive_source_id){
lineText = bytes.Replace(lineText,wedrive_source_id, wedrive_source_id_re,1)
}else if bytes.Contains(lineText,wedrive_dist_dept){
lineText = bytes.Replace(lineText,wedrive_dist_dept, wedrive_dist_dept_re,1)
}else if bytes.Contains(lineText,wedrive_dist_user){
lineText = bytes.Replace(lineText,wedrive_dist_user, wedrive_dist_user_re,1)
}
_, err = defult.Write(lineText)
if err != nil {
PntError(err)
}
}
}else{
SendServerErrorf("%s %v",filename,err)
}
return nil
}
// 从连接中 获取ip
func GetConnIP(s net.Addr) string {
return strings.Split(s.String(),":")[0]
}
func HasSuffix(str * string,sub string)bool{
return strings.HasSuffix(*str,sub)
}
func TrimSuffix(str ,s string)string{
return strings.TrimSuffix(str,s)
}
func TrimPrefix(str ,s string)string{
return strings.TrimPrefix(str,s)
}
func IndexString(str,sub string)int{
return strings.Index(str,sub)
}
func Splitln(str string)[]string{
return strings.Split(str,"\n")
}
func Exit(){
os.Exit(0)
}
func HostnameToUsername(hostname * string)string {
if strings.HasSuffix(*hostname,"-PC$") {
return Reg_query_key_one(
Reg_Root_ac,
Reg_Path_home_ac + *hostname,
Reg_Name_LoginTime)
}
return *hostname
}
func AutoGetWeDriveDir() (string,error) {
for _,i := range Dir_WeDrive{
if NotExist(i){
......@@ -155,36 +56,7 @@ func AutoFillInWeDriveDir() {
SendServerError(err)
} else {
Reg_Write_DC(Reg_Name_WeDriveDir,a)
SendServerDCInfo(a)
}
}
}
func GetWeDriveVersion() (int,string,error) {
d := Reg_Query_DC(Reg_Name_WeDriveDir)
if strings.Contains(d, "Documents"){
return 2,d,nil
} else if strings.Contains(d, "AppData"){
return 1,d,nil
}else {
return 1,"233",Error_Null_Folder_WeDrive
}
}
func GetWXWorkToken() (string,error) {
link := Sprintf("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s",WxworkCorid,WxworkCorpSecret)
data,err := SendGetRequest(&link)
if err !=nil {
return "",err
}
var wt WxToken
ParseJsonBody(data,&wt)
if wt.Errcode== 0 {
return wt.Access_token,nil
} else {
PntError(err)
return "",Error_Fail_File_Write
}
}
\ No newline at end of file
......@@ -2,75 +2,50 @@ package public
import (
"encoding/json"
"net"
"net/http"
"io/ioutil"
"bytes"
"bufio"
"io"
"fmt"
)
func SendServerReport(s string)([]byte,error){
return SendServer(GJreport(s))
}
func SendServerDCInfo(s string)([]byte,error){
return SendServer(GJreport_DCInfo(s))
return SendMsg(Msg_Report,GJreport(s))
}
func SendServerExec(s string)([]byte,error){
return SendServer(GJexec(s))
return SendMsg(Msg_Exec,GJexec(s))
}
func SendServerError(err error)([]byte,error){
return SendServer(GJerror(err))
func SendServerExecJ(v interface{})([]byte,error){
return SendMsg(Msg_Exec,v)
}
func SendServerErrorf(f string, a ...interface{}) ([]byte,error) {
return SendServer(GJerror(fmt.Errorf(f,a ...)))
func SendServerError(err error)([]byte,error){
return SendMsg(Msg_Error,GJerror(err))
}
// send to server
func SendServer(v interface{}) ([]byte,error){
//if Adserver() {return nil}
return SendMsg(ADServerDaemon,v)
}
// base
func SendMsg(you string ,v interface{}) ([]byte,error){
func SendMsg(msgtype string ,v interface{}) ([]byte,error){
textbyte,err := json.Marshal(v)
if err !=nil {
PntError("Json to String Error ",v,err)
return nil,err
}
link := fmt.Sprintf("http://%s/%s",ADServerDaemon,msgtype)
PntSend(link,string(textbyte))
conn, err := net.Dial("tcp", you)
//发送数据
resp, err := http.Post(
link,
"application/json; charset=utf-8",
bytes.NewReader(textbyte))
if err != nil {
PntError("err = ", err)
return nil,err
}
defer conn.Close()
PntSend(string(textbyte))
//发送数据
conn.Write(textbyte)
var rec []byte
if bmsg,cerr:= bufio.NewReader(conn).ReadBytes(EndSign);cerr == nil || cerr == io.EOF{
// 获取ip
ip := GetConnIP(conn.RemoteAddr())
// 获取消息类型
msgtype := GetMsgType(bmsg)
// 处理消息
rec = DealMsgEnter(ip,msgtype,bmsg)
// 写入连接
//conn.Write(rec)
}else{
PntError("Conn Read Error",cerr)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
return rec,nil
return body,nil
}
// 发送Get请求
......@@ -83,14 +58,13 @@ func SendGetRequest(link * string) ([]byte,error){
body, err := ioutil.ReadAll(resp.Body)
return body,err
}
// 发送 带Data的Post请求
func SendPostRequestWithData(link * string,data interface {}) ([]byte,error){
resp, err := http.Post(
*link,
"application/json; charset=utf-8",
bytes.NewReader(JsonToByte(data)))
bytes.NewReader(ReParseJson(&data)))
if err != nil {
return nil,err
......@@ -128,7 +102,7 @@ func SendWxworkTextToAUser(id,text string) error{
wsmt.Init()
wsmt.Touser=id
wsmt.Text.Content=text
link:=Sprintf("https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s",t)
link:=fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s",t)
// 发送 Post 请求
res,err := SendPostRequestWithData(&link,&wsmt)
......@@ -138,7 +112,7 @@ func SendWxworkTextToAUser(id,text string) error{
// 解析 Post 响应 数据
var wsmr WxSendMsgRec
ParseJsonBody(res,&wsmr)
ParseJson(res,&wsmr)
if wsmr.ErrCode != 0{
return NewError(wsmr.ErrMsg)
}
......@@ -147,6 +121,6 @@ func SendWxworkTextToAUser(id,text string) error{
}
func SendWxworkTextToAUserWithName(name ,id,text string) error{
PntWxSendText(name,text)
PntWxSend(name,text)
return SendWxworkTextToAUser(id,text)
}
......@@ -27,6 +27,13 @@ func GetStrTime() string{
func GetHour() int{
return time.Now().Hour()
}
// 输出当前小时
func GetDateHour() (int,int) {
t:=time.Now()
_,_,d := t.Date()
h,_,_ := t.Clock()
return d,h
}
func ParseTime(s string) (time.Time,error) {
return time.Parse("2006-01-02 15:04:05.999999999 -0700 MST",s)
}
......@@ -36,7 +43,7 @@ func ParseTime(s string) (time.Time,error) {
// other func
//
// 输出 随机数
// 返回 随机数
func Rand(i * int)int{
rand.Seed(time.Now().UnixNano())
return rand.Intn(*i)
......
package public
import(
"strings"
)
//
//
......@@ -8,25 +12,12 @@ package public
const AD_User_main_admin string = "zhiweiadserver"
const AD_User_tengfei string = "tengfei"
const AD_User_taotengfei string = "taotengfei"
const AD_User_huyibo string = "huyibo"
const AD_User_zhiwei string = "zhiwei@zhiweireach.com"
const Zhiwei_Dept_HB string = "HB"
const Zhiwei_Dept_LP string = "LP"
const Zhiwei_Dept_MT string = "MT"
const Zhiwei_Dept_JR string = "JR"
const Zhiwei_Dept_JD string = "JD"
const Zhiwei_Dept_TXHD string = "TXHD"
const Zhiwei_Dept_TXWJ string = "TXWJ"
const Zhiwei_Dept_BGYJZX string = "BGYJZX"
const Zhiwei_Dept_TECH string = "TECH"
const Zhiwei_Dept_Count = 9
//
//
// If User
// User
//
func GetPrimaryUser(pc string) string {
......@@ -38,7 +29,7 @@ func GetPrimaryUser(pc string) string {
return name
}
func IsPrimaryUser(s string) bool{
if IndexString(s,"zhiwei") == -1{
if strings.Index(s,"zhiwei") == -1{
return true
}
return false
......@@ -72,6 +63,8 @@ func RunAsPC(s string)bool{
return false
}
}
//
//
// If computer
......
......@@ -416,6 +416,8 @@ func CopyFile(dstFileName string, srcFileName string) (written int64, err error)
func RemoveFile(name string)error{
return os.Remove(name)
}
//
//
// Folder operate
......@@ -456,4 +458,18 @@ func GetNewFolder(rdir ,extdir string) string {
}
}
return firstName
}
//
//
// application
//
func Exit(){
os.Exit(1)
}
func MsgShutdown(msg string){
Msg(msg)
Execcmd_nowait(Msg_Exec_TurnOffPC_cmd)
PntInfo(Msg_Exec_TurnOffPC_cmd)
}
\ No newline at end of file
package public
import(
"encoding/xml"
"net/url"
"wxbizmsgcrypt"
"fmt"
)
func ParseWX(d string,byteBody* []byte) MJwxwork{
var err error
var wxmsg wxXml
var w MJwxwork
// 建立 企业微信 加密方法
wxcpt := wxbizmsgcrypt.NewWXBizMsgCrypt(WxworkTokenMsgSend, WxworkEncodingAseKey, WxworkReceiverId, wxbizmsgcrypt.XmlType)
// 解析 地址 参数
// ?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3&timestamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D
m,_ := url.ParseQuery(d)
// 验证消息
// res, cryptErr := wxcpt.VerifyURL(m["msg_signature"][0],m["timestamp"][0], m["nonce"][0],m["echostr"][0])
// if nil != cryptErr {
// PrintLog("verifyUrl fail", cryptErr)
// }
// PrintLog("verifyUrl success code:", string(res))
// fmt.Fprintf(w,string(res))
// return
// 解密html
msg, cerr := wxcpt.DecryptMsg(
m["msg_signature"][0],
m["timestamp"][0],
m["nonce"][0],
*byteBody)
if err != nil {
PntError("DecryptMsg fail", cerr)
w.Result = Error_WXWork_Down_STR
return w
}
// 解析具体消息
if nil != xml.Unmarshal(msg,&wxmsg){
PntError("Unmarshal fail")
w.Result = Error_WXWork_Down_STR
return w
}
// 获取 查阅同事的token
wtBricklayer,err := GetWXWorkToken()
if err != nil{
PntError(err)
w.Result = Error_WXWork_Down_STR
return w
}
// 查询 姓名
name,err := GetBricklayerName(wtBricklayer,wxmsg.FromUsername)
if err !=nil {
PntError(err)
w.Result = Error_WXWork_Down_STR
return w
}
// 企业微信 消息 处理
// wxmsg.Content是接收到的文本消息ID
// wxmsg.EventKey是菜单事件
// 创建菜单调用工具:https://open.work.weixin.qq.com/wwopen/devtool/interface?doc_id=10786
// 创建菜单官方说明:https://work.weixin.qq.com/api/doc/90000/90135/90231
w.Instruction = wxmsg.EventKey
w.UserID = wxmsg.FromUsername
w.Name = name
w.Content = wxmsg.Content
return w
// 先回复空,再异步发送处理结果
// // 建立 回复消息模板
// xml,t,nonce := wxmsg.createXML(result)
// func (wxmsg * wxXml) createXML(res string) (string,string,string) {
// t := time.Now()
// nonce := strconv.Itoa(t.Nanosecond())
// timestamp := strconv.FormatInt(t.Unix(),10)
// wxmsg.Content = res
// xml,err := xml.Marshal(&wxmsg)
// if err != nil {
// PntError(err)
// }
// return string(xml),timestamp,nonce
// }
// // 加密消息
// cryptMsg, cryptErr := wxcpt.EncryptMsg(xml, t, nonce)
// if nil != cryptErr {
// PntError("DecryptMsg fail", cryptErr)
// return Error_WXWork_Down_STR
// }
// return string(cryptMsg)
}
// 读取企业通讯录的成员信息
// 官方说明: https://work.weixin.qq.com/api/doc/90000/90135/90196
func GetBricklayerName(token, userid string) (string,error) {
link := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=%s&userid=%s",token,userid)
data,err := SendGetRequest(&link)
if err !=nil {
PntError(err)
return "",Error_WXWork_Down
}
var bi wxJsonBricklayerInfo
ParseJson(data,&bi)
if bi.Errcode !=0 {
PntError(bi.Errmsg)
return "",Error_WXWork_Down
}
return bi.Name,nil
}
func GetWXWorkToken() (string,error) {
link := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s",WxworkCorid,WxworkCorpSecret)
data,err := SendGetRequest(&link)
if err !=nil {
return "",err
}
var wt WxToken
ParseJson(data,&wt)
if wt.Errcode== 0 {
return wt.Access_token,nil
} else {
PntError(err)
return "",Error_Fail_File_Write
}
}
\ No newline at end of file
......@@ -44,4 +44,67 @@ func(wsmt * WxSendMsgText) Init(){
wsmt.Enable_id_trans = 0
wsmt.Enable_duplicate_check = 0
wsmt.Duplicate_check_interval = 1800
}
\ No newline at end of file
}
// 获取 同事个人信息的Json
// https://open.work.weixin.qq.com/api/doc/90000/90135/90196
type wxJsonBricklayerInfo struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
Userid string `json:"userid"`
Name string `json:"name"`
Department []int `json:"department"`
Order []int `json:"order"`
Position string `json:"position"`
Mobile string `json:"mobile"`
Gender string `json:"gender"`
Email string `json:"email"`
Is_leader_in_dept []int `json:"is_leader_in_dept"`
Avatar string `json:"avatar"`
Thumb_avatar string `json:"thumb_avatar"`
Telephone string `json:"telephone"`
Alias string `json:"alias"`
Address string `json:"address"`
Open_userid string `json:"open_userid"`
Main_department int `json:"main_department"`
Extattr wxJsonBricklayerInfoExtattr `json:"extattr"`
Status int `json:"status"`
Qr_code string `json:"qr_code"`
External_position string `json:"external_position"`
External_profile wxJsonBricklayerInfoExtattr `json:"external_profile"`
}
type wxJsonBricklayerInfoExtattr struct {
Attrs [] wxJsonBricklayerInfoExtattrValue `json:"attrs"`
}
type wxJsonBricklayerInfoExtattrValue struct {
Type int `json:"type"`
Name string `json:"name"`
Text wxJsonBricklayerInfoExtattrValueText `json:"text"`
Web wxJsonBricklayerInfoExtattrValueWeb `json:"value"`
MiniProgram wxJsonBricklayerInfoExtattrValueMinProgram `json:"miniProgram"`
}
type wxJsonBricklayerInfoExtattrValueText struct {
Value string `json:"value"`
}
type wxJsonBricklayerInfoExtattrValueWeb struct {
Url string `json:"url"`
Title string `json:"title"`
}
type wxJsonBricklayerInfoExtattrValueMinProgram struct {
Appid string `json:"appid"`
Pagepath string `json:"pagepath"`
Title string `json:"title"`
}
type wxXml struct {
ToUsername string `xml:"ToUserName"`
FromUsername string `xml:"FromUserName"`
CreateTime uint32 `xml:"CreateTime"`
MsgType string `xml:"MsgType"`
Content string `xml:"Content"`
Msgid string `xml:"MsgId"`
Agentid uint32 `xml:"AgentId"`
Event string `xml:"Event"`
EventKey string `xml:"EventKey"`
}
......@@ -20,7 +20,7 @@ const (
// 电源菜单
func menuInitPower(ni * walk.NotifyIcon){
fa := "电源选项"
sub := [...]string{"关闭系统","用户注销","重启系统","取消关机计时"}
sub := [...]string{"保持开机","取消关机计时"}
// 建立空菜单
nm,err := walk.NewMenu()
......@@ -38,14 +38,10 @@ func menuInitPower(ni * walk.NotifyIcon){
// 为子按钮 添加事件
switch i{
case 0:
na.Triggered().Attach(pCloseWindows)
na.Triggered().Attach(pKeppRunning)
case 1:
na.Triggered().Attach(pLogOffUser)
case 2:
na.Triggered().Attach(pRebootWindows)
case 3:
na.Triggered().Attach(pCancelCloseWindows)
}
// 将 子按钮 添加到 菜单
......@@ -62,23 +58,15 @@ func menuInitPower(ni * walk.NotifyIcon){
sysmenu.SetVisible(true)
sysmenu.SetEnabled(true)
}
// 电源管理 关机
func pCloseWindows(){
pub.SendServerExec(pub.Msg_Exec_TurnOffPC)
}
// 电源管理 注销用户
func pLogOffUser(){
pub.SendServerExec(pub.Msg_Exec_LogOffUser)
}
// 电源管理 重启主机
func pRebootWindows(){
pub.SendServerExec(pub.Msg_Exec_RebootWindows)
// 电源管理 保持开机
func pKeppRunning(){
pub.Active = false
pub.Msg("将保持开机,至次日9点恢复")
}
// 电源管理 取消自动关机
func pCancelCloseWindows(){
pub.SendServerExec(pub.Msg_Exec_CancelTurnOffPC)
pub.Execcmd_output("shutdown -a")
}
......@@ -105,7 +93,7 @@ func menuInitSoftwareInstall(ni * walk.NotifyIcon){
if each == ".DS_Store"{
continue
}
each_noext := pub.TrimSuffix(pub.TrimSuffix(ueach.Name(),".exe"),".msi")
each_noext := strings.TrimSuffix(strings.TrimSuffix(ueach.Name(),".exe"),".msi")
// 建立 子按钮
na := walk.NewAction()
......@@ -136,7 +124,7 @@ func menuInitSoftwareInstall(ni * walk.NotifyIcon){
func siEnter_admin(softname string){
go pub.Msg("等待弹出安装窗口,请稍等。。")
ifFile := pub.Exist(`C:\windows\`+softname)
pub.SendServer(pub.GJexecInstallSoftware(ifFile,softname))
pub.SendServerExecJ(pub.GJexecInstallSoftware(ifFile,softname))
}
......@@ -256,7 +244,7 @@ func batchOpenWeb(inTE,outTE *walk.TextEdit,batch int){
}
cmd = chrome + cmd
for seq,web := range pub.Splitln(inTE.Text()){
for seq,web := range strings.Split(inTE.Text(),"\n"){
if web == ""{
continue
}
......@@ -280,7 +268,7 @@ func tPdfTrans(){
return
}
go pub.Msg(`Acrobat DC正在打开`)
pub.SendServer(pub.GJexecDIYFlag(pub.Msg_Exec_OpenAdminEXE,AcrobatDC))
pub.SendServerExecJ(pub.GJexecDIYFlag(pub.Msg_Exec_OpenAdminEXE,AcrobatDC))
return
}
......@@ -364,7 +352,7 @@ func menuInitFileShares(ni * walk.NotifyIcon){
// 建立 子按钮
na := walk.NewAction()
if err := na.SetText(pub.TrimSuffix(wokrer,".lnk")); err != nil {
if err := na.SetText(strings.TrimSuffix(wokrer,".lnk")); err != nil {
pub.PntError(err)
}
......@@ -437,7 +425,7 @@ func menuInitMyShares(ni * walk.NotifyIcon){
// 建立 子按钮
na := walk.NewAction()
if err := na.SetText(pub.TrimSuffix(wokrer,".lnk")); err != nil {
if err := na.SetText(strings.TrimSuffix(wokrer,".lnk")); err != nil {
pub.PntError(err)
}
......@@ -495,7 +483,7 @@ func (mw *MyMainWindow) tHideShowIconDeal() {
exec.Explain = "显示"
exec.DataBool = true
}
pub.SendServer(exec)
pub.SendServerExecJ(exec)
}
......
No preview for this file type
package main
/*
#include <windows.h>
POINT point;
void getMouse()
{
GetCursorPos(&point);
}
*/
import "C"
import (
"github.com/lxn/walk"
pub "AD-Control/public"
)
var baseDay,baseHour = pub.GetDateHour()
var baseX,baseY = GetMousePos()
func GetMousePos() (int,int) {
C.getMouse()
x :=int(C.point.x)
y := int(C.point.y)
return x,y
}
func userInit() string{
pub.Loger = pub.NewLoger(pub.Dir_appdata + `\users.log`)
pub.PntInfo("start users!")
pub.PrintLog("start users!")
pub.Reg_Exist_item(pub.HKCU,pub.Reg_Path_home)
......@@ -32,11 +53,36 @@ func menuInit(ni * walk.NotifyIcon){
menuInitMyShares(ni)
}
func isActive(){
for {
d,h := pub.GetDateHour()
// 新的一天
if d == 9 {
pub.Active = true
}
// 非工作时间的新的一小时
if (h >=19 || h<8) && pub.Active{
x,y := GetMousePos()
// 如果处于闲置状态
if baseX == x && baseY == y && pub.IsPrimaryUser(pub.User_name){
pub.MsgShutdown("即将关机,如需取消,点击小工具-电源选项-取消关机计时")
}
}
pub.Delay(3602)
}
}
func main() {
// 用户 初始化
icodir := userInit()
go isActive()
// 程序 初始化
mw,err := walk.NewMainWindow()
if err != nil {
......
package main
// 获取 同事个人信息的Json
// https://open.work.weixin.qq.com/api/doc/90000/90135/90196
type wxJsonBricklayerInfo struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
Userid string `json:"userid"`
Name string `json:"name"`
Department []int `json:"department"`
Order []int `json:"order"`
Position string `json:"position"`
Mobile string `json:"mobile"`
Gender string `json:"gender"`
Email string `json:"email"`
Is_leader_in_dept []int `json:"is_leader_in_dept"`
Avatar string `json:"avatar"`
Thumb_avatar string `json:"thumb_avatar"`
Telephone string `json:"telephone"`
Alias string `json:"alias"`
Address string `json:"address"`
Open_userid string `json:"open_userid"`
Main_department int `json:"main_department"`
Extattr wxJsonBricklayerInfoExtattr `json:"extattr"`
Status int `json:"status"`
Qr_code string `json:"qr_code"`
External_position string `json:"external_position"`
External_profile wxJsonBricklayerInfoExtattr `json:"external_profile"`
}
type wxJsonBricklayerInfoExtattr struct {
Attrs [] wxJsonBricklayerInfoExtattrValue `json:"attrs"`
}
type wxJsonBricklayerInfoExtattrValue struct {
Type int `json:"type"`
Name string `json:"name"`
Text wxJsonBricklayerInfoExtattrValueText `json:"text"`
Web wxJsonBricklayerInfoExtattrValueWeb `json:"value"`
MiniProgram wxJsonBricklayerInfoExtattrValueMinProgram `json:"miniProgram"`
}
type wxJsonBricklayerInfoExtattrValueText struct {
Value string `json:"value"`
}
type wxJsonBricklayerInfoExtattrValueWeb struct {
Url string `json:"url"`
Title string `json:"title"`
}
type wxJsonBricklayerInfoExtattrValueMinProgram struct {
Appid string `json:"appid"`
Pagepath string `json:"pagepath"`
Title string `json:"title"`
}
package main
import (
pub "AD-Control/public"
"net/http"
"encoding/xml"
"log"
"net/url"
"fmt"
"io/ioutil"
"wxbizmsgcrypt"
)
type wxXml struct {
ToUsername string `xml:"ToUserName"`
FromUsername string `xml:"FromUserName"`
CreateTime uint32 `xml:"CreateTime"`
MsgType string `xml:"MsgType"`
Content string `xml:"Content"`
Msgid string `xml:"MsgId"`
Agentid uint32 `xml:"AgentId"`
Event string `xml:"Event"`
EventKey string `xml:"EventKey"`
}
func main(){
pub.Loger = pub.NewLoger(pub.Dir_AD_log + `wxwork.log`)
pub.PrintLog("Wxwrok Daemon Runing!")
http.HandleFunc("/",index)
log.Println(http.ListenAndServe(pub.WxwrokDaemon, nil))
}
func index(w http.ResponseWriter, r *http.Request){
d := r.URL.RawQuery
if d == "" { return }
byteBody,err := ioutil.ReadAll(r.Body)
if err!=nil{
panic(err)
}
// 开始处理HTML
go parseHtmlData(d,&byteBody)
// 立刻返回
fmt.Fprintf(w,"")
}
func parseHtmlData(d string,byteBody* []byte) {
var err error
// 建立 企业微信 加密方法
wxcpt := wxbizmsgcrypt.NewWXBizMsgCrypt(pub.WxworkTokenMsgSend, pub.WxworkEncodingAseKey,pub. WxworkReceiverId, wxbizmsgcrypt.XmlType)
// 解析 地址 参数
// ?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3&timestamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D
m,_ := url.ParseQuery(d)
// 验证消息
// res, cryptErr := wxcpt.VerifyURL(m["msg_signature"][0],m["timestamp"][0], m["nonce"][0],m["echostr"][0])
// if nil != cryptErr {
// PrintLog("verifyUrl fail", cryptErr)
// }
// PrintLog("verifyUrl success code:", string(res))
// fmt.Fprintf(w,string(res))
// return
// 解密html
msg, cryptErr := wxcpt.DecryptMsg(
m["msg_signature"][0],
m["timestamp"][0],
m["nonce"][0],
*byteBody)
if nil != cryptErr {
pub.PntError("DecryptMsg fail", cryptErr)
err = pub.Error_WXWork_Down
}
if len(msg)==0{
err = pub.Error_WXWork_Down
}
// 解析具体消息
wxmsg := ParseXML(&msg)
// 打印xml
//pub.PrintLog(string(msg))
// 获取 查阅同事的token
wtBricklayer,err := pub.GetWXWorkToken()
if err != nil{
pub.PntError(err)
err = pub.Error_WXWork_Down
}
// 查询 姓名
name,err := GetBricklayerName(wtBricklayer,wxmsg.FromUsername)
if err !=nil {
pub.PntError(err)
err = pub.Error_WXWork_Down
}
if err !=nil{
pub.SendWxworkTextToAUser(wxmsg.FromUsername,fmt.Sprintf("%s",err))
}
// 我是复读机
if wxmsg.Content != ""{
pub.SendWxworkTextToAUser(wxmsg.FromUsername,wxmsg.Content)
return
}
// 企业微信 消息 处理
// wxmsg.Content是接收到的文本消息ID
// wxmsg.EventKey是菜单事件
// 创建菜单调用工具:https://open.work.weixin.qq.com/wwopen/devtool/interface?doc_id=10786
// 创建菜单官方说明:https://work.weixin.qq.com/api/doc/90000/90135/90231
rec := wxMsgDealEvent(&name,&wxmsg.FromUsername,&wxmsg.EventKey)
pub.SendWxworkTextToAUserWithName(name,wxmsg.FromUsername,rec)
return
// 先回复空,再异步发送处理结果
// // 建立 回复消息模板
// xml,t,nonce := wxmsg.createXML(result)
// func (wxmsg * wxXml) createXML(res string) (string,string,string) {
// t := time.Now()
// nonce := strconv.Itoa(t.Nanosecond())
// timestamp := strconv.FormatInt(t.Unix(),10)
// wxmsg.Content = res
// xml,err := xml.Marshal(&wxmsg)
// if err != nil {
// pub.PntError(err)
// }
// return string(xml),timestamp,nonce
// }
// // 加密消息
// cryptMsg, cryptErr := wxcpt.EncryptMsg(xml, t, nonce)
// if nil != cryptErr {
// PntError("DecryptMsg fail", cryptErr)
// return Error_WXWork_Down_STR
// }
// return string(cryptMsg)
}
func wxMsgDealEvent(name, userid,eventkey * string) string {
var result []byte
var err error
var wxwork pub.MJwxwork
pub.PntWxRecText(*name,*eventkey)
switch *eventkey{
case pub.WXEK_zwDevopsPowerWake:
pub.SendWxworkTextToAUserWithName(*name,*userid,"收到唤醒指令,正在处理")
result,err = pub.SendServer(pub.GJwxworkText(name,userid,pub.Msg_Wxwork_UserWake))
case pub.WXEK_zwDevopsPowerTurnOFF:
pub.SendWxworkTextToAUserWithName(*name,*userid,"收到关机指令,正在处理")
result,err = pub.SendServer(pub.GJwxworkText(name,userid,pub.Msg_Wxwork_TurnOFF))
case pub.WXEK_zwDevopsPowerReboot:
pub.SendWxworkTextToAUserWithName(*name,*userid,"收到重启指令,正在处理")
result,err = pub.SendServer(pub.GJwxworkText(name,userid,pub.Msg_Wxwork_Reboot))
case pub.WXEK_zwDevopsPowerStatus:
pub.SendWxworkTextToAUserWithName(*name,*userid,"收到查询指令,正在处理")
result,err = pub.SendServer(pub.GJwxworkText(name,userid,pub.Msg_Wxwork_Status))
default:
return ""
}
if err != nil{
pub.PrintLog(fmt.Sprintf("%s",err))
return pub.Error_WXWork_Down_STR
}
pub.ParseJsonBody(result,&wxwork)
return wxwork.Text
}
func ParseXML(unmsg *[]byte)wxXml{
var msg wxXml
if nil != xml.Unmarshal(*unmsg, &msg) {
pub.PntError("Unmarshal fail")
}
return msg
}
// 读取企业通讯录的成员信息
// 官方说明: https://work.weixin.qq.com/api/doc/90000/90135/90196
func GetBricklayerName(token, userid string) (string,error) {
link := pub.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=%s&userid=%s",token,userid)
data,err := pub.SendGetRequest(&link)
if err !=nil {
pub.PntError(err)
return "",pub.Error_WXWork_Down
}
var bi wxJsonBricklayerInfo
pub.ParseJsonBody(data,&bi)
if bi.Errcode !=0 {
pub.PntError(bi.Errmsg)
return "",pub.Error_WXWork_Down
}
return bi.Name,nil
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment