-- | Subscription to change notifications through webhooks -- -- see for a list of resources that can produce change notifications -- -- see for protocol details module MSGraphAPI.ChangeNotifications.Subscription where import Data.List.NonEmpty (NonEmpty) import GHC.Generics (Generic(..)) -- aeson import qualified Data.Aeson as A (ToJSON(..), FromJSON(..), eitherDecode, genericParseJSON, genericToEncoding, defaultOptions, Options(..), withObject, withText, (.:), (.:?), object, (.=)) import qualified Data.Aeson.Encoding as A (text) -- hoauth import Network.OAuth.OAuth2.Internal (AccessToken(..)) -- req import Network.HTTP.Req (Req) -- text import Data.Text (Text, pack, unpack) -- time import Data.Time (LocalTime) -- import Data.UUID.Types (UUID) import qualified MSGraphAPI.Internal.Common as MSG (Collection(..), get, post, aesonOptions) import MSGraphAPI.Files.DriveItem (DriveItem) -- | Represents the notification sent to the subscriber. https://learn.microsoft.com/en-us/graph/api/resources/changenotification?view=graph-rest-1.0 -- -- data ChangeNotification a = ChangeNotification { cnChangeType :: ChangeType , cnClientState :: Text , cnId :: Text , cnResource :: Text , cnResourceData :: Maybe a , cnSubscriptionId :: Text , cnTenantId :: Text } deriving (Eq, Show, Generic) instance A.FromJSON a => A.FromJSON (ChangeNotification a) where parseJSON = A.genericParseJSON (MSG.aesonOptions "cn") -- | Create a subscription https://learn.microsoft.com/en-us/graph/api/subscription-post-subscriptions?view=graph-rest-1.0&tabs=http -- -- @ POST https:\/\/graph.microsoft.com\/v1.0\/subscriptions@ -- -- Creating a subscription requires read scope to the resource. For example, to get change notifications on messages, your app needs the @Mail.Read@ permission. createSubscription :: (A.FromJSON b) => Subscription -> AccessToken -> Req b createSubscription = MSG.post ["subscriptions"] mempty -- | A subscription allows a client app to receive change notifications about changes to data in Microsoft Graph. -- -- https://learn.microsoft.com/en-us/graph/api/resources/subscription?view=graph-rest-1.0 data Subscription = Subscription { cnsId :: Text , cnsChangeType :: NonEmpty ChangeType , cnsClientState :: Text , cnsExpirationDateTime :: LocalTime , cnsNotificationUrl :: Text -- ^ The URL of the endpoint that will receive the change notifications. This URL must make use of the HTTPS protocol. Any query string parameter included in the notificationUrl property will be included in the HTTP POST request when Microsoft Graph sends the change notifications. , cnsResource :: Text -- ^ Specifies the resource that will be monitored for changes. Do not include the base URL (@https:\/\/graph.microsoft.com\/v1.0\/@) , cnsLatestSupportedTLSVersion :: LatestTLSVer } deriving (Eq, Show, Generic) instance A.FromJSON Subscription where parseJSON = A.genericParseJSON (MSG.aesonOptions "cns") instance A.ToJSON Subscription where toEncoding = A.genericToEncoding (MSG.aesonOptions "cns") data LatestTLSVer = LTV10 | LTV11 | LTV12 | LTV13 deriving (Eq, Show, Generic) instance A.FromJSON LatestTLSVer where parseJSON = A.withText "LatestTLSVer" $ \t -> case t of "v1_0" -> pure LTV10 "v1_1" -> pure LTV11 "v1_2" -> pure LTV12 "v1_3" -> pure LTV13 x -> fail $ unwords ["LatestTLSVer : unexpected value:", unpack x] instance A.ToJSON LatestTLSVer where toEncoding = \case LTV10 -> A.text "v1_0" LTV11 -> A.text "v1_1" LTV12 -> A.text "v1_2" LTV13 -> A.text "v1_3" data ChangeType = CTCreated | CTUpdated | CTDeleted deriving (Eq, Show, Generic) instance A.FromJSON ChangeType where parseJSON = A.withText "ChangeType" $ \t -> case t of "created" -> pure CTCreated "updated" -> pure CTUpdated "deleted" -> pure CTDeleted x -> fail $ unwords ["ChangeType : unexpected value:", unpack x] instance A.ToJSON ChangeType where toEncoding = \case CTCreated -> A.text "created" CTUpdated -> A.text "updated" CTDeleted -> A.text "deleted"