discord.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "sort"
  6. "github.com/ayntgl/discordgo"
  7. "github.com/gen2brain/beeep"
  8. "github.com/rivo/tview"
  9. )
  10. var (
  11. session *discordgo.Session
  12. selectedChannel *discordgo.Channel
  13. selectedMessage *discordgo.Message
  14. )
  15. func newSession() *discordgo.Session {
  16. s, err := discordgo.New()
  17. if err != nil {
  18. panic(err)
  19. }
  20. s.UserAgent = conf.UserAgent
  21. s.Identify.Compress = false
  22. s.Identify.Intents = 0
  23. s.Identify.LargeThreshold = 0
  24. s.Identify.Properties.Device = ""
  25. s.Identify.Properties.Browser = "Chrome"
  26. s.Identify.Properties.OS = "Linux"
  27. s.AddHandlerOnce(onSessionReady)
  28. s.AddHandler(onSessionMessageCreate)
  29. return s
  30. }
  31. func onSessionReady(_ *discordgo.Session, r *discordgo.Ready) {
  32. dmNode := tview.NewTreeNode("Direct Messages").
  33. Collapse()
  34. n := mainTreeView.GetRoot()
  35. n.AddChild(dmNode)
  36. sort.Slice(r.PrivateChannels, func(i, j int) bool {
  37. return r.PrivateChannels[i].LastMessageID > r.PrivateChannels[j].LastMessageID
  38. })
  39. for _, c := range r.PrivateChannels {
  40. cn := tview.NewTreeNode(genChannelRepr(c)).
  41. SetReference(c.ID)
  42. dmNode.AddChild(cn)
  43. }
  44. sort.Slice(r.Guilds, func(a, b int) bool {
  45. found := false
  46. for _, gID := range r.Settings.GuildPositions {
  47. if found {
  48. if gID == r.Guilds[b].ID {
  49. return true
  50. }
  51. } else {
  52. if gID == r.Guilds[a].ID {
  53. found = true
  54. }
  55. }
  56. }
  57. return false
  58. })
  59. for _, g := range r.Guilds {
  60. gn := tview.NewTreeNode(g.Name).
  61. SetReference(g.ID)
  62. n.AddChild(gn)
  63. }
  64. mainTreeView.SetCurrentNode(n)
  65. }
  66. func onSessionMessageCreate(_ *discordgo.Session, m *discordgo.MessageCreate) {
  67. if selectedChannel == nil {
  68. selectedChannel = &discordgo.Channel{ID: ""}
  69. }
  70. if selectedChannel.ID != m.ChannelID {
  71. if conf.Notifications {
  72. for _, u := range m.Mentions {
  73. if u.ID == session.State.User.ID {
  74. g, err := session.State.Guild(m.GuildID)
  75. if err != nil {
  76. return
  77. }
  78. c, err := session.State.Channel(m.ChannelID)
  79. if err != nil {
  80. return
  81. }
  82. go beeep.Alert(fmt.Sprintf("%s (#%s)", g.Name, c.Name), m.ContentWithMentionsReplaced(), "")
  83. return
  84. }
  85. }
  86. }
  87. return
  88. }
  89. selectedChannel.Messages = append(selectedChannel.Messages, m.Message)
  90. renderMessage(m.Message)
  91. }
  92. type loginResponse struct {
  93. MFA bool `json:"mfa"`
  94. SMS bool `json:"sms"`
  95. Ticket string `json:"ticket"`
  96. Token string `json:"token"`
  97. }
  98. func login(email, password string) (*loginResponse, error) {
  99. data := struct {
  100. Email string `json:"email"`
  101. Password string `json:"password"`
  102. }{email, password}
  103. resp, err := session.RequestWithBucketID(
  104. "POST",
  105. discordgo.EndpointLogin,
  106. data,
  107. discordgo.EndpointLogin,
  108. )
  109. if err != nil {
  110. return nil, err
  111. }
  112. var lr loginResponse
  113. err = json.Unmarshal(resp, &lr)
  114. if err != nil {
  115. return nil, err
  116. }
  117. return &lr, nil
  118. }
  119. func totp(code, ticket string) (*loginResponse, error) {
  120. data := struct {
  121. Code string `json:"code"`
  122. Ticket string `json:"ticket"`
  123. }{code, ticket}
  124. e := discordgo.EndpointAuth + "mfa/totp"
  125. resp, err := session.RequestWithBucketID("POST", e, data, e)
  126. if err != nil {
  127. return nil, err
  128. }
  129. var lr loginResponse
  130. err = json.Unmarshal(resp, &lr)
  131. if err != nil {
  132. return nil, err
  133. }
  134. return &lr, nil
  135. }