mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 02:18:26 +00:00
Manage notification channels separately and migrate
It's more convenient to manage notification channels separately, as it is done with email settings. Notification hook and other forms are adopted to only select channels. Hooks can now use more than one channel.
This commit is contained in:
@ -1739,7 +1739,7 @@ paths:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/extraSchemas/NotificationHook"
|
||||
$ref: "#/components/schemas/NotificationHook"
|
||||
post:
|
||||
operationId: "sec-notification-hook-post"
|
||||
tags: [ Notification ]
|
||||
@ -1753,7 +1753,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/NotificationHook"
|
||||
$ref: "#/components/schemas/NotificationHook"
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
@ -1775,7 +1775,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/NotificationHook"
|
||||
$ref: "#/components/schemas/NotificationHook"
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
@ -1821,7 +1821,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/NotificationHook"
|
||||
$ref: "#/components/schemas/NotificationHook"
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
@ -4917,7 +4917,7 @@ paths:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/extraSchemas/PeriodicDueItemsSettings"
|
||||
$ref: "#/components/schemas/PeriodicDueItemsSettings"
|
||||
post:
|
||||
operationId: "sec-usertask-notify-new"
|
||||
tags: [ User Tasks ]
|
||||
@ -4931,7 +4931,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/PeriodicDueItemsSettings"
|
||||
$ref: "#/components/schemas/PeriodicDueItemsSettings"
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
@ -4954,7 +4954,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/PeriodicDueItemsSettings"
|
||||
$ref: "#/components/schemas/PeriodicDueItemsSettings"
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
@ -4984,7 +4984,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/PeriodicDueItemsSettings"
|
||||
$ref: "#/components/schemas/PeriodicDueItemsSettings"
|
||||
delete:
|
||||
operationId: "sec-usertask-notify-delete"
|
||||
tags: [ User Tasks ]
|
||||
@ -5018,7 +5018,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/PeriodicDueItemsSettings"
|
||||
$ref: "#/components/schemas/PeriodicDueItemsSettings"
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
@ -5048,7 +5048,7 @@ paths:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/extraSchemas/PeriodicQuerySettings"
|
||||
$ref: "#/components/schemas/PeriodicQuerySettings"
|
||||
post:
|
||||
operationId: "sec-usertask-periodic-query-new"
|
||||
tags: [ User Tasks ]
|
||||
@ -5062,7 +5062,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/PeriodicQuerySettings"
|
||||
$ref: "#/components/schemas/PeriodicQuerySettings"
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
@ -5085,7 +5085,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/PeriodicQuerySettings"
|
||||
$ref: "#/components/schemas/PeriodicQuerySettings"
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
@ -5115,7 +5115,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/PeriodicQuerySettings"
|
||||
$ref: "#/components/schemas/PeriodicQuerySettings"
|
||||
delete:
|
||||
operationId: "sec-usertask-periodic-query-delete"
|
||||
tags: [ User Tasks ]
|
||||
@ -5149,7 +5149,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/extraSchemas/PeriodicQuerySettings"
|
||||
$ref: "#/components/schemas/PeriodicQuerySettings"
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
@ -5467,7 +5467,10 @@ components:
|
||||
type: string
|
||||
NotificationChannelRef:
|
||||
description: |
|
||||
A reference to a channel.
|
||||
A reference to a channel. The `id` and `channelType` are
|
||||
required to identify a channel. The `name` attribute is as a
|
||||
descriptive name and is returned by the server if it is
|
||||
specified for the corresponding channel.
|
||||
required:
|
||||
- id
|
||||
- channelType
|
||||
@ -5478,6 +5481,8 @@ components:
|
||||
channelType:
|
||||
type: string
|
||||
format: channeltype
|
||||
name:
|
||||
type: string
|
||||
NotificationMatrix:
|
||||
description: |
|
||||
A notification channel for matrix.
|
||||
@ -5576,6 +5581,136 @@ components:
|
||||
items:
|
||||
type: string
|
||||
|
||||
NotificationHook:
|
||||
description: |
|
||||
Describes a notifcation hook. There must be at least one
|
||||
channel specified. When creating hooks, the channels must
|
||||
provide the `ìd` and the `channelType` while their `name`
|
||||
attribute is optional.
|
||||
required:
|
||||
- id
|
||||
- enabled
|
||||
- channel
|
||||
- events
|
||||
- allEvents
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: ident
|
||||
enabled:
|
||||
type: boolean
|
||||
channels:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/NotificationChannelRef"
|
||||
allEvents:
|
||||
type: boolean
|
||||
eventFilter:
|
||||
type: string
|
||||
format: jsonminiq
|
||||
description: |
|
||||
A filter expression that is applied to the event to be able
|
||||
to ignore a subset of them. See its
|
||||
[documentation](https://docspell.org/docs/jsonminiquery/).
|
||||
events:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: eventtype
|
||||
enum:
|
||||
- tagsAdded
|
||||
- tagsSet
|
||||
|
||||
PeriodicQuerySettings:
|
||||
description: |
|
||||
Settings for the periodc-query task. At least one of `query`
|
||||
and `bookmark` is required! There must be at least one channel
|
||||
specified when creating settings. A channel must provide its
|
||||
`id` and `channelType`, while its `name` is optional.
|
||||
required:
|
||||
- id
|
||||
- enabled
|
||||
- channel
|
||||
- schedule
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: ident
|
||||
enabled:
|
||||
type: boolean
|
||||
summary:
|
||||
type: string
|
||||
channels:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/NotificationChannelRef"
|
||||
schedule:
|
||||
type: string
|
||||
format: calevent
|
||||
query:
|
||||
type: string
|
||||
format: itemquery
|
||||
bookmark:
|
||||
type: string
|
||||
description: |
|
||||
Name or ID of bookmark to use.
|
||||
contentStart:
|
||||
type: string
|
||||
|
||||
PeriodicDueItemsSettings:
|
||||
description: |
|
||||
Settings for notifying about due items. At least one of
|
||||
`query` and `bookmark` is required! There must be at least one
|
||||
channel specified when creating settings. A channel must
|
||||
provide its `id` and `channelType`, while its `name` is
|
||||
optional.
|
||||
required:
|
||||
- id
|
||||
- enabled
|
||||
- channel
|
||||
- schedule
|
||||
- remindDays
|
||||
- capOverdue
|
||||
- tagsInclude
|
||||
- tagsExclude
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: ident
|
||||
enabled:
|
||||
type: boolean
|
||||
summary:
|
||||
type: string
|
||||
channels:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/NotificationChannelRef"
|
||||
schedule:
|
||||
type: string
|
||||
format: calevent
|
||||
remindDays:
|
||||
type: integer
|
||||
format: int32
|
||||
description: |
|
||||
Used to restrict items by their due dates. All items with
|
||||
a due date lower than (now + remindDays) are searched.
|
||||
capOverdue:
|
||||
type: boolean
|
||||
description: |
|
||||
If this is true, the search is also restricted to due
|
||||
dates greater than `now - remindDays'. Otherwise, due date
|
||||
are not restricted in that direction (only lower than `now
|
||||
+ remindDays' applies) and it is expected to restrict it
|
||||
more using custom tags.
|
||||
tagsInclude:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Tag"
|
||||
tagsExclude:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Tag"
|
||||
|
||||
ShareSecret:
|
||||
description: |
|
||||
The secret (the share id + optional password) to access a
|
||||
@ -8009,137 +8144,3 @@ components:
|
||||
schema:
|
||||
type: string
|
||||
format: ident
|
||||
|
||||
# sadly no generator support for these.
|
||||
# Changes here requires corresponding changes in:
|
||||
# - NotificationHook.elm
|
||||
# - routes.model.*
|
||||
extraSchemas:
|
||||
NotificationHook:
|
||||
description: |
|
||||
Describes a notifcation hook. There must be exactly one channel
|
||||
specified, so either use a `channelRef` or one `channel`.
|
||||
required:
|
||||
- id
|
||||
- enabled
|
||||
- channel
|
||||
- events
|
||||
- allEvents
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: ident
|
||||
enabled:
|
||||
type: boolean
|
||||
channel:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/NotificationMail"
|
||||
- $ref: "#/components/schemas/NotificationGotify"
|
||||
- $ref: "#/components/schemas/NotificationMatrix"
|
||||
- $ref: "#/components/schemas/NotificationHttp"
|
||||
- $ref: "#/components/schemas/NotificationChannelRef"
|
||||
allEvents:
|
||||
type: boolean
|
||||
eventFilter:
|
||||
type: string
|
||||
format: jsonminiq
|
||||
description: |
|
||||
A filter expression that is applied to the event to be able
|
||||
to ignore a subset of them. See its
|
||||
[documentation](https://docspell.org/docs/jsonminiquery/).
|
||||
events:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: eventtype
|
||||
enum:
|
||||
- tagsAdded
|
||||
- tagsSet
|
||||
|
||||
PeriodicQuerySettings:
|
||||
description: |
|
||||
Settings for the periodc-query task. At least one of `query` and
|
||||
`bookmark` is required!
|
||||
required:
|
||||
- id
|
||||
- enabled
|
||||
- channel
|
||||
- schedule
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: ident
|
||||
enabled:
|
||||
type: boolean
|
||||
summary:
|
||||
type: string
|
||||
channel:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/NotificationMail"
|
||||
- $ref: "#/components/schemas/NotificationGotify"
|
||||
- $ref: "#/components/schemas/NotificationMatrix"
|
||||
- $ref: "#/components/schemas/NotificationHttp"
|
||||
- $ref: "#/components/schemas/NotificationChannelRef"
|
||||
schedule:
|
||||
type: string
|
||||
format: calevent
|
||||
query:
|
||||
type: string
|
||||
format: itemquery
|
||||
bookmark:
|
||||
type: string
|
||||
description: |
|
||||
Name or ID of bookmark to use.
|
||||
|
||||
PeriodicDueItemsSettings:
|
||||
description: |
|
||||
Settings for notifying about due items.
|
||||
required:
|
||||
- id
|
||||
- enabled
|
||||
- channel
|
||||
- schedule
|
||||
- remindDays
|
||||
- capOverdue
|
||||
- tagsInclude
|
||||
- tagsExclude
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: ident
|
||||
enabled:
|
||||
type: boolean
|
||||
summary:
|
||||
type: string
|
||||
channel:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/NotificationMail"
|
||||
- $ref: "#/components/schemas/NotificationGotify"
|
||||
- $ref: "#/components/schemas/NotificationMatrix"
|
||||
- $ref: "#/components/schemas/NotificationHttp"
|
||||
- $ref: "#/components/schemas/NotificationChannelRef"
|
||||
schedule:
|
||||
type: string
|
||||
format: calevent
|
||||
remindDays:
|
||||
type: integer
|
||||
format: int32
|
||||
description: |
|
||||
Used to restrict items by their due dates. All items with
|
||||
a due date lower than (now + remindDays) are searched.
|
||||
capOverdue:
|
||||
type: boolean
|
||||
description: |
|
||||
If this is true, the search is also restricted to due
|
||||
dates greater than `now - remindDays'. Otherwise, due date
|
||||
are not restricted in that direction (only lower than `now
|
||||
+ remindDays' applies) and it is expected to restrict it
|
||||
more using custom tags.
|
||||
tagsInclude:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Tag"
|
||||
tagsExclude:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Tag"
|
||||
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Eike K. & Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package docspell.restapi.model
|
||||
|
||||
import docspell.common._
|
||||
import docspell.jsonminiq.JsonMiniQuery
|
||||
import docspell.notification.api.{ChannelRef, EventType}
|
||||
import docspell.restapi.codec.ChannelEitherCodec
|
||||
|
||||
import io.circe.{Decoder, Encoder}
|
||||
|
||||
// this must comply to the definition in openapi.yml in `extraSchemas`
|
||||
final case class NotificationHook(
|
||||
id: Ident,
|
||||
enabled: Boolean,
|
||||
channel: Either[ChannelRef, NotificationChannel],
|
||||
allEvents: Boolean,
|
||||
eventFilter: Option[JsonMiniQuery],
|
||||
events: List[EventType]
|
||||
)
|
||||
|
||||
object NotificationHook {
|
||||
import ChannelEitherCodec._
|
||||
|
||||
implicit val jsonDecoder: Decoder[NotificationHook] =
|
||||
io.circe.generic.semiauto.deriveDecoder
|
||||
implicit val jsonEncoder: Encoder[NotificationHook] =
|
||||
io.circe.generic.semiauto.deriveEncoder
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Eike K. & Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package docspell.restapi.model
|
||||
|
||||
import docspell.common._
|
||||
import docspell.restapi.model._
|
||||
|
||||
import com.github.eikek.calev.CalEvent
|
||||
import com.github.eikek.calev.circe.CalevCirceCodec._
|
||||
import io.circe.generic.semiauto
|
||||
import io.circe.{Decoder, Encoder}
|
||||
|
||||
// this must comply to the definition in openapi.yml in `extraSchemas`
|
||||
final case class PeriodicDueItemsSettings(
|
||||
id: Ident,
|
||||
enabled: Boolean,
|
||||
summary: Option[String],
|
||||
channel: NotificationChannel,
|
||||
schedule: CalEvent,
|
||||
remindDays: Int,
|
||||
capOverdue: Boolean,
|
||||
tagsInclude: List[Tag],
|
||||
tagsExclude: List[Tag]
|
||||
)
|
||||
object PeriodicDueItemsSettings {
|
||||
|
||||
implicit val jsonDecoder: Decoder[PeriodicDueItemsSettings] =
|
||||
semiauto.deriveDecoder[PeriodicDueItemsSettings]
|
||||
implicit val jsonEncoder: Encoder[PeriodicDueItemsSettings] =
|
||||
semiauto.deriveEncoder[PeriodicDueItemsSettings]
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Eike K. & Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package docspell.restapi.model
|
||||
|
||||
import docspell.common._
|
||||
import docspell.query.ItemQuery
|
||||
import docspell.restapi.codec.ItemQueryJson._
|
||||
|
||||
import com.github.eikek.calev.CalEvent
|
||||
import com.github.eikek.calev.circe.CalevCirceCodec._
|
||||
import io.circe.generic.semiauto
|
||||
import io.circe.{Decoder, Encoder}
|
||||
|
||||
// this must comply to the definition in openapi.yml in `extraSchemas`
|
||||
final case class PeriodicQuerySettings(
|
||||
id: Ident,
|
||||
summary: Option[String],
|
||||
enabled: Boolean,
|
||||
channel: NotificationChannel,
|
||||
query: Option[ItemQuery],
|
||||
bookmark: Option[String],
|
||||
contentStart: Option[String],
|
||||
schedule: CalEvent
|
||||
) {}
|
||||
|
||||
object PeriodicQuerySettings {
|
||||
|
||||
implicit val jsonDecoder: Decoder[PeriodicQuerySettings] =
|
||||
semiauto.deriveDecoder
|
||||
|
||||
implicit val jsonEncoder: Encoder[PeriodicQuerySettings] =
|
||||
semiauto.deriveEncoder
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Eike K. & Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package docspell.restapi.model
|
||||
|
||||
import docspell.common._
|
||||
import docspell.notification.api.ChannelRef
|
||||
import docspell.notification.api.ChannelType
|
||||
|
||||
import io.circe.Decoder
|
||||
import io.circe.parser
|
||||
import munit._
|
||||
|
||||
class NotificationCodecTest extends FunSuite {
|
||||
|
||||
def parse[A: Decoder](str: String): A =
|
||||
parser.parse(str).fold(throw _, identity).as[A].fold(throw _, identity)
|
||||
|
||||
def id(str: String): Ident =
|
||||
Ident.unsafe(str)
|
||||
|
||||
test("decode with channelref") {
|
||||
val json = """{"id":"",
|
||||
"enabled": true,
|
||||
"channel": {"id":"abcde", "channelType":"matrix"},
|
||||
"allEvents": false,
|
||||
"events": ["TagsChanged", "SetFieldValue"]
|
||||
}"""
|
||||
|
||||
val hook = parse[NotificationHook](json)
|
||||
assertEquals(hook.enabled, true)
|
||||
assertEquals(hook.channel, Left(ChannelRef(id("abcde"), ChannelType.Matrix)))
|
||||
}
|
||||
|
||||
test("decode with gotify data") {
|
||||
val json = """{"id":"",
|
||||
"enabled": true,
|
||||
"channel": {"id":"", "channelType":"gotify", "url":"http://test.gotify.com", "appKey": "abcde"},
|
||||
"allEvents": false,
|
||||
"eventFilter": null,
|
||||
"events": ["TagsChanged", "SetFieldValue"]
|
||||
}"""
|
||||
val hook = parse[NotificationHook](json)
|
||||
assertEquals(hook.enabled, true)
|
||||
assertEquals(
|
||||
hook.channel,
|
||||
Right(
|
||||
NotificationChannel.Gotify(
|
||||
NotificationGotify(
|
||||
id(""),
|
||||
ChannelType.Gotify,
|
||||
LenientUri.unsafe("http://test.gotify.com"),
|
||||
Password("abcde"),
|
||||
None
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
test("decode with gotify data with prio") {
|
||||
val json = """{"id":"",
|
||||
"enabled": true,
|
||||
"channel": {"id":"", "channelType":"gotify", "url":"http://test.gotify.com", "appKey": "abcde", "priority":9},
|
||||
"allEvents": false,
|
||||
"eventFilter": null,
|
||||
"events": ["TagsChanged", "SetFieldValue"]
|
||||
}"""
|
||||
val hook = parse[NotificationHook](json)
|
||||
assertEquals(hook.enabled, true)
|
||||
assertEquals(
|
||||
hook.channel,
|
||||
Right(
|
||||
NotificationChannel.Gotify(
|
||||
NotificationGotify(
|
||||
id(""),
|
||||
ChannelType.Gotify,
|
||||
LenientUri.unsafe("http://test.gotify.com"),
|
||||
Password("abcde"),
|
||||
Some(9)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user