util.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package discordgo
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "mime/multipart"
  8. "net/textproto"
  9. "strconv"
  10. "time"
  11. )
  12. // SnowflakeTimestamp returns the creation time of a Snowflake ID relative to the creation of Discord.
  13. func SnowflakeTimestamp(ID string) (t time.Time, err error) {
  14. i, err := strconv.ParseInt(ID, 10, 64)
  15. if err != nil {
  16. return
  17. }
  18. timestamp := (i >> 22) + 1420070400000
  19. t = time.Unix(0, timestamp*1000000)
  20. return
  21. }
  22. // MultipartBodyWithJSON returns the contentType and body for a discord request
  23. // data : The object to encode for payload_json in the multipart request
  24. // files : Files to include in the request
  25. func MultipartBodyWithJSON(data interface{}, files []*File) (requestContentType string, requestBody []byte, err error) {
  26. body := &bytes.Buffer{}
  27. bodywriter := multipart.NewWriter(body)
  28. payload, err := json.Marshal(data)
  29. if err != nil {
  30. return
  31. }
  32. var p io.Writer
  33. h := make(textproto.MIMEHeader)
  34. h.Set("Content-Disposition", `form-data; name="payload_json"`)
  35. h.Set("Content-Type", "application/json")
  36. p, err = bodywriter.CreatePart(h)
  37. if err != nil {
  38. return
  39. }
  40. if _, err = p.Write(payload); err != nil {
  41. return
  42. }
  43. for i, file := range files {
  44. h := make(textproto.MIMEHeader)
  45. h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="file%d"; filename="%s"`, i, quoteEscaper.Replace(file.Name)))
  46. contentType := file.ContentType
  47. if contentType == "" {
  48. contentType = "application/octet-stream"
  49. }
  50. h.Set("Content-Type", contentType)
  51. p, err = bodywriter.CreatePart(h)
  52. if err != nil {
  53. return
  54. }
  55. if _, err = io.Copy(p, file.Reader); err != nil {
  56. return
  57. }
  58. }
  59. err = bodywriter.Close()
  60. if err != nil {
  61. return
  62. }
  63. return bodywriter.FormDataContentType(), body.Bytes(), nil
  64. }