discord.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. sort.Slice(r.Guilds, func(a, b int) bool {
  33. found := false
  34. for _, gID := range r.Settings.GuildPositions {
  35. if found {
  36. if gID == r.Guilds[b].ID {
  37. return true
  38. }
  39. } else {
  40. if gID == r.Guilds[a].ID {
  41. found = true
  42. }
  43. }
  44. }
  45. return false
  46. })
  47. n := guildsTreeView.GetRoot()
  48. for _, g := range r.Guilds {
  49. gn := tview.NewTreeNode(g.Name).
  50. SetReference(g.ID)
  51. n.AddChild(gn)
  52. }
  53. guildsTreeView.SetCurrentNode(n)
  54. }
  55. func onSessionMessageCreate(_ *discordgo.Session, m *discordgo.MessageCreate) {
  56. if selectedChannel == nil {
  57. selectedChannel = &discordgo.Channel{ID: ""}
  58. }
  59. if selectedChannel.ID != m.ChannelID {
  60. if conf.Notifications {
  61. for _, u := range m.Mentions {
  62. if u.ID == session.State.User.ID {
  63. g, err := session.State.Guild(m.GuildID)
  64. if err != nil {
  65. return
  66. }
  67. c, err := session.State.Channel(m.ChannelID)
  68. if err != nil {
  69. return
  70. }
  71. go beeep.Alert(fmt.Sprintf("%s (#%s)", g.Name, c.Name), m.ContentWithMentionsReplaced(), "")
  72. return
  73. }
  74. }
  75. }
  76. return
  77. }
  78. selectedChannel.Messages = append(selectedChannel.Messages, m.Message)
  79. renderMessage(m.Message)
  80. }
  81. type loginResponse struct {
  82. MFA bool `json:"mfa"`
  83. SMS bool `json:"sms"`
  84. Ticket string `json:"ticket"`
  85. Token string `json:"token"`
  86. }
  87. func login(email, password string) (*loginResponse, error) {
  88. data := struct {
  89. Email string `json:"email"`
  90. Password string `json:"password"`
  91. }{email, password}
  92. resp, err := session.RequestWithBucketID(
  93. "POST",
  94. discordgo.EndpointLogin,
  95. data,
  96. discordgo.EndpointLogin,
  97. )
  98. if err != nil {
  99. return nil, err
  100. }
  101. var lr loginResponse
  102. err = json.Unmarshal(resp, &lr)
  103. if err != nil {
  104. return nil, err
  105. }
  106. return &lr, nil
  107. }
  108. func totp(code, ticket string) (*loginResponse, error) {
  109. data := struct {
  110. Code string `json:"code"`
  111. Ticket string `json:"ticket"`
  112. }{code, ticket}
  113. e := discordgo.EndpointAuth + "mfa/totp"
  114. resp, err := session.RequestWithBucketID("POST", e, data, e)
  115. if err != nil {
  116. return nil, err
  117. }
  118. var lr loginResponse
  119. err = json.Unmarshal(resp, &lr)
  120. if err != nil {
  121. return nil, err
  122. }
  123. return &lr, nil
  124. }