message.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. package controller
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/gin-gonic/gin"
  7. "message-pusher/channel"
  8. "message-pusher/common"
  9. "message-pusher/model"
  10. "net/http"
  11. "strconv"
  12. "time"
  13. )
  14. func GetPushMessage(c *gin.Context) {
  15. message := model.Message{
  16. Title: c.Query("title"),
  17. Description: c.Query("description"),
  18. Content: c.Query("content"),
  19. URL: c.Query("url"),
  20. Channel: c.Query("channel"),
  21. Token: c.Query("token"),
  22. To: c.Query("to"),
  23. }
  24. if message.Description == "" {
  25. // Keep compatible with ServerChan
  26. message.Description = c.Query("desp")
  27. }
  28. if message.Channel == "" {
  29. // Keep compatible with old version
  30. message.Channel = c.Query("type")
  31. }
  32. pushMessageHelper(c, &message)
  33. }
  34. func PostPushMessage(c *gin.Context) {
  35. message := model.Message{
  36. Title: c.PostForm("title"),
  37. Description: c.PostForm("description"),
  38. Content: c.PostForm("content"),
  39. URL: c.PostForm("url"),
  40. Channel: c.PostForm("channel"),
  41. Token: c.PostForm("token"),
  42. Desp: c.PostForm("desp"),
  43. To: c.PostForm("to"),
  44. }
  45. if message == (model.Message{}) {
  46. // Looks like the user is using JSON
  47. err := json.NewDecoder(c.Request.Body).Decode(&message)
  48. if err != nil {
  49. c.JSON(http.StatusOK, gin.H{
  50. "success": false,
  51. "message": "无法解析请求体,请检查其是否为合法 JSON",
  52. })
  53. return
  54. }
  55. }
  56. if message.Description == "" {
  57. message.Description = message.Desp
  58. }
  59. pushMessageHelper(c, &message)
  60. }
  61. func pushMessageHelper(c *gin.Context, message *model.Message) {
  62. user := model.User{Username: c.Param("username")}
  63. err := user.FillUserByUsername()
  64. if err != nil {
  65. c.JSON(http.StatusOK, gin.H{
  66. "success": false,
  67. "message": err.Error(),
  68. })
  69. return
  70. }
  71. if user.Status == common.UserStatusNonExisted {
  72. c.JSON(http.StatusOK, gin.H{
  73. "success": false,
  74. "message": "用户不存在",
  75. })
  76. return
  77. }
  78. if user.Status == common.UserStatusDisabled {
  79. c.JSON(http.StatusOK, gin.H{
  80. "success": false,
  81. "message": "用户已被封禁",
  82. })
  83. return
  84. }
  85. if user.Token != "" && user.Token != " " {
  86. if message.Token == "" {
  87. message.Token = c.Request.Header.Get("Authorization")
  88. if message.Token == "" {
  89. c.JSON(http.StatusOK, gin.H{
  90. "success": false,
  91. "message": "token 为空",
  92. })
  93. return
  94. }
  95. }
  96. if user.Token != message.Token {
  97. c.JSON(http.StatusOK, gin.H{
  98. "success": false,
  99. "message": "无效的 token",
  100. })
  101. return
  102. }
  103. }
  104. if message.Title == "" {
  105. message.Title = common.SystemName
  106. }
  107. if message.Channel == "" {
  108. message.Channel = user.Channel
  109. if message.Channel == "" {
  110. message.Channel = model.TypeEmail
  111. }
  112. }
  113. channel_, err := model.GetChannelByName(message.Channel, user.Id)
  114. if err != nil {
  115. c.JSON(http.StatusOK, gin.H{
  116. "success": false,
  117. "message": "无效的渠道名称:" + message.Channel,
  118. })
  119. return
  120. }
  121. err = saveAndSendMessage(&user, message, channel_)
  122. if err != nil {
  123. c.JSON(http.StatusOK, gin.H{
  124. "success": false,
  125. "message": err.Error(),
  126. })
  127. return
  128. }
  129. c.JSON(http.StatusOK, gin.H{
  130. "success": true,
  131. "message": "",
  132. })
  133. }
  134. func saveAndSendMessage(user *model.User, message *model.Message, channel_ *model.Channel) error {
  135. if channel_.Status != common.ChannelStatusEnabled {
  136. return errors.New("该渠道已被禁用")
  137. }
  138. message.Link = common.GetUUID()
  139. if message.URL == "" {
  140. message.URL = fmt.Sprintf("%s/message/%s", common.ServerAddress, message.Link)
  141. }
  142. success := false
  143. if common.MessagePersistenceEnabled || user.SaveMessageToDatabase == common.SaveMessageToDatabaseAllowed {
  144. defer func() {
  145. // Update the status of the message
  146. status := common.MessageSendStatusFailed
  147. if success {
  148. status = common.MessageSendStatusSent
  149. }
  150. err := message.UpdateStatus(status)
  151. if err != nil {
  152. common.SysError("failed to update the status of the message: " + err.Error())
  153. }
  154. }()
  155. err := message.UpdateAndInsert(user.Id)
  156. if err != nil {
  157. return err
  158. }
  159. } else {
  160. message.Link = "unsaved" // This is for user to identify whether the message is saved
  161. }
  162. err := channel.SendMessage(message, user, channel_)
  163. common.MessageCount += 1 // We don't need to use atomic here because it's not a critical value
  164. if err != nil {
  165. return err
  166. }
  167. success = true
  168. return nil // After this line, the message status will be updated
  169. }
  170. func GetStaticFile(c *gin.Context) {
  171. path := c.Param("file")
  172. c.FileFromFS("public/static/"+path, http.FS(common.FS))
  173. }
  174. func RenderMessage(c *gin.Context) {
  175. if !common.MessageRenderEnabled {
  176. c.HTML(http.StatusOK, "message.html", gin.H{
  177. "title": "无法渲染",
  178. "time": time.Now().Format("2006-01-02 15:04:05"),
  179. "description": "超级管理员禁用了消息渲染",
  180. "content": "很抱歉,您所使用的消息推送服务的管理员禁用了消息渲染功能,因此您的消息无法渲染。",
  181. })
  182. return
  183. }
  184. link := c.Param("link")
  185. if link == "unsaved" {
  186. c.HTML(http.StatusOK, "message.html", gin.H{
  187. "title": "无法渲染",
  188. "time": time.Now().Format("2006-01-02 15:04:05"),
  189. "description": "超级管理员禁用了消息持久化",
  190. "content": "很抱歉,您所使用的消息推送服务的管理员禁用了消息持久化功能,您的消息并没有存储到数据库中,因此无法渲染。",
  191. })
  192. return
  193. }
  194. message, err := model.GetMessageByLink(link)
  195. if err != nil {
  196. c.Status(http.StatusNotFound)
  197. return
  198. }
  199. if message.Description != "" {
  200. message.Description, err = common.Markdown2HTML(message.Description)
  201. if err != nil {
  202. common.SysLog(err.Error())
  203. }
  204. }
  205. if message.Content != "" {
  206. message.HTMLContent, err = common.Markdown2HTML(message.Content)
  207. if err != nil {
  208. common.SysLog(err.Error())
  209. }
  210. }
  211. c.HTML(http.StatusOK, "message.html", gin.H{
  212. "title": message.Title,
  213. "time": time.Unix(message.Timestamp, 0).Format("2006-01-02 15:04:05"),
  214. "description": message.Description,
  215. "content": message.HTMLContent,
  216. })
  217. return
  218. }
  219. func GetUserMessages(c *gin.Context) {
  220. userId := c.GetInt("id")
  221. p, _ := strconv.Atoi(c.Query("p"))
  222. if p < 0 {
  223. p = 0
  224. }
  225. messages, err := model.GetMessagesByUserId(userId, p*common.ItemsPerPage, common.ItemsPerPage)
  226. if err != nil {
  227. c.JSON(http.StatusOK, gin.H{
  228. "success": false,
  229. "message": err.Error(),
  230. })
  231. return
  232. }
  233. c.JSON(http.StatusOK, gin.H{
  234. "success": true,
  235. "message": "",
  236. "data": messages,
  237. })
  238. return
  239. }
  240. func GetMessage(c *gin.Context) {
  241. messageId, _ := strconv.Atoi(c.Param("id"))
  242. userId := c.GetInt("id")
  243. message, err := model.GetMessageById(messageId, userId)
  244. if err != nil {
  245. c.JSON(http.StatusOK, gin.H{
  246. "success": false,
  247. "message": err.Error(),
  248. })
  249. return
  250. }
  251. c.JSON(http.StatusOK, gin.H{
  252. "success": true,
  253. "message": "",
  254. "data": message,
  255. })
  256. return
  257. }
  258. func SearchMessages(c *gin.Context) {
  259. keyword := c.Query("keyword")
  260. messages, err := model.SearchMessages(keyword)
  261. if err != nil {
  262. c.JSON(http.StatusOK, gin.H{
  263. "success": false,
  264. "message": err.Error(),
  265. })
  266. return
  267. }
  268. c.JSON(http.StatusOK, gin.H{
  269. "success": true,
  270. "message": "",
  271. "data": messages,
  272. })
  273. return
  274. }
  275. func ResendMessage(c *gin.Context) {
  276. messageId, _ := strconv.Atoi(c.Param("id"))
  277. userId := c.GetInt("id")
  278. helper := func() error {
  279. message, err := model.GetMessageById(messageId, userId)
  280. message.Id = 0
  281. if err != nil {
  282. return err
  283. }
  284. user, err := model.GetUserById(userId, true)
  285. if err != nil {
  286. return err
  287. }
  288. channel_, err := model.GetChannelByName(message.Channel, user.Id)
  289. if err != nil {
  290. return err
  291. }
  292. err = saveAndSendMessage(user, message, channel_)
  293. if err != nil {
  294. return err
  295. }
  296. return nil
  297. }
  298. err := helper()
  299. if err != nil {
  300. c.JSON(http.StatusOK, gin.H{
  301. "success": false,
  302. "message": err.Error(),
  303. })
  304. return
  305. }
  306. c.JSON(http.StatusOK, gin.H{
  307. "success": true,
  308. "message": "",
  309. })
  310. return
  311. }
  312. func DeleteMessage(c *gin.Context) {
  313. messageId, _ := strconv.Atoi(c.Param("id"))
  314. userId := c.GetInt("id")
  315. err := model.DeleteMessageById(messageId, userId)
  316. if err != nil {
  317. c.JSON(http.StatusOK, gin.H{
  318. "success": false,
  319. "message": err.Error(),
  320. })
  321. return
  322. }
  323. c.JSON(http.StatusOK, gin.H{
  324. "success": true,
  325. "message": "",
  326. })
  327. return
  328. }
  329. func DeleteAllMessages(c *gin.Context) {
  330. err := model.DeleteAllMessages()
  331. if err != nil {
  332. c.JSON(http.StatusOK, gin.H{
  333. "success": false,
  334. "message": err.Error(),
  335. })
  336. return
  337. }
  338. c.JSON(http.StatusOK, gin.H{
  339. "success": true,
  340. "message": "",
  341. })
  342. return
  343. }