resourceChannel.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. package resourceChannel
  2. import (
  3. "encoding/json"
  4. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  5. "github.com/go-redis/redis"
  6. "golang.org/x/net/context"
  7. "log"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. func redisCli() *redis.Client {
  13. client := redis.NewClient(&redis.Options{
  14. //Addr: coo.RedisHost, // Redis地址
  15. Addr: "192.168.204.193:6379", // Redis地址
  16. Password: "", // Redis密码,默认为空
  17. DB: 1, // 使用哪个数据库,默认为0
  18. })
  19. _, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
  20. defer cancel()
  21. return client
  22. }
  23. type ResourceAssessment struct {
  24. ID uint `gorm:"primaryKey" json:"id"` // 留学评估表
  25. DataType uint8 `json:"data_type"` // 1.网课 2.api资源 3.专题页 4.工作台录入 5.后台录入 6 小程序
  26. ChatID string `json:"chat_id"` // 会话id
  27. Channel int `json:"channel"` // 渠道id
  28. Category int `json:"category"` // 分类id
  29. CreatedAt time.Time `json:"created_at"` // 数据创建时间
  30. ReferPageURL string `json:"refer_page_url"` // 来源网址
  31. URL string `json:"url"` // 落地页地址
  32. ChatURL string `json:"chat_url"` // 对话发起页
  33. GrUserId string `json:"gr_user_id"` // 神策distinct_id
  34. }
  35. type SemJsChatRecord struct {
  36. ChatID int64 `gorm:"column:CHAT_ID"`
  37. CreateTime time.Time `gorm:"column:CREATE_TIME"`
  38. ReferPage string `gorm:"type:text;column:REFER_PAGE"`
  39. ChatURL string `gorm:"type:text;column:CHAT_URL"`
  40. ChannleID int `gorm:"column:CHANNLE_ID"`
  41. CategoryID int `gorm:"column:CATEGORY_ID"`
  42. GrUserID string `gorm:"column:gr_user_id"`
  43. SourceUrl string `gorm:"column:source_url"`
  44. }
  45. type ChannelCategory struct {
  46. Channel int
  47. Category int
  48. }
  49. // GetChannel 表单渠道归因处理
  50. func GetChannel(assessment ResourceAssessment) ChannelCategory {
  51. log.Printf("%v", assessment)
  52. // 获取神策URL(不包含utm)
  53. cc, _ := redisCli().Get("website:" + assessment.GrUserId).Result()
  54. var websiteUrl SensorsData
  55. json.Unmarshal([]byte(cc), &websiteUrl)
  56. // 到梦解析
  57. 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")) {
  58. log.Printf("解析到梦")
  59. assessment.Channel = 38
  60. assessment.Category = getCategory(201)
  61. return ChannelCategory{assessment.Channel, assessment.Category}
  62. }
  63. // 网课解析
  64. if assessment.DataType == 1 {
  65. log.Printf("解析网课")
  66. assessment.Channel = 26
  67. assessment.Category = getCategory(121)
  68. return ChannelCategory{assessment.Channel, assessment.Category}
  69. }
  70. // 小程序解析
  71. if strings.Contains(assessment.ChatURL, "pages") && strings.Split(strings.Split(assessment.ChatURL, "?")[1], "=")[0] == "miniapp" && (strings.Contains(assessment.ChatURL, "baidu") || strings.Contains(assessment.ChatURL, "wechat")) {
  72. log.Printf("解析小程序")
  73. appType := strings.Split(strings.Split(strings.Split(assessment.ChatURL, "?")[1], "=")[1], "_")[1]
  74. if appType == "baidu" {
  75. assessment.Channel = 1
  76. assessment.Category = getCategory(30)
  77. } else if appType == "wechat" {
  78. assessment.Channel = 8
  79. assessment.Category = getCategory(32)
  80. }
  81. return ChannelCategory{assessment.Channel, assessment.Category}
  82. }
  83. // URL解析
  84. if strings.Contains(assessment.URL, "link=") || strings.Contains(assessment.ReferPageURL, "link=") || strings.Contains(assessment.ChatURL, "link=") {
  85. log.Printf("解析URL")
  86. if strings.Contains(assessment.URL, "link=") && len(strings.Split(strings.Split(assessment.URL, "link=")[1], "_")) == 3 {
  87. var category, _ = strconv.Atoi(strings.Split(strings.Split(assessment.URL, "link=")[1], "_")[1])
  88. if category > 10000 {
  89. assessment.Channel = category
  90. assessment.Category = category
  91. }
  92. } else if strings.Contains(assessment.ReferPageURL, "link=") && len(strings.Split(strings.Split(assessment.ReferPageURL, "link=")[1], "_")) == 3 {
  93. var category, _ = strconv.Atoi(strings.Split(strings.Split(assessment.ReferPageURL, "link=")[1], "_")[1])
  94. if category > 10000 {
  95. assessment.Channel = category
  96. assessment.Category = category
  97. }
  98. } else if strings.Contains(assessment.ChatURL, "link=") && len(strings.Split(strings.Split(assessment.ChatURL, "link=")[1], "_")) == 3 {
  99. var category, _ = strconv.Atoi(strings.Split(strings.Split(assessment.ChatURL, "link=")[1], "_")[1])
  100. if category > 10000 {
  101. assessment.Channel = category
  102. assessment.Category = category
  103. }
  104. } else {
  105. if strings.Contains(assessment.URL, "link=") {
  106. split := strings.Split(assessment.URL, "link")
  107. if strings.Contains(split[1], "form") || strings.Contains(split[1], "from") {
  108. assessment.Channel, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.URL, "link")[1], "form")[0], "_")[1])
  109. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.URL, "link")[1], "form")[0], "_")[2])
  110. assessment.Category = getCategory(category)
  111. } else {
  112. assessment.Channel = 5
  113. assessment.Category = getCategory(11)
  114. }
  115. } else if strings.Contains(assessment.ReferPageURL, "link=") {
  116. split := strings.Split(assessment.ReferPageURL, "link")
  117. if strings.Contains(split[1], "form") || strings.Contains(split[1], "from") {
  118. assessment.Channel, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ReferPageURL, "link")[1], "form")[0], "_")[1])
  119. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ReferPageURL, "link")[1], "form")[0], "_")[2])
  120. assessment.Category = getCategory(category)
  121. } else {
  122. assessment.Channel = 5
  123. assessment.Category = getCategory(11)
  124. }
  125. } else {
  126. split := strings.Split(assessment.ChatURL, "link")
  127. if strings.Contains(split[1], "form") || strings.Contains(split[1], "from") {
  128. assessment.Channel, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ChatURL, "link")[1], "form")[0], "_")[1])
  129. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ChatURL, "link")[1], "form")[0], "_")[2])
  130. assessment.Category = getCategory(category)
  131. } else {
  132. assessment.Channel = 5
  133. assessment.Category = getCategory(11)
  134. }
  135. }
  136. }
  137. // 百度惠生活渠道合并
  138. if assessment.Category == 239 {
  139. assessment.Category = getCategory(292)
  140. }
  141. return ChannelCategory{assessment.Channel, assessment.Category}
  142. }
  143. // 获取神策url(包含utm)
  144. cc1, _ := redisCli().Get("sensors:" + assessment.GrUserId).Result()
  145. var utmUrl SensorsData
  146. json.Unmarshal([]byte(cc1), &utmUrl)
  147. // 神策解析
  148. if utmUrl.Url != "" && !strings.Contains(assessment.URL, "link=") && !strings.Contains(assessment.ReferPageURL, "link=") && !strings.Contains(assessment.ChatURL, "link=") {
  149. log.Printf("解析神策")
  150. assessment.Channel = utmUrl.Channel
  151. assessment.Category = utmUrl.Category
  152. // 百度惠生活渠道合并
  153. if assessment.Category == 239 {
  154. assessment.Category = getCategory(292)
  155. }
  156. return ChannelCategory{assessment.Channel, assessment.Category}
  157. }
  158. // 搜索引擎SEO,外链解析
  159. if assessment.ReferPageURL != "" && !strings.Contains(assessment.ReferPageURL, "https://www.jjl.cn/") && !strings.Contains(assessment.ReferPageURL, "https://m.jjl.cn/") {
  160. log.Printf("解析SEO")
  161. assessment.Channel = 5
  162. assessment.Category = getCategory(11)
  163. return ChannelCategory{assessment.Channel, assessment.Category}
  164. }
  165. // 官网自然访问解析
  166. if strings.Contains(assessment.URL, "https://www.jjl.cn/") || strings.Contains(assessment.URL, "https://m.jjl.cn/") ||
  167. strings.Contains(assessment.ReferPageURL, "https://www.jjl.cn/") || strings.Contains(assessment.ReferPageURL, "https://m.jjl.cn/") ||
  168. strings.Contains(assessment.ChatURL, "https://www.jjl.cn/") || strings.Contains(assessment.ChatURL, "https://m.jjl.cn/") ||
  169. strings.Contains(utmUrl.Url, "https://www.jjl.cn/") || strings.Contains(utmUrl.Url, "https://m.jjl.cn/") {
  170. log.Printf("解析官网")
  171. assessment.Channel = 7
  172. assessment.Category = getCategory(126)
  173. return ChannelCategory{assessment.Channel, assessment.Category}
  174. }
  175. log.Printf("默认解析为SEO")
  176. assessment.Channel = 5
  177. assessment.Category = getCategory(11)
  178. return ChannelCategory{assessment.Channel, assessment.Category}
  179. }
  180. // GetChatChannel 会话渠道归因处理
  181. func GetChatChannel(chat SemJsChatRecord) ChannelCategory {
  182. log.Printf("%v", chat)
  183. // 获取神策URL(不包含utm)
  184. cc, _ := redisCli().Get("website:" + chat.GrUserID).Result()
  185. var websiteUrl SensorsData
  186. json.Unmarshal([]byte(cc), &websiteUrl)
  187. // 小程序解析
  188. if strings.Contains(chat.ChatURL, "pages") && strings.Split(strings.Split(chat.ChatURL, "?")[1], "=")[0] == "miniapp" && (strings.Contains(chat.ChatURL, "baidu") || strings.Contains(chat.ChatURL, "wechat")) {
  189. log.Printf("小程序解析")
  190. log.Printf(chat.ChatURL)
  191. appType := strings.Split(strings.Split(strings.Split(chat.ChatURL, "?")[1], "=")[1], "_")[1]
  192. if appType == "baidu" {
  193. chat.ChannleID = 1
  194. chat.CategoryID = getCategory(30)
  195. } else if appType == "wechat" {
  196. chat.ChannleID = 8
  197. chat.CategoryID = getCategory(32)
  198. }
  199. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  200. }
  201. // 到梦解析
  202. if !strings.Contains(chat.ReferPage, "utm") && !strings.Contains(chat.ChatURL, "utm") && (strings.Contains(chat.ReferPage, "daomeng") || strings.Contains(chat.ChatURL, "daomeng")) {
  203. log.Printf("到梦解析")
  204. chat.ChannleID = 38
  205. chat.CategoryID = getCategory(201)
  206. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  207. }
  208. // URL解析
  209. if strings.Contains(chat.ChatURL, "link=") || strings.Contains(chat.ReferPage, "link=") {
  210. log.Printf("解析CHATURL")
  211. if strings.Contains(chat.ChatURL, "link=") && len(strings.Split(strings.Split(chat.ChatURL, "link=")[1], "_")) == 3 {
  212. var category, _ = strconv.Atoi(strings.Split(strings.Split(chat.ChatURL, "link=")[1], "_")[1])
  213. if category > 10000 {
  214. chat.ChannleID = category
  215. chat.CategoryID = category
  216. }
  217. } else if strings.Contains(chat.ReferPage, "link=") && len(strings.Split(strings.Split(chat.ReferPage, "link=")[1], "_")) == 3 {
  218. var category, _ = strconv.Atoi(strings.Split(strings.Split(chat.ReferPage, "link=")[1], "_")[1])
  219. if category > 10000 {
  220. chat.ChannleID = category
  221. chat.CategoryID = category
  222. }
  223. } else {
  224. if strings.Contains(chat.ChatURL, "link=") {
  225. split := strings.Split(chat.ChatURL, "link=")
  226. if strings.Contains(split[1], "form") || strings.Contains(split[1], "from") {
  227. chat.ChannleID, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ChatURL, "link")[1], "form")[0], "_")[1])
  228. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ChatURL, "link")[1], "form")[0], "_")[2])
  229. chat.CategoryID = getCategory(category)
  230. } else {
  231. chat.ChannleID = 5
  232. chat.CategoryID = getCategory(11)
  233. }
  234. } else {
  235. split := strings.Split(chat.ReferPage, "link=")
  236. if strings.Contains(split[01], "form") || strings.Contains(split[1], "from") {
  237. chat.ChannleID, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ReferPage, "link")[1], "form")[0], "_")[1])
  238. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ReferPage, "link")[1], "form")[0], "_")[2])
  239. chat.CategoryID = getCategory(category)
  240. } else {
  241. chat.ChannleID = 5
  242. chat.CategoryID = getCategory(11)
  243. }
  244. }
  245. }
  246. // 百度惠生活渠道合并
  247. if chat.CategoryID == 239 {
  248. chat.CategoryID = getCategory(292)
  249. }
  250. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  251. }
  252. // 获取神策url(包含utm)
  253. cc1, _ := redisCli().Get("sensors:" + chat.GrUserID).Result()
  254. var utmUrl SensorsData
  255. json.Unmarshal([]byte(cc1), &utmUrl)
  256. // 神策解析
  257. if utmUrl.Url != "" && utmUrl.Channel > 0 && !strings.Contains(chat.ReferPage, "link=") && !strings.Contains(chat.ChatURL, "link=") {
  258. log.Printf("解析神策")
  259. chat.ChannleID = utmUrl.Channel
  260. chat.CategoryID = utmUrl.Category
  261. // 百度惠生活渠道合并
  262. if chat.CategoryID == 239 {
  263. chat.CategoryID = getCategory(292)
  264. }
  265. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  266. }
  267. // 搜索引擎SEO,外链解析
  268. if chat.ReferPage != "" && !strings.Contains(chat.ReferPage, "https://www.jjl.cn/") && !strings.Contains(chat.ReferPage, "https://m.jjl.cn/") {
  269. log.Printf("解析SEO")
  270. chat.ChannleID = 5
  271. chat.CategoryID = getCategory(11)
  272. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  273. }
  274. // 官网自然访问解析
  275. if strings.Contains(chat.ReferPage, "https://www.jjl.cn/") || strings.Contains(chat.ReferPage, "https://m.jjl.cn/") ||
  276. strings.Contains(chat.ChatURL, "https://www.jjl.cn/") || strings.Contains(chat.ChatURL, "https://m.jjl.cn/") ||
  277. strings.Contains(utmUrl.Url, "https://www.jjl.cn/") || strings.Contains(utmUrl.Url, "https://m.jjl.cn/") {
  278. log.Printf("解析官网")
  279. chat.ChannleID = 7
  280. chat.CategoryID = getCategory(126)
  281. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  282. }
  283. log.Printf("默认解析为SEO")
  284. chat.ChannleID = 5
  285. chat.CategoryID = getCategory(11)
  286. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  287. }
  288. type SensorsData struct {
  289. DistinctId string `json:"distinctID"`
  290. Channel int `json:"channel"`
  291. Category int `json:"category"`
  292. Url string `json:"url"`
  293. }
  294. type SysChannel struct {
  295. OriginalCategory string `json:"original_category"` // 主键ID
  296. CategoryId string `json:"category_id"` // 备注
  297. }
  298. func getCategory(OriginalCategory int) int {
  299. endpoint := "oss-cn-beijing.aliyuncs.com" // 例如 "oss-cn-hangzhou.aliyuncs.com"
  300. accessKeyID := "LTAI5t7iAtrYaUgGgK8ws54e"
  301. accessKeySecret := "j4A6llCRqZBMzXLQ7ms84LdKl9l0IS"
  302. bucketName := "jjl-prod-bucket"
  303. objectName := "channel/category_mapper.json"
  304. client, err := oss.New(endpoint, accessKeyID, accessKeySecret)
  305. if err != nil {
  306. log.Fatalf("创建OSS客户端失败: %v", err)
  307. }
  308. // 获取存储空间
  309. bucket, err := client.Bucket(bucketName)
  310. if err != nil {
  311. log.Fatalf("获取Bucket失败: %v", err)
  312. }
  313. // 获取对象
  314. body, err := bucket.GetObject(objectName)
  315. if err != nil {
  316. log.Fatalf("获取对象失败: %v", err)
  317. }
  318. defer body.Close()
  319. // 读取对象内容
  320. var channel []SysChannel
  321. decoder := json.NewDecoder(body)
  322. if err := decoder.Decode(&channel); err != nil {
  323. log.Fatalf("解析JSON失败: %v", err)
  324. }
  325. for i := range channel {
  326. ori, _ := strconv.Atoi(channel[i].OriginalCategory)
  327. if ori == OriginalCategory {
  328. category, _ := strconv.Atoi(channel[i].CategoryId)
  329. return category
  330. }
  331. }
  332. return -1
  333. }