message.go 8.2 KB

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