423 lines
11 KiB
Go
423 lines
11 KiB
Go
|
package controller
|
|||
|
|
|||
|
import (
|
|||
|
"encoding/json"
|
|||
|
"fmt"
|
|||
|
"github.com/gin-contrib/sessions"
|
|||
|
"github.com/gin-gonic/gin"
|
|||
|
"github.com/silenceper/wechat/v2/officialaccount/message"
|
|||
|
"kefu/common"
|
|||
|
"kefu/lib"
|
|||
|
"kefu/models"
|
|||
|
"kefu/tools"
|
|||
|
"kefu/types"
|
|||
|
"kefu/ws"
|
|||
|
"log"
|
|||
|
"regexp"
|
|||
|
"strconv"
|
|||
|
"strings"
|
|||
|
)
|
|||
|
|
|||
|
func SendServerJiang(title string, content string, domain string) string {
|
|||
|
noticeServerJiang, err := strconv.ParseBool(models.FindConfig("NoticeServerJiang"))
|
|||
|
serverJiangAPI := models.FindConfig("ServerJiangAPI")
|
|||
|
if err != nil || !noticeServerJiang || serverJiangAPI == "" {
|
|||
|
log.Println("do not notice serverjiang:", serverJiangAPI, noticeServerJiang)
|
|||
|
return ""
|
|||
|
}
|
|||
|
sendStr := fmt.Sprintf("%s%s", title, content)
|
|||
|
desp := title + ":" + content + "[登录](http://" + domain + "/main)"
|
|||
|
url := serverJiangAPI + "?text=" + sendStr + "&desp=" + desp
|
|||
|
//log.Println(url)
|
|||
|
res := tools.Get(url)
|
|||
|
return res
|
|||
|
}
|
|||
|
func SendVisitorLoginNotice(kefuName, visitorName, avator, content, visitorId string) {
|
|||
|
if !tools.LimitFreqSingle("sendnotice:"+visitorId, 1, 5) {
|
|||
|
log.Println("SendVisitorLoginNotice limit")
|
|||
|
return
|
|||
|
}
|
|||
|
userInfo := make(map[string]string)
|
|||
|
userInfo["username"] = visitorName
|
|||
|
userInfo["avator"] = avator
|
|||
|
userInfo["content"] = content
|
|||
|
msg := ws.TypeMessage{
|
|||
|
Type: "notice",
|
|||
|
Data: userInfo,
|
|||
|
}
|
|||
|
str, _ := json.Marshal(msg)
|
|||
|
ws.OneKefuMessage(kefuName, str)
|
|||
|
}
|
|||
|
func SendNoticeEmail(username, subject, entId, content string) {
|
|||
|
if !tools.LimitFreqSingle("send_notice_email:"+username, 1, 10) {
|
|||
|
log.Println("send_notice_email limit")
|
|||
|
return
|
|||
|
}
|
|||
|
configs := models.FindEntConfigByEntid(entId)
|
|||
|
smtp := ""
|
|||
|
email := ""
|
|||
|
password := ""
|
|||
|
for _, config := range configs {
|
|||
|
if config.ConfKey == "NoticeEmailAddress" {
|
|||
|
email = config.ConfValue
|
|||
|
}
|
|||
|
if config.ConfKey == "NoticeEmailPassword" {
|
|||
|
password = config.ConfValue
|
|||
|
}
|
|||
|
if config.ConfKey == "NoticeEmailSmtp" {
|
|||
|
smtp = config.ConfValue
|
|||
|
}
|
|||
|
}
|
|||
|
if smtp == "" || email == "" || password == "" {
|
|||
|
return
|
|||
|
}
|
|||
|
log.Println("发送访客通知邮件:" + smtp + "," + email + "," + password)
|
|||
|
err := tools.SendSmtp(smtp, email, password, []string{email}, subject, content)
|
|||
|
if err != nil {
|
|||
|
log.Println("发送访客通知邮件失败:")
|
|||
|
log.Println(err)
|
|||
|
}
|
|||
|
}
|
|||
|
func SendEntSmtpEmail(subject, msg, entId string) {
|
|||
|
if !tools.LimitFreqSingle("send_ent_email:"+entId, 1, 2) {
|
|||
|
log.Println("send_ent_email limit")
|
|||
|
return
|
|||
|
}
|
|||
|
configs := models.FindEntConfigByEntid(entId)
|
|||
|
smtp := ""
|
|||
|
email := ""
|
|||
|
password := ""
|
|||
|
for _, config := range configs {
|
|||
|
if config.ConfKey == "NoticeEmailAddress" {
|
|||
|
email = config.ConfValue
|
|||
|
}
|
|||
|
if config.ConfKey == "NoticeEmailPassword" {
|
|||
|
password = config.ConfValue
|
|||
|
}
|
|||
|
if config.ConfKey == "NoticeEmailSmtp" {
|
|||
|
smtp = config.ConfValue
|
|||
|
}
|
|||
|
}
|
|||
|
if smtp == "" || email == "" || password == "" {
|
|||
|
return
|
|||
|
}
|
|||
|
err := tools.SendSmtp(smtp, email, password, []string{email}, subject, msg)
|
|||
|
if err != nil {
|
|||
|
log.Println(err)
|
|||
|
}
|
|||
|
}
|
|||
|
func SendAppGetuiPush(kefu string, title, content string) {
|
|||
|
clientModel := &models.User_client{
|
|||
|
Kefu: kefu,
|
|||
|
}
|
|||
|
clientInfos := clientModel.FindClients()
|
|||
|
if len(clientInfos) == 0 {
|
|||
|
return
|
|||
|
}
|
|||
|
appid := models.FindConfig("GetuiAppID")
|
|||
|
appkey := models.FindConfig("GetuiAppKey")
|
|||
|
appsecret := models.FindConfig("GetuiAppSecret")
|
|||
|
appmastersecret := models.FindConfig("GetuiMasterSecret")
|
|||
|
token := models.FindConfig("GetuiToken")
|
|||
|
getui := &lib.Getui{
|
|||
|
AppId: appid,
|
|||
|
AppKey: appkey,
|
|||
|
AppSecret: appsecret,
|
|||
|
AppMasterSecret: appmastersecret,
|
|||
|
}
|
|||
|
for _, client := range clientInfos {
|
|||
|
res, err := getui.PushSingle(token, client.Client_id, title, content)
|
|||
|
//不正确的账号
|
|||
|
if res == 20001 && err.Error() == "target user is invalid" {
|
|||
|
clientModel2 := &models.User_client{
|
|||
|
Kefu: kefu,
|
|||
|
Client_id: client.Client_id,
|
|||
|
}
|
|||
|
clientModel2.DeleteClient()
|
|||
|
}
|
|||
|
if res == 10001 {
|
|||
|
token, _ = getui.GetGetuiToken()
|
|||
|
models.UpdateConfig("GetuiToken", token)
|
|||
|
getui.PushSingle(token, client.Client_id, title, content)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 发送邮件验证码
|
|||
|
func SendEmailAuthCode(c *gin.Context) {
|
|||
|
email := c.PostForm("email")
|
|||
|
//验证邮箱
|
|||
|
matched, _ := regexp.MatchString("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*", email)
|
|||
|
if !matched {
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": types.ApiCode.INVALID,
|
|||
|
"msg": "邮箱格式不正确",
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
if !tools.LimitFreqSingle("send_email_authcode:"+email, 1, 50) {
|
|||
|
log.Println("send_email_authcode limit " + email)
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": types.ApiCode.FREQ_LIMIT,
|
|||
|
"msg": types.ApiCode.GetMessage(types.ApiCode.FREQ_LIMIT),
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
smtp := models.FindConfig("NoticeEmailSmtp")
|
|||
|
sender := models.FindConfig("NoticeEmailAddress")
|
|||
|
password := models.FindConfig("NoticeEmailPassword")
|
|||
|
|
|||
|
if smtp == "" || sender == "" || password == "" {
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": types.ApiCode.INVALID,
|
|||
|
"msg": "系统没有配置发送邮箱",
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
ranNum := tools.RandNum(6)
|
|||
|
session := sessions.DefaultMany(c, "go-session")
|
|||
|
session.Set("emailCode"+email, ranNum)
|
|||
|
_ = session.Save()
|
|||
|
content := strings.Replace(common.NoticeTemplate, "[:content]", "你好,验证码为 "+ranNum, -1)
|
|||
|
|
|||
|
log.Println("发送邮件验证码:" + smtp + "," + sender + "," + password + "," + email + "," + content)
|
|||
|
|
|||
|
logContent := fmt.Sprintf("'%s'获取邮箱验证码 %s", email, ranNum)
|
|||
|
go models.CreateFlyLog(email, c.ClientIP(), logContent, "user")
|
|||
|
|
|||
|
err := tools.SendSmtp(smtp, sender, password, []string{email}, "在线客服系统验证码", content)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
logContent := "发送邮件验证码失败:" + err.Error()
|
|||
|
log.Println(logContent)
|
|||
|
go models.CreateFlyLog(email, c.ClientIP(), logContent, "user")
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": types.ApiCode.EMAIL_FAILD,
|
|||
|
"msg": err.Error(),
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": 200,
|
|||
|
"msg": "ok",
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
// 发送注册通知邮件
|
|||
|
func SendRegisterEmail(username, nickname, loginEmail string) {
|
|||
|
|
|||
|
smtp := models.FindConfig("NoticeEmailSmtp")
|
|||
|
sender := models.FindConfig("NoticeEmailAddress")
|
|||
|
password := models.FindConfig("NoticeEmailPassword")
|
|||
|
|
|||
|
if smtp == "" || sender == "" || password == "" {
|
|||
|
return
|
|||
|
}
|
|||
|
content := fmt.Sprintf("账户:%s,邮箱:%s,昵称:%s,注册成功", username, nickname, loginEmail)
|
|||
|
|
|||
|
err := tools.SendSmtp(smtp, sender, password, []string{sender}, "在线客服系统注册成功", content)
|
|||
|
if err != nil {
|
|||
|
log.Println("发送邮件失败:", err)
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// 发送短信验证码
|
|||
|
func SendSmsCode(c *gin.Context) {
|
|||
|
phone := c.Query("phone")
|
|||
|
//验证
|
|||
|
matched, _ := regexp.MatchString("1[3-9]\\d{9}$", phone)
|
|||
|
if !matched {
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": types.ApiCode.INVALID,
|
|||
|
"msg": types.ApiCode.GetMessage(types.ApiCode.INVALID),
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
if !tools.LimitFreqSingle("sendsms:"+c.ClientIP(), 1, 50) {
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": types.ApiCode.FREQ_LIMIT,
|
|||
|
"msg": types.ApiCode.GetMessage(types.ApiCode.FREQ_LIMIT),
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
ranNum := tools.RandNum(6)
|
|||
|
session := sessions.DefaultMany(c, "go-session-a")
|
|||
|
session.Set("smsCode"+phone, ranNum)
|
|||
|
_ = session.Save()
|
|||
|
|
|||
|
log.Println("发送短信验证码:", phone, ranNum)
|
|||
|
|
|||
|
err := lib.SendSms(phone, ranNum)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Println("发送短信验证码:", err)
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": types.ApiCode.EMAIL_FAILD,
|
|||
|
"msg": err.Error(),
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
kefuName, _ := c.Get("kefu_name")
|
|||
|
entId, _ := c.Get("ent_id")
|
|||
|
logContent := fmt.Sprintf("'%s'手机%s,发送短信验证码'%s'", kefuName, phone, ranNum)
|
|||
|
go models.CreateFlyLog(entId.(string), c.ClientIP(), logContent, "sms")
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": 200,
|
|||
|
"msg": "ok",
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
// 发送微信模板消息
|
|||
|
func PostSendWechatTemplate(c *gin.Context) {
|
|||
|
entId := c.PostForm("ent_id")
|
|||
|
kefuName := c.PostForm("kefu_name")
|
|||
|
tel := c.PostForm("tel")
|
|||
|
customer := models.FindCustomerWhere("kefu_name = ? and tel = ?", kefuName, tel)
|
|||
|
if customer.AcountOpenid == "" {
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": 200,
|
|||
|
"msg": "未查询到绑定的公众号OpenID",
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
templateId := c.PostForm("template_id")
|
|||
|
url := c.PostForm("url")
|
|||
|
keyword1 := c.PostForm("keyword1")
|
|||
|
keyword2 := c.PostForm("keyword2")
|
|||
|
keyword3 := c.PostForm("keyword3")
|
|||
|
keyword4 := c.PostForm("keyword4")
|
|||
|
keyword5 := c.PostForm("keyword5")
|
|||
|
keyword6 := c.PostForm("keyword6")
|
|||
|
remark := c.PostForm("remark")
|
|||
|
wechatConfig, _ := lib.NewWechatLib(entId)
|
|||
|
|
|||
|
msgData := make(map[string]*message.TemplateDataItem)
|
|||
|
msgData["keyword1"] = &message.TemplateDataItem{
|
|||
|
Value: keyword1,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword2"] = &message.TemplateDataItem{
|
|||
|
Value: keyword2,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword3"] = &message.TemplateDataItem{
|
|||
|
Value: keyword3,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword4"] = &message.TemplateDataItem{
|
|||
|
Value: keyword4,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword5"] = &message.TemplateDataItem{
|
|||
|
Value: keyword5,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword6"] = &message.TemplateDataItem{
|
|||
|
Value: keyword6,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["remark"] = &message.TemplateDataItem{
|
|||
|
Value: remark,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msg := &message.TemplateMessage{
|
|||
|
ToUser: customer.AcountOpenid,
|
|||
|
Data: msgData,
|
|||
|
TemplateID: templateId,
|
|||
|
URL: url,
|
|||
|
}
|
|||
|
_, err := SendWechatTemplate(wechatConfig, msg)
|
|||
|
if err != nil {
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": 400,
|
|||
|
"msg": err.Error(),
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": 200,
|
|||
|
"msg": "ok",
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
// 发送微信模板消息
|
|||
|
func PostSendWechatTemplateByOpenid(c *gin.Context) {
|
|||
|
openid := c.PostForm("openid")
|
|||
|
entId := c.PostForm("ent_id")
|
|||
|
if openid == "" {
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": 400,
|
|||
|
"msg": "请传递公众号OpenID!",
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
templateId := c.PostForm("template_id")
|
|||
|
url := c.PostForm("url")
|
|||
|
keyword1 := c.PostForm("keyword1")
|
|||
|
keyword2 := c.PostForm("keyword2")
|
|||
|
keyword3 := c.PostForm("keyword3")
|
|||
|
keyword4 := c.PostForm("keyword4")
|
|||
|
keyword5 := c.PostForm("keyword5")
|
|||
|
keyword6 := c.PostForm("keyword6")
|
|||
|
remark := c.PostForm("remark")
|
|||
|
systemBussinesId := models.FindConfig("SystemBussinesId")
|
|||
|
if entId == "" {
|
|||
|
entId = systemBussinesId
|
|||
|
}
|
|||
|
wechatConfig, _ := lib.NewWechatLib(entId)
|
|||
|
|
|||
|
msgData := make(map[string]*message.TemplateDataItem)
|
|||
|
msgData["keyword1"] = &message.TemplateDataItem{
|
|||
|
Value: keyword1,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword2"] = &message.TemplateDataItem{
|
|||
|
Value: keyword2,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword3"] = &message.TemplateDataItem{
|
|||
|
Value: keyword3,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword4"] = &message.TemplateDataItem{
|
|||
|
Value: keyword4,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword5"] = &message.TemplateDataItem{
|
|||
|
Value: keyword5,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["keyword6"] = &message.TemplateDataItem{
|
|||
|
Value: keyword6,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msgData["remark"] = &message.TemplateDataItem{
|
|||
|
Value: remark,
|
|||
|
Color: "",
|
|||
|
}
|
|||
|
msg := &message.TemplateMessage{
|
|||
|
ToUser: openid,
|
|||
|
Data: msgData,
|
|||
|
TemplateID: templateId,
|
|||
|
URL: url,
|
|||
|
}
|
|||
|
_, err := SendWechatTemplate(wechatConfig, msg)
|
|||
|
if err != nil {
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": 400,
|
|||
|
"msg": err.Error(),
|
|||
|
})
|
|||
|
return
|
|||
|
}
|
|||
|
c.JSON(200, gin.H{
|
|||
|
"code": 200,
|
|||
|
"msg": "ok",
|
|||
|
})
|
|||
|
}
|