attachments.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package main
  2. import (
  3. "bytes"
  4. "fmt"
  5. "image"
  6. "io"
  7. "net/http"
  8. "strings"
  9. "maunium.net/go/mautrix/crypto/attachment"
  10. "github.com/bwmarrin/discordgo"
  11. "maunium.net/go/mautrix"
  12. "maunium.net/go/mautrix/appservice"
  13. "maunium.net/go/mautrix/event"
  14. "maunium.net/go/mautrix/id"
  15. )
  16. func (portal *Portal) downloadDiscordAttachment(url string) ([]byte, error) {
  17. req, err := http.NewRequest(http.MethodGet, url, nil)
  18. if err != nil {
  19. return nil, err
  20. }
  21. for key, value := range discordgo.DroidDownloadHeaders {
  22. req.Header.Set(key, value)
  23. }
  24. resp, err := http.DefaultClient.Do(req)
  25. if err != nil {
  26. return nil, err
  27. }
  28. defer resp.Body.Close()
  29. if resp.StatusCode > 300 {
  30. data, _ := io.ReadAll(resp.Body)
  31. return nil, fmt.Errorf("unexpected status %d: %s", resp.StatusCode, data)
  32. }
  33. return io.ReadAll(resp.Body)
  34. }
  35. func (portal *Portal) downloadMatrixAttachment(content *event.MessageEventContent) ([]byte, error) {
  36. var file *event.EncryptedFileInfo
  37. rawMXC := content.URL
  38. if content.File != nil {
  39. file = content.File
  40. rawMXC = file.URL
  41. }
  42. mxc, err := rawMXC.Parse()
  43. if err != nil {
  44. return nil, err
  45. }
  46. data, err := portal.MainIntent().DownloadBytes(mxc)
  47. if err != nil {
  48. return nil, err
  49. }
  50. if file != nil {
  51. err = file.DecryptInPlace(data)
  52. if err != nil {
  53. return nil, err
  54. }
  55. }
  56. return data, nil
  57. }
  58. func (portal *Portal) uploadMatrixAttachment(intent *appservice.IntentAPI, data []byte, content *event.MessageEventContent) error {
  59. content.Info.Size = len(data)
  60. if content.Info.Width == 0 && content.Info.Height == 0 && strings.HasPrefix(content.Info.MimeType, "image/") {
  61. cfg, _, _ := image.DecodeConfig(bytes.NewReader(data))
  62. content.Info.Width = cfg.Width
  63. content.Info.Height = cfg.Height
  64. }
  65. uploadMime := content.Info.MimeType
  66. var file *attachment.EncryptedFile
  67. if portal.Encrypted {
  68. file = attachment.NewEncryptedFile()
  69. file.EncryptInPlace(data)
  70. uploadMime = "application/octet-stream"
  71. }
  72. req := mautrix.ReqUploadMedia{
  73. ContentBytes: data,
  74. ContentType: uploadMime,
  75. }
  76. var mxc id.ContentURI
  77. if portal.bridge.Config.Homeserver.AsyncMedia {
  78. uploaded, err := intent.UnstableUploadAsync(req)
  79. if err != nil {
  80. return err
  81. }
  82. mxc = uploaded.ContentURI
  83. } else {
  84. uploaded, err := intent.UploadMedia(req)
  85. if err != nil {
  86. return err
  87. }
  88. mxc = uploaded.ContentURI
  89. }
  90. if file != nil {
  91. content.File = &event.EncryptedFileInfo{
  92. EncryptedFile: *file,
  93. URL: mxc.CUString(),
  94. }
  95. } else {
  96. content.URL = mxc.CUString()
  97. }
  98. return nil
  99. }