client.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package ifttt
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "fmt"
  7. "io"
  8. "net/http"
  9. "net/url"
  10. goahttp "goa.design/goa/v3/http"
  11. )
  12. type (
  13. Client interface {
  14. Trigger(ctx context.Context, present bool) (event string, values *Values, err error)
  15. }
  16. client struct {
  17. c *http.Client
  18. presentEvent, presentURL, absentEvent, absentURL string
  19. presentValues, absentValues *Values
  20. debug bool
  21. }
  22. Values struct {
  23. Value1 string `json:"value1,omitempty"`
  24. Value2 string `json:"value2,omitempty"`
  25. Value3 string `json:"value3,omitempty"`
  26. }
  27. )
  28. func NewClient(c *http.Client, baseURL, key, presentEvent, absentEvent string, presentValues, absentValues Values, debug bool) (Client, error) {
  29. presentURL, err := url.JoinPath(baseURL, "trigger", presentEvent, "with/key", key)
  30. if err != nil {
  31. return nil, err
  32. }
  33. absentURL, err := url.JoinPath(baseURL, "trigger", absentEvent, "with/key", key)
  34. if err != nil {
  35. return nil, err
  36. }
  37. return &client{
  38. c: c,
  39. presentEvent: presentEvent,
  40. presentURL: presentURL,
  41. presentValues: &presentValues,
  42. absentEvent: absentEvent,
  43. absentURL: absentURL,
  44. absentValues: &absentValues,
  45. debug: debug,
  46. }, nil
  47. }
  48. func (c *client) Trigger(ctx context.Context, present bool) (string, *Values, error) {
  49. var (
  50. event, u string
  51. values *Values
  52. )
  53. if present {
  54. event = c.presentEvent
  55. u = c.presentURL
  56. values = c.presentValues
  57. } else {
  58. event = c.absentEvent
  59. u = c.absentURL
  60. values = c.absentValues
  61. }
  62. var (
  63. b = &bytes.Buffer{}
  64. e = json.NewEncoder(b)
  65. )
  66. e.SetEscapeHTML(false)
  67. if err := e.Encode(values); err != nil {
  68. return "", nil, err
  69. }
  70. req, err := http.NewRequestWithContext(ctx, http.MethodPost, u, b)
  71. if err != nil {
  72. return "", nil, err
  73. }
  74. doer := goahttp.Doer(c.c)
  75. if c.debug {
  76. doer = goahttp.NewDebugDoer(doer)
  77. }
  78. resp, err := doer.Do(req)
  79. if err != nil {
  80. return "", nil, err
  81. }
  82. defer func() { _ = resp.Body.Close() }()
  83. if resp.StatusCode != http.StatusOK {
  84. var b []byte
  85. b, err = io.ReadAll(resp.Body)
  86. if err != nil {
  87. return "", nil, fmt.Errorf("%v: <failed to read body: %w>", resp.Status, err)
  88. } else if len(b) == 0 {
  89. b = []byte("<empty body>")
  90. }
  91. return "", nil, fmt.Errorf("%v: %s", resp.Status, b)
  92. }
  93. return event, values, nil
  94. }