options.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package client
  2. import (
  3. "fmt"
  4. "heckel.io/ntfy/v2/util"
  5. "net/http"
  6. "strings"
  7. "time"
  8. )
  9. // RequestOption is a generic request option that can be added to Client calls
  10. type RequestOption = func(r *http.Request) error
  11. // PublishOption is an option that can be passed to the Client.Publish call
  12. type PublishOption = RequestOption
  13. // SubscribeOption is an option that can be passed to a Client.Subscribe or Client.Poll call
  14. type SubscribeOption = RequestOption
  15. // WithMessage sets the notification message. This is an alternative way to passing the message body.
  16. func WithMessage(message string) PublishOption {
  17. return WithHeader("X-Message", message)
  18. }
  19. // WithTitle adds a title to a message
  20. func WithTitle(title string) PublishOption {
  21. return WithHeader("X-Title", title)
  22. }
  23. // WithPriority adds a priority to a message. The priority can be either a number (1=min, 5=max),
  24. // or the corresponding names (see util.ParsePriority).
  25. func WithPriority(priority string) PublishOption {
  26. return WithHeader("X-Priority", priority)
  27. }
  28. // WithTagsList adds a list of tags to a message. The tags parameter must be a comma-separated list
  29. // of tags. To use a slice, use WithTags instead
  30. func WithTagsList(tags string) PublishOption {
  31. return WithHeader("X-Tags", tags)
  32. }
  33. // WithTags adds a list of a tags to a message
  34. func WithTags(tags []string) PublishOption {
  35. return WithTagsList(strings.Join(tags, ","))
  36. }
  37. // WithDelay instructs the server to send the message at a later date. The delay parameter can be a
  38. // Unix timestamp, a duration string or a natural langage string. See https://ntfy.sh/docs/publish/#scheduled-delivery
  39. // for details.
  40. func WithDelay(delay string) PublishOption {
  41. return WithHeader("X-Delay", delay)
  42. }
  43. // WithClick makes the notification action open the given URL as opposed to entering the detail view
  44. func WithClick(url string) PublishOption {
  45. return WithHeader("X-Click", url)
  46. }
  47. // WithIcon makes the notification use the given URL as its icon
  48. func WithIcon(icon string) PublishOption {
  49. return WithHeader("X-Icon", icon)
  50. }
  51. // WithActions adds custom user actions to the notification. The value can be either a JSON array or the
  52. // simple format definition. See https://ntfy.sh/docs/publish/#action-buttons for details.
  53. func WithActions(value string) PublishOption {
  54. return WithHeader("X-Actions", value)
  55. }
  56. // WithAttach sets a URL that will be used by the client to download an attachment
  57. func WithAttach(attach string) PublishOption {
  58. return WithHeader("X-Attach", attach)
  59. }
  60. // WithMarkdown instructs the server to interpret the message body as Markdown
  61. func WithMarkdown() PublishOption {
  62. return WithHeader("X-Markdown", "yes")
  63. }
  64. // WithTemplate instructs the server to use a specific template for the message. If templateName is is "yes" or "1",
  65. // the server will interpret the message and title as a template.
  66. func WithTemplate(templateName string) PublishOption {
  67. return WithHeader("X-Template", templateName)
  68. }
  69. // WithFilename sets a filename for the attachment, and/or forces the HTTP body to interpreted as an attachment
  70. func WithFilename(filename string) PublishOption {
  71. return WithHeader("X-Filename", filename)
  72. }
  73. // WithSequenceID sets a sequence ID for the message, allowing updates to existing notifications
  74. func WithSequenceID(sequenceID string) PublishOption {
  75. return WithHeader("X-Sequence-ID", sequenceID)
  76. }
  77. // WithEmail instructs the server to also send the message to the given e-mail address
  78. func WithEmail(email string) PublishOption {
  79. return WithHeader("X-Email", email)
  80. }
  81. // WithBasicAuth adds the Authorization header for basic auth to the request
  82. func WithBasicAuth(user, pass string) PublishOption {
  83. return WithHeader("Authorization", util.BasicAuth(user, pass))
  84. }
  85. // WithBearerAuth adds the Authorization header for Bearer auth to the request
  86. func WithBearerAuth(token string) PublishOption {
  87. return WithHeader("Authorization", fmt.Sprintf("Bearer %s", token))
  88. }
  89. // WithEmptyAuth clears the Authorization header
  90. func WithEmptyAuth() PublishOption {
  91. return RemoveHeader("Authorization")
  92. }
  93. // WithNoCache instructs the server not to cache the message server-side
  94. func WithNoCache() PublishOption {
  95. return WithHeader("X-Cache", "no")
  96. }
  97. // WithNoFirebase instructs the server not to forward the message to Firebase
  98. func WithNoFirebase() PublishOption {
  99. return WithHeader("X-Firebase", "no")
  100. }
  101. // WithSince limits the number of messages returned from the server. The parameter since can be a Unix
  102. // timestamp (see WithSinceUnixTime), a duration (WithSinceDuration) the word "all" (see WithSinceAll).
  103. func WithSince(since string) SubscribeOption {
  104. return WithQueryParam("since", since)
  105. }
  106. // WithSinceAll instructs the server to return all messages for the given topic from the server
  107. func WithSinceAll() SubscribeOption {
  108. return WithSince("all")
  109. }
  110. // WithSinceDuration instructs the server to return all messages since the given duration ago
  111. func WithSinceDuration(since time.Duration) SubscribeOption {
  112. return WithSinceUnixTime(time.Now().Add(-1 * since).Unix())
  113. }
  114. // WithSinceUnixTime instructs the server to return only messages newer or equal to the given timestamp
  115. func WithSinceUnixTime(since int64) SubscribeOption {
  116. return WithSince(fmt.Sprintf("%d", since))
  117. }
  118. // WithPoll instructs the server to close the connection after messages have been returned. Don't use this option
  119. // directly. Use Client.Poll instead.
  120. func WithPoll() SubscribeOption {
  121. return WithQueryParam("poll", "1")
  122. }
  123. // WithScheduled instructs the server to also return messages that have not been sent yet, i.e. delayed/scheduled
  124. // messages (see WithDelay). The messages will have a future date.
  125. func WithScheduled() SubscribeOption {
  126. return WithQueryParam("scheduled", "1")
  127. }
  128. // WithFilter is a generic subscribe option meant to be used to filter for certain messages only
  129. func WithFilter(param, value string) SubscribeOption {
  130. return WithQueryParam(param, value)
  131. }
  132. // WithMessageFilter instructs the server to only return messages that match the exact message
  133. func WithMessageFilter(message string) SubscribeOption {
  134. return WithQueryParam("message", message)
  135. }
  136. // WithTitleFilter instructs the server to only return messages with a title that match the exact string
  137. func WithTitleFilter(title string) SubscribeOption {
  138. return WithQueryParam("title", title)
  139. }
  140. // WithPriorityFilter instructs the server to only return messages with the matching priority. Not that messages
  141. // without priority also implicitly match priority 3.
  142. func WithPriorityFilter(priority int) SubscribeOption {
  143. return WithQueryParam("priority", fmt.Sprintf("%d", priority))
  144. }
  145. // WithTagsFilter instructs the server to only return messages that contain all of the given tags
  146. func WithTagsFilter(tags []string) SubscribeOption {
  147. return WithQueryParam("tags", strings.Join(tags, ","))
  148. }
  149. // WithHeader is a generic option to add headers to a request
  150. func WithHeader(header, value string) RequestOption {
  151. return func(r *http.Request) error {
  152. if value != "" {
  153. r.Header.Set(header, value)
  154. }
  155. return nil
  156. }
  157. }
  158. // WithQueryParam is a generic option to add query parameters to a request
  159. func WithQueryParam(param, value string) RequestOption {
  160. return func(r *http.Request) error {
  161. if value != "" {
  162. q := r.URL.Query()
  163. q.Add(param, value)
  164. r.URL.RawQuery = q.Encode()
  165. }
  166. return nil
  167. }
  168. }
  169. // RemoveHeader is a generic option to remove a header from a request
  170. func RemoveHeader(header string) RequestOption {
  171. return func(r *http.Request) error {
  172. if header != "" {
  173. delete(r.Header, header)
  174. }
  175. return nil
  176. }
  177. }