package resourceChannel import ( "encoding/json" "github.com/bilibili/gengine/builder" gengineContext "github.com/bilibili/gengine/context" "github.com/bilibili/gengine/engine" "github.com/go-redis/redis" "golang.org/x/net/context" "strconv" "strings" "time" ) func redisCli() *redis.Client { client := redis.NewClient(&redis.Options{ Addr: "192.168.204.180:3377", // Redis地址 Password: "", // Redis密码,默认为空 DB: 1, // 使用哪个数据库,默认为0 }) _, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) defer cancel() return client } type ResourceAssessment struct { ID uint `gorm:"primaryKey" json:"id"` // 留学评估表 DataType uint8 `json:"data_type"` // 1.网课 2.api资源 3.专题页 4.工作台录入 5.后台录入 6 小程序 ChatID string `json:"chat_id"` // 会话id Channel int `json:"channel"` // 渠道id Category int `json:"category"` // 分类id CreatedAt time.Time `json:"created_at"` // 数据创建时间 ReferPageURL string `json:"refer_page_url"` // 来源网址 URL string `json:"url"` // 落地页地址 ChatURL string `json:"chat_url"` // 对话发起页 GrUserId string `json:"gr_user_id"` // 神策distinct_id } type SemJsChatRecord struct { ChatID int64 `gorm:"column:CHAT_ID"` CreateTime time.Time `gorm:"column:CREATE_TIME"` ReferPage string `gorm:"type:text;column:REFER_PAGE"` ChatURL string `gorm:"type:text;column:CHAT_URL"` ChannleID int `gorm:"column:CHANNLE_ID"` CategoryID int `gorm:"column:CATEGORY_ID"` GrUserID string `gorm:"column:gr_user_id"` } type ChannelCategory struct { Channel int Category int } // AssessmentAnalysisRule 表单解析 func (a ResourceAssessment) AssessmentAnalysisRule(assessment *ResourceAssessment) { // 获取神策URL(不包含utm) cc, _ := redisCli().Get("website:" + assessment.GrUserId).Result() var websiteUrl SensorsData json.Unmarshal([]byte(cc), &websiteUrl) // 获取神策url(包含utm) cc1, _ := redisCli().Get("sensors:" + assessment.GrUserId).Result() var utmUrl SensorsData json.Unmarshal([]byte(cc1), &utmUrl) // 到梦解析 if !strings.Contains(assessment.URL, "utm") && !strings.Contains(assessment.ChatURL, "utm") && !strings.Contains(assessment.ReferPageURL, "utm") && (strings.Contains(assessment.ReferPageURL, "daomeng") || strings.Contains(assessment.ChatURL, "daomeng")) { println("解析到梦") assessment.Channel = 38 assessment.Category = 201 return } // 网课解析 if assessment.DataType == 1 { println("解析网课") assessment.Channel = 26 assessment.Category = 121 return } // 小程序解析 if strings.Contains(assessment.ChatURL, "pages") && strings.Split(strings.Split(assessment.ChatURL, "?")[1], "=")[0] == "miniapp" { println("解析小程序") appType := strings.Split(strings.Split(strings.Split(assessment.ChatURL, "?")[1], "=")[1], "_")[1] if appType == "baidu" { assessment.Channel = 1 assessment.Category = 30 } else if appType == "wechat" { assessment.Channel = 8 assessment.Category = 32 } return } // URL解析 if strings.Contains(assessment.URL, "link") || strings.Contains(assessment.ReferPageURL, "link") || strings.Contains(assessment.ChatURL, "link") { println("解析URL") if strings.Contains(assessment.URL, "link") { assessment.Channel, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.URL, "link")[1], "form")[0], "_")[1]) assessment.Category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.URL, "link")[1], "form")[0], "_")[2]) } else if strings.Contains(assessment.ReferPageURL, "link") { assessment.Channel, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ReferPageURL, "link")[1], "form")[0], "_")[1]) assessment.Category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ReferPageURL, "link")[1], "form")[0], "_")[2]) } else { assessment.Channel, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ChatURL, "link")[1], "form")[0], "_")[1]) assessment.Category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ChatURL, "link")[1], "form")[0], "_")[2]) } return } // 神策解析 if utmUrl.Url != "" && !strings.Contains(assessment.URL, "link") && !strings.Contains(assessment.ReferPageURL, "link") && !strings.Contains(assessment.ChatURL, "link") { println("解析神策") assessment.Channel = utmUrl.Channel assessment.Category = utmUrl.Category return } // 搜索引擎SEO,外链解析 if assessment.ReferPageURL != "" && !strings.Contains(assessment.ReferPageURL, "https://www.jjl.cn/") && !strings.Contains(assessment.ReferPageURL, "https://m.jjl.cn/") { println("解析SEO") assessment.Channel = 5 assessment.Category = 11 return } // 官网自然访问解析 if strings.Contains(assessment.URL, "https://www.jjl.cn/") || strings.Contains(assessment.URL, "https://m.jjl.cn/") || strings.Contains(assessment.ReferPageURL, "https://www.jjl.cn/") || strings.Contains(assessment.ReferPageURL, "https://m.jjl.cn/") || strings.Contains(assessment.ChatURL, "https://www.jjl.cn/") || strings.Contains(assessment.ChatURL, "https://m.jjl.cn/") || strings.Contains(utmUrl.Url, "https://www.jjl.cn/") || strings.Contains(utmUrl.Url, "https://m.jjl.cn/") { println("解析官网") assessment.Channel = 7 assessment.Category = 126 return } println("默认解析为SEO") assessment.Channel = 5 assessment.Category = 11 } // ChatAnalysisRule 表单解析规则 func (c SemJsChatRecord) ChatAnalysisRule(chat *SemJsChatRecord) { // 获取神策URL(不包含utm) cc, _ := redisCli().Get("website:" + chat.GrUserID).Result() var websiteUrl SensorsData json.Unmarshal([]byte(cc), &websiteUrl) // 获取神策url(包含utm) cc1, _ := redisCli().Get("sensors:" + chat.GrUserID).Result() var utmUrl SensorsData json.Unmarshal([]byte(cc1), &utmUrl) // 小程序解析 if strings.Contains(chat.ChatURL, "pages") && strings.Split(strings.Split(chat.ChatURL, "?")[1], "=")[0] == "miniapp" { println("小程序解析") appType := strings.Split(strings.Split(strings.Split(chat.ChatURL, "?")[1], "=")[1], "_")[1] if appType == "baidu" { chat.ChannleID = 1 chat.CategoryID = 30 } else if appType == "wechat" { chat.ChannleID = 8 chat.CategoryID = 32 } return } // 到梦解析 if !strings.Contains(chat.ReferPage, "utm") && !strings.Contains(chat.ChatURL, "utm") && (strings.Contains(chat.ReferPage, "daomeng") || strings.Contains(chat.ChatURL, "daomeng")) { println("到梦解析") chat.ChannleID = 38 chat.CategoryID = 201 return } // URL解析 if strings.Contains(chat.ChatURL, "link") || strings.Contains(chat.ReferPage, "link") { println("解析URL") if strings.Contains(chat.ChatURL, "link") { chat.ChannleID, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ChatURL, "link")[1], "form")[0], "_")[1]) chat.CategoryID, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ChatURL, "link")[1], "form")[0], "_")[2]) } else { chat.ChannleID, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ReferPage, "link")[1], "form")[0], "_")[1]) chat.ChannleID, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ReferPage, "link")[1], "form")[0], "_")[2]) } return } // 神策解析 if utmUrl.Url != "" && !strings.Contains(chat.ReferPage, "link") && !strings.Contains(chat.ChatURL, "link") { println("解析神策") chat.ChannleID = utmUrl.Channel chat.CategoryID = utmUrl.Category return } // 搜索引擎SEO,外链解析 if chat.ReferPage != "" && !strings.Contains(chat.ReferPage, "https://www.jjl.cn/") && !strings.Contains(chat.ReferPage, "https://m.jjl.cn/") { println("解析SEO") chat.ChannleID = 5 chat.CategoryID = 11 return } // 官网自然访问解析 if strings.Contains(chat.ReferPage, "https://www.jjl.cn/") || strings.Contains(chat.ReferPage, "https://m.jjl.cn/") || strings.Contains(chat.ChatURL, "https://www.jjl.cn/") || strings.Contains(chat.ChatURL, "https://m.jjl.cn/") || strings.Contains(utmUrl.Url, "https://www.jjl.cn/") || strings.Contains(utmUrl.Url, "https://m.jjl.cn/") { println("解析官网") chat.ChannleID = 7 chat.CategoryID = 126 return } println("默认解析为SEO") chat.ChannleID = 5 chat.CategoryID = 11 } const AssessmentAnalysisRule = ` rule "AssessmentAnalysisRule" "表单解析" salience 1 begin assessment.AssessmentAnalysisRule(assessment) end` const ChatAnalysisRule = ` rule "ChatAnalysisRule" "会话解析" salience 1 begin chat.ChatAnalysisRule(chat) end` // GetChannel 表单渠道归因处理 func GetChannel(assessment ResourceAssessment) ChannelCategory { dataContext := gengineContext.NewDataContext() dataContext.Add("assessment", &assessment) ruleBuilder := builder.NewRuleBuilder(dataContext) ruleBuilder.BuildRuleFromString(AssessmentAnalysisRule) engine := engine.NewGengine() engine.Execute(ruleBuilder, true) return ChannelCategory{assessment.Channel, assessment.Category} } // GetChatChannel 会话渠道归因处理 func GetChatChannel(chat SemJsChatRecord) ChannelCategory { dataContext := gengineContext.NewDataContext() dataContext.Add("chat", &chat) ruleBuilder := builder.NewRuleBuilder(dataContext) ruleBuilder.BuildRuleFromString(ChatAnalysisRule) engine := engine.NewGengine() engine.Execute(ruleBuilder, true) return ChannelCategory{chat.ChannleID, chat.CategoryID} } type SensorsData struct { DistinctId string `json:"distinctID"` Channel int `json:"channel"` Category int `json:"category"` Url string `json:"url"` } //func main() { // //var assessment []ResourceAssessment // //lib.GetDbInstance().Where("DATE(created_at) >= '2023-05-23' and id = 382346").Find(&assessment) // //for _, value := range assessment { // // cc := GetChannel(value) // // println(cc.Channel) // // println(cc.Category) // // println("END") // //} // // var chat []SemJsChatRecord // lib.GetDbInstance().Where("DATE(CREATE_TIME) >= '2023-01-01'").Find(&chat) // for _, value := range chat { // println(value.ChatID) // cc := GetChatChannel(value) // println(cc.Channel, cc.Category) // } //}