fix(notify): bugFix

This commit is contained in:
mhf
2023-02-28 19:35:15 +08:00
parent 8443d4077f
commit ab42fcaade
16 changed files with 176 additions and 151 deletions
+1
View File
@@ -149,6 +149,7 @@ type SendParams struct {
Event string
Receivers SNotifyReceiver
EmailMsg *SEmailMessage
DomainId string
}
type SSMSSendParams struct {
+10 -6
View File
@@ -17,6 +17,7 @@ package models
import (
"context"
"database/sql"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -110,7 +111,7 @@ func (c *SConfig) PostCreate(ctx context.Context, userCred mcclient.TokenCredent
if err != nil {
log.Errorf("unable to StartRepullSubcontactTask: %v", err)
}
ConfigMap[c.Type] = *c
ConfigMap[fmt.Sprintf("%s-%s", c.Type, c.DomainId)] = *c
}
func (c *SConfig) GetNotifyConfig() api.NotifyConfig {
@@ -151,7 +152,7 @@ func (c *SConfig) ValidateUpdateData(ctx context.Context, userCred mcclient.Toke
func (c *SConfig) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
c.SStandaloneResourceBase.PostUpdate(ctx, userCred, query, data)
config := c.GetNotifyConfig()
ConfigMap[c.Type] = SConfig{
ConfigMap[fmt.Sprintf("%s-%s", c.Type, c.DomainId)] = SConfig{
Content: &config.SNotifyConfigContent,
}
err := c.StartRepullSubcontactTask(ctx, userCred, false)
@@ -162,7 +163,7 @@ func (c *SConfig) PostUpdate(ctx context.Context, userCred mcclient.TokenCredent
func (c *SConfig) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) {
c.SStandaloneResourceBase.PreDelete(ctx, userCred)
delete(ConfigMap, c.Type)
delete(ConfigMap, fmt.Sprintf("%s-%s", c.Type, c.DomainId))
}
func (c *SConfig) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
@@ -178,7 +179,7 @@ func (c *SConfig) Delete(ctx context.Context, userCred mcclient.TokenCredential)
}
func (c *SConfig) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
delete(ConfigMap, c.Type)
delete(ConfigMap, fmt.Sprintf("%s-%s", c.Type, c.DomainId))
return c.SDomainLevelResourceBase.Delete(ctx, userCred)
}
@@ -352,12 +353,15 @@ func (confManager *SConfigManager) InitializeData() error {
}
ConfigMap = make(map[string]SConfig)
for _, config := range res {
ConfigMap[config.Type] = config
ConfigMap[fmt.Sprintf("%s-%s", config.Type, config.DomainId)] = config
if config.Type == api.EMAIL {
ConfigMap[config.Type] = config
}
driver := GetDriver(config.Type)
if config.Type == notify.EMAIL || config.Type == notify.MOBILE {
continue
}
err := driver.GetAccessToken()
err := driver.GetAccessToken(fmt.Sprintf("%s-%s", config.Type, config.DomainId))
if err != nil {
session := auth.GetAdminSession(context.Background(), options.Options.Region)
logclient.AddSimpleActionLog(&config, logclient.ACT_INIT_NOTIFY_CONFIGMAP, err, session.GetToken(), false)
+1 -1
View File
@@ -28,7 +28,7 @@ type ISenderDriver interface {
IsSystemConfigContactType() bool
IsValid() bool
IsPullType() bool
GetAccessToken() error
GetAccessToken(key string) error
}
var (
+11 -11
View File
@@ -38,7 +38,7 @@ func (dingSender *SDingTalkSender) GetSenderType() string {
func (dingSender *SDingTalkSender) Send(args api.SendParams) error {
body := map[string]interface{}{
"agent_id": models.ConfigMap[api.DINGTALK].Content.AgentId,
"agent_id": models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId)].Content.AgentId,
"msg": map[string]interface{}{
"msgtype": "markdown",
"markdown": map[string]interface{}{
@@ -49,7 +49,7 @@ func (dingSender *SDingTalkSender) Send(args api.SendParams) error {
"userid_list": args.Receivers.Contact,
}
params := url.Values{}
params.Set("access_token", models.ConfigMap[api.DINGTALK].Content.AccessToken)
params.Set("access_token", models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId)].Content.AccessToken)
req, err := sendRequest(ApiDingtalkSendMessage, httputils.POST, nil, params, jsonutils.Marshal(body))
if err != nil {
subCode, _ := req.GetString("sub_code")
@@ -57,13 +57,13 @@ func (dingSender *SDingTalkSender) Send(args api.SendParams) error {
// token失效或不合法
case "40014":
// 尝试重新获取token
err = dingSender.GetAccessToken()
err = dingSender.GetAccessToken(fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId))
if err != nil {
return errors.Wrap(err, "reset token")
}
// 重新发送通知
params = url.Values{}
params.Set("access_token", models.ConfigMap[api.DINGTALK].Content.AccessToken)
params.Set("access_token", models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId)].Content.AccessToken)
req, err = sendRequest(ApiDingtalkSendMessage, httputils.POST, nil, params, jsonutils.Marshal(body))
if err != nil {
return errors.Wrap(err, "dingtalk resend message")
@@ -77,7 +77,7 @@ func (dingSender *SDingTalkSender) Send(args api.SendParams) error {
// 获取消息通知发送结果
task_id, _ := req.GetString("task_id")
body = map[string]interface{}{
"agent_id": models.ConfigMap[api.DINGTALK].Content.AgentId,
"agent_id": models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId)].Content.AgentId,
"task_id": task_id,
}
_, err = sendRequest(ApiDingtalkSendMessage, httputils.POST, nil, params, jsonutils.Marshal(body))
@@ -93,12 +93,12 @@ func (dingSender *SDingTalkSender) ValidateConfig(config api.NotifyConfig) (stri
}
return "", err
}
models.ConfigMap[api.DINGTALK].Content.AppKey, models.ConfigMap[api.DINGTALK].Content.AppSecret = config.AppKey, config.AppSecret
models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, config.DomainId)].Content.AppKey, models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, config.DomainId)].Content.AppSecret = config.AppKey, config.AppSecret
return "", nil
}
func (dingSender *SDingTalkSender) ContactByMobile(mobile, domainId string) (string, error) {
err := dingSender.GetAccessToken()
err := dingSender.GetAccessToken(fmt.Sprintf("%s-%s", api.DINGTALK, domainId))
if err != nil {
return "", err
}
@@ -106,7 +106,7 @@ func (dingSender *SDingTalkSender) ContactByMobile(mobile, domainId string) (str
"mobile": mobile,
})
params := url.Values{}
params.Set("access_token", models.ConfigMap[api.DINGTALK].Content.AccessToken)
params.Set("access_token", models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, domainId)].Content.AccessToken)
res, err := sendRequest(ApiDingtalkGetUserByMobile, httputils.POST, nil, params, body)
if err != nil {
return "", errors.Wrap(err, "get user by mobile")
@@ -134,13 +134,13 @@ func (dingSender *SDingTalkSender) IsSystemConfigContactType() bool {
return true
}
func (dingSender *SDingTalkSender) GetAccessToken() error {
appKey, appSecret := models.ConfigMap[api.DINGTALK].Content.AppKey, models.ConfigMap[api.DINGTALK].Content.AppSecret
func (dingSender *SDingTalkSender) GetAccessToken(key string) error {
appKey, appSecret := models.ConfigMap[key].Content.AppKey, models.ConfigMap[key].Content.AppSecret
token, err := dingSender.getAccessToken(appKey, appSecret)
if err != nil {
return errors.Wrap(err, "dingtalk getAccessToken")
}
models.ConfigMap[api.DINGTALK].Content.AccessToken = token
models.ConfigMap[key].Content.AccessToken = token
return nil
}
+1 -1
View File
@@ -99,7 +99,7 @@ func (dingRobotSender *SDingTalkRobotSender) IsSystemConfigContactType() bool {
return true
}
func (dingRobotSender *SDingTalkRobotSender) GetAccessToken() error {
func (dingRobotSender *SDingTalkRobotSender) GetAccessToken(key string) error {
return nil
}
+1 -19
View File
@@ -187,28 +187,10 @@ func (emailSender *SEmailSender) IsSystemConfigContactType() bool {
return true
}
func (emailSender *SEmailSender) GetAccessToken() error {
corpId, secret := models.ConfigMap[api.WORKWX].Content.CorpId, models.ConfigMap[api.WORKWX].Content.Secret
token, err := emailSender.getAccessToken(corpId, secret)
if err != nil {
return errors.Wrap(err, "workwx getAccessToken")
}
models.ConfigMap[api.WORKWX].Content.AccessToken = token
func (emailSender *SEmailSender) GetAccessToken(key string) error {
return nil
}
func (emailSender *SEmailSender) getAccessToken(corpId, secret string) (string, error) {
// url := ApiWorkwxGetToken + fmt.Sprintf("?corpid=%s&corpsecret=%s", corpId, secret)
params := url.Values{}
params.Set("corpid", corpId)
params.Set("corpsecret", secret)
res, err := sendRequest(ApiWorkwxGetToken, httputils.GET, nil, params, nil)
if err != nil {
return "", errors.Wrap(err, "get workwx token")
}
return res.GetString("access_token")
}
func (emailSender *SEmailSender) sendMessageWithToken(uri string, method httputils.THttpMethod, header http.Header, params url.Values, body jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if params == nil {
params = url.Values{}
+13 -10
View File
@@ -48,20 +48,23 @@ func (feishuSender *SFeishuSender) Send(args api.SendParams) error {
},
} // 添加bearer token请求头
header := http.Header{}
header.Add("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[api.FEISHU].Content.AccessToken))
req, err := sendRequest(ApiSendMessageForFeishuByOpenId, httputils.POST, header, nil, jsonutils.Marshal(body))
header.Add("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[fmt.Sprintf("%s-%s", api.FEISHU, args.DomainId)].Content.AccessToken))
rep, err := sendRequest(ApiSendMessageForFeishuByOpenId, httputils.POST, header, nil, jsonutils.Marshal(body))
if err == nil {
return nil
}
// 发送通知失败的情况
code, _ := req.GetString("code")
code, err := rep.GetString("code")
if err != nil {
return err
}
switch code {
case "99991663": //token过期
err = feishuSender.GetAccessToken()
err = feishuSender.GetAccessToken(fmt.Sprintf("%s-%s", api.FEISHU, args.DomainId))
if err != nil {
return errors.Wrap(err, "tenant token invalid && getToken err")
}
header.Set("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[api.FEISHU].Content.AccessToken))
header.Set("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[fmt.Sprintf("%s-%s", api.FEISHU, args.DomainId)].Content.AccessToken))
_, err = sendRequest(ApiSendMessageForFeishuByOpenId, httputils.POST, header, nil, jsonutils.Marshal(body))
if err == nil {
return nil
@@ -95,7 +98,7 @@ func (feishuSender *SFeishuSender) ContactByMobile(mobile, domainId string) (str
body.Set("mobiles", jsonutils.NewArray(jsonutils.NewString(mobile)))
header := http.Header{}
// 考虑到获取用户id需求较少,可通过直接更新token来避免token失效
err := feishuSender.GetAccessToken()
err := feishuSender.GetAccessToken(fmt.Sprintf("%s-%s", api.FEISHU, domainId))
if err != nil {
return "", errors.Wrap(err, "GetAccessToken")
}
@@ -103,7 +106,7 @@ func (feishuSender *SFeishuSender) ContactByMobile(mobile, domainId string) (str
params := url.Values{}
params.Set("mobiles", mobile)
header.Set("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[api.FEISHU].Content.AccessToken))
header.Set("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[fmt.Sprintf("%s-%s", api.FEISHU, domainId)].Content.AccessToken))
resp, err := sendRequest(ApiFetchUserID, httputils.GET, header, params, body)
if err != nil {
return "", err
@@ -141,10 +144,10 @@ func (feishuSender *SFeishuSender) IsSystemConfigContactType() bool {
}
// 获取token
func (feishuSender *SFeishuSender) GetAccessToken() error {
appId, appSecret := models.ConfigMap[api.FEISHU].Content.AppId, models.ConfigMap[api.FEISHU].Content.AppSecret
func (feishuSender *SFeishuSender) GetAccessToken(key string) error {
appId, appSecret := models.ConfigMap[key].Content.AppId, models.ConfigMap[key].Content.AppSecret
resp, err := feishuSender.getAccessToken(appId, appSecret)
models.ConfigMap[api.FEISHU].Content.AccessToken = resp.TenantAccessToken
models.ConfigMap[key].Content.AccessToken = resp.TenantAccessToken
return err
}
+1 -1
View File
@@ -101,7 +101,7 @@ func (feishuRobotSender *SFeishuRobotSender) IsSystemConfigContactType() bool {
return true
}
func (feishuRobotSender *SFeishuRobotSender) GetAccessToken() error {
func (feishuRobotSender *SFeishuRobotSender) GetAccessToken(key string) error {
return nil
}
+1 -1
View File
@@ -102,7 +102,7 @@ func (smsSender *SMobileSender) IsSystemConfigContactType() bool {
return true
}
func (smsSender *SMobileSender) GetAccessToken() error {
func (smsSender *SMobileSender) GetAccessToken(key string) error {
return nil
}
+1 -36
View File
@@ -29,41 +29,6 @@ func (self *SWebconsoleSender) GetSenderType() string {
}
func (self *SWebconsoleSender) Send(args api.SendParams) error {
// var token string
// var errs []error
// title, msg := args.Title, args.Message
// // for _, recevier := range args.Receivers {
// webhook := args.Receivers.Contact
// switch {
// case strings.HasPrefix(webhook, ApiWebhookRobotV2SendMessage):
// token = webhook[len(ApiWebhookRobotV2SendMessage):]
// case strings.HasPrefix(webhook, feishu.ApiWebhookRobotSendMessage):
// token = webhook[len(feishu.ApiWebhookRobotSendMessage):]
// default:
// return errors.Wrap(InvalidWebhook, webhook)
// }
// req := feishu.WebhookRobotMsgReq{
// Title: title,
// Text: msg,
// }
// rep, err := feishu.SendWebhookRobotMessage(token, req)
// if err != nil {
// return errors.Wrap(err, "SendWebhookRobotMessage")
// }
// if !rep.Ok {
// if strings.Contains(rep.Error, "token") {
// return ErrNoSuchWebhook
// } else {
// return fmt.Errorf("SendWebhookRobotMessage failed: %s", rep.Error)
// }
// }
// if err != nil {
// if errs == nil {
// errs = []error{}
// }
// errs = append(errs, err)
// }
// return errors.NewAggregate(errs)
return nil
}
@@ -107,7 +72,7 @@ func (websender *SWebconsoleSender) IsSystemConfigContactType() bool {
return true
}
func (websender *SWebconsoleSender) GetAccessToken() error {
func (websender *SWebconsoleSender) GetAccessToken(key string) error {
return nil
}
+1 -1
View File
@@ -92,7 +92,7 @@ func (websender *SWebhookSender) IsSystemConfigContactType() bool {
return true
}
func (websender *SWebhookSender) GetAccessToken() error {
func (websender *SWebhookSender) GetAccessToken(key string) error {
return nil
}
+1 -1
View File
@@ -105,7 +105,7 @@ func (websocket *SWebsocketSender) ContactByMobile(mobile, domainId string) (str
return "", nil
}
func (websocket *SWebsocketSender) GetAccessToken() error {
func (websocket *SWebsocketSender) GetAccessToken(key string) error {
return nil
}
+9 -9
View File
@@ -38,14 +38,14 @@ func (workwxSender *SWorkwxSender) GetSenderType() string {
func (workwxSender *SWorkwxSender) Send(args api.SendParams) error {
body := map[string]interface{}{
"agentid": models.ConfigMap[api.WORKWX].Content.AgentId,
"agentid": models.ConfigMap[fmt.Sprintf("%s-%s", api.WORKWX, args.DomainId)].Content.AgentId,
"msgtype": "markdown",
"markdown": map[string]interface{}{
"content": fmt.Sprintf("# %s\n\n%s", args.Title, args.Message),
},
"touser": args.Receivers.Contact,
}
_, err := workwxSender.sendMessageWithToken(ApiWorkwxSendMessage, httputils.POST, nil, nil, jsonutils.Marshal(body))
_, err := workwxSender.sendMessageWithToken(ApiWorkwxSendMessage, fmt.Sprintf("%s-%s", api.WORKWX, args.DomainId), httputils.POST, nil, nil, jsonutils.Marshal(body))
if err != nil {
return errors.Wrap(err, "workwx send message")
}
@@ -69,14 +69,14 @@ func (workwxSender *SWorkwxSender) ValidateConfig(config api.NotifyConfig) (stri
}
func (workwxSender *SWorkwxSender) ContactByMobile(mobile, domainId string) (string, error) {
err := workwxSender.GetAccessToken()
err := workwxSender.GetAccessToken(fmt.Sprintf("%s-%s", api.WORKWX, domainId))
if err != nil {
return "", err
}
body := jsonutils.Marshal(map[string]interface{}{
"mobile": mobile,
})
res, err := workwxSender.sendMessageWithToken(ApiWorkwxGetUserByMobile, httputils.POST, nil, nil, jsonutils.Marshal(body))
res, err := workwxSender.sendMessageWithToken(ApiWorkwxGetUserByMobile, fmt.Sprintf("%s-%s", api.WORKWX, domainId), httputils.POST, nil, nil, jsonutils.Marshal(body))
if err != nil {
return "", errors.Wrap(err, "get user by mobile")
}
@@ -103,13 +103,13 @@ func (workwxSender *SWorkwxSender) IsSystemConfigContactType() bool {
return true
}
func (workwxSender *SWorkwxSender) GetAccessToken() error {
corpId, secret := models.ConfigMap[api.WORKWX].Content.CorpId, models.ConfigMap[api.WORKWX].Content.Secret
func (workwxSender *SWorkwxSender) GetAccessToken(key string) error {
corpId, secret := models.ConfigMap[key].Content.CorpId, models.ConfigMap[key].Content.Secret
token, err := workwxSender.getAccessToken(corpId, secret)
if err != nil {
return errors.Wrap(err, "workwx getAccessToken")
}
models.ConfigMap[api.WORKWX].Content.AccessToken = token
models.ConfigMap[key].Content.AccessToken = token
return nil
}
@@ -125,11 +125,11 @@ func (workwxSender *SWorkwxSender) getAccessToken(corpId, secret string) (string
return res.GetString("access_token")
}
func (workwxSender *SWorkwxSender) sendMessageWithToken(uri string, method httputils.THttpMethod, header http.Header, params url.Values, body jsonutils.JSONObject) (jsonutils.JSONObject, error) {
func (workwxSender *SWorkwxSender) sendMessageWithToken(uri, key string, method httputils.THttpMethod, header http.Header, params url.Values, body jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if params == nil {
params = url.Values{}
}
params.Set("access_token", models.ConfigMap[api.WORKWX].Content.AccessToken)
params.Set("access_token", models.ConfigMap[key].Content.AccessToken)
return sendRequest(uri, httputils.POST, nil, params, jsonutils.Marshal(body))
}
+1 -1
View File
@@ -84,7 +84,7 @@ func (workwxRobotSender *SWorkwxRobotSender) IsSystemConfigContactType() bool {
return true
}
func (workwxRobotSender *SWorkwxRobotSender) GetAccessToken() error {
func (workwxRobotSender *SWorkwxRobotSender) GetAccessToken(key string) error {
return nil
}
@@ -213,6 +213,7 @@ func (self *NotificationSendTask) OnInit(ctx context.Context, obj db.IStandalone
p.Message += "\nfrom " + options.Options.ApiServer
}
p.DomainId = self.UserCred.GetDomainId()
// set status before send
now := time.Now()
for _, rn := range receivers {
+122 -53
View File
@@ -41,6 +41,19 @@ var PullContactType = []string{
apis.WORKWX,
}
var UserContactType = []string{
apis.EMAIL,
apis.MOBILE,
}
var allContactTypes = []string{
apis.DINGTALK,
apis.FEISHU,
apis.WORKWX,
apis.EMAIL,
apis.MOBILE,
}
type SubcontactPullTask struct {
taskman.STask
}
@@ -82,67 +95,123 @@ func (self *SubcontactPullTask) OnInit(ctx context.Context, obj db.IStandaloneMo
if self.Params.Contains("contact_types") {
jArray, _ := self.Params.Get("contact_types")
contactTypes = jArray.(*jsonutils.JSONArray).GetStringArray()
} else {
contactTypes, _ = receiver.GetEnabledContactTypes()
}
for _, cType := range contactTypes {
if !utils.IsInStringArray(cType, PullContactType) {
continue
}
content := ""
switch cType {
case apis.EMAIL:
content = receiver.Email
default:
driver := models.GetDriver(cType)
content, err = driver.ContactByMobile(mobile, "")
}
if err != nil {
var reason string
if errors.Cause(err) == apis.ErrNoSuchMobile {
receiver.MarkContactTypeUnVerified(ctx, cType, apis.ErrNoSuchMobile.Error())
reason = fmt.Sprintf("%q: no such mobile %s", cType, receiver.Mobile)
} else if errors.Cause(err) == apis.ErrIncompleteConfig {
receiver.MarkContactTypeUnVerified(ctx, cType, apis.ErrIncompleteConfig.Error())
reason = fmt.Sprintf("%q: %v", cType, err)
// 遍历所有通知渠道
for _, contactType := range allContactTypes {
// 若该渠道在输入渠道内,则设为enable
if utils.IsInStringArray(contactType, contactTypes) {
// 常规渠道
if utils.IsInStringArray(contactType, PullContactType) {
content := ""
driver := models.GetDriver(contactType)
content, err = driver.ContactByMobile(mobile, self.UserCred.GetDomainId())
if err != nil {
var reason string
if errors.Cause(err) == apis.ErrNoSuchMobile {
receiver.MarkContactTypeUnVerified(ctx, contactType, apis.ErrNoSuchMobile.Error())
reason = fmt.Sprintf("%q: no such mobile %s", contactType, receiver.Mobile)
} else if errors.Cause(err) == apis.ErrIncompleteConfig {
receiver.MarkContactTypeUnVerified(ctx, contactType, apis.ErrIncompleteConfig.Error())
reason = fmt.Sprintf("%q: %v", contactType, err)
} else {
receiver.MarkContactTypeUnVerified(ctx, contactType, "service exceptions")
reason = fmt.Sprintf("%q: %v", contactType, err)
}
failedReasons = append(failedReasons, reason)
continue
}
subcontact := []models.SSubContact{}
q := models.SubContactManager.Query()
cond := sqlchemy.AND(sqlchemy.Equals(q.Field("receiver_id"), receiver.Id), sqlchemy.Equals(q.Field("type"), contactType))
q.Filter(cond)
err = db.FetchModelObjects(models.SubContactManager, q, &subcontact)
if err != nil {
failedReasons = append(failedReasons, err.Error())
continue
}
subid := ""
if len(subcontact) > 0 {
subid = subcontact[0].Id
}
err = models.SubContactManager.TableSpec().InsertOrUpdate(ctx, &models.SSubContact{
SStandaloneResourceBase: db.SStandaloneResourceBase{
SStandaloneAnonResourceBase: db.SStandaloneAnonResourceBase{Id: subid},
},
ReceiverID: receiver.Id,
Type: contactType,
Contact: content,
ParentContactType: "mobile",
Enabled: tristate.True,
})
if err != nil {
failedReasons = append(failedReasons, err.Error())
continue
}
receiver.SetContact(contactType, content)
receiver.MarkContactTypeVerified(ctx, contactType)
} else {
receiver.MarkContactTypeUnVerified(ctx, cType, "service exceptions")
reason = fmt.Sprintf("%q: %v", cType, err)
_, err := db.Update(receiver, func() error {
if contactType == apis.MOBILE {
receiver.EnabledMobile = tristate.True
}
if contactType == apis.EMAIL {
receiver.EnabledEmail = tristate.True
}
return nil
})
if err != nil {
failedReasons = append(failedReasons, err.Error())
continue
}
}
failedReasons = append(failedReasons, reason)
continue
} else {
q := models.SubContactManager.Query()
cond := sqlchemy.AND(sqlchemy.Equals(q.Field("receiver_id"), receiver.Id), sqlchemy.Equals(q.Field("type"), cType))
q.Filter(cond)
subcontact := []models.SSubContact{}
err := db.FetchModelObjects(models.SubContactManager, q, &subcontact)
if err != nil {
failedReasons = append(failedReasons, err.Error())
continue
}
subid := ""
if len(subcontact) > 0 {
subid = subcontact[0].Id
}
err = models.SubContactManager.TableSpec().InsertOrUpdate(ctx, &models.SSubContact{
SStandaloneResourceBase: db.SStandaloneResourceBase{
SStandaloneAnonResourceBase: db.SStandaloneAnonResourceBase{Id: subid},
},
ReceiverID: receiver.Id,
Type: cType,
Contact: content,
ParentContactType: "mobile",
Enabled: tristate.True,
})
if err != nil {
log.Errorln("this is err:", err)
// 若该渠道在输入渠道内,则设为disable
if utils.IsInStringArray(contactType, PullContactType) {
subcontact := []models.SSubContact{}
q := models.SubContactManager.Query()
cond := sqlchemy.AND(sqlchemy.Equals(q.Field("receiver_id"), receiver.Id), sqlchemy.Equals(q.Field("type"), contactType))
q.Filter(cond)
err = db.FetchModelObjects(models.SubContactManager, q, &subcontact)
if err != nil {
failedReasons = append(failedReasons, err.Error())
continue
}
subid := ""
if len(subcontact) > 0 {
subid = subcontact[0].Id
}
err = models.SubContactManager.TableSpec().InsertOrUpdate(ctx, &models.SSubContact{
SStandaloneResourceBase: db.SStandaloneResourceBase{
SStandaloneAnonResourceBase: db.SStandaloneAnonResourceBase{Id: subid},
},
ReceiverID: receiver.Id,
Type: contactType,
ParentContactType: "mobile",
Enabled: tristate.False,
})
if err != nil {
failedReasons = append(failedReasons, err.Error())
continue
}
} else {
_, err := db.Update(receiver, func() error {
if contactType == apis.MOBILE {
receiver.EnabledMobile = tristate.False
}
if contactType == apis.EMAIL {
receiver.EnabledEmail = tristate.False
}
return nil
})
if err != nil {
failedReasons = append(failedReasons, err.Error())
continue
}
}
}
receiver.SetContact(cType, content)
receiver.MarkContactTypeVerified(ctx, cType)
}
if len(failedReasons) > 0 {
reason := strings.Join(failedReasons, "; ")
self.taskFailed(ctx, receiver, reason)