discord.go 2.8 KB

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