{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-| Module : Dialogflow.V2.Request Description : Dialogflow types for the webhook request. Copyright : (c) Mauricio Fierro, 2019 License : BSD3-Clause Maintainer : Mauricio Fierro This module contains types for Dialogflow webhook requests. See the Dialogflow . -} module Dialogflow.V2.Fulfillment.Webhook.Request where import Data.Aeson ( FromJSON , parseJSON , ToJSON , toJSON , withObject , (.:) , (.:!) , (.=)) import qualified Data.Map as M import Dialogflow.Util -- | Represents an intent. data Intent = Intent { intentName :: String -- ^ Intent name. , displayName :: String -- ^ Display name for the intent. } deriving (Eq, Show) instance FromJSON Intent where parseJSON = withObject "intent" $ \i -> do intentName <- i .: "name" displayName <- i .: "displayName" return Intent {..} instance ToJSON Intent where toJSON Intent{..} = noNullObjects [ "name" .= intentName , "displayName" .= displayName ] -- | Represents a context. data Context = Context { ctxName :: String -- ^ The unique identifier of the context. , ctxLifespanCount :: Maybe Int -- ^ The number of conversational query requests after which the -- context expires. , ctxParameters :: Maybe (M.Map String String) -- ^ The collection of parameters associated with this context. } deriving (Eq, Show) instance FromJSON Context where parseJSON = withObject "context" $ \c -> do ctxName <- c .: "name" ctxLifespanCount <- c .:! "lifespanCount" ctxParameters <- c .: "parameters" return Context{..} instance ToJSON Context where toJSON Context{..} = noNullObjects [ "name" .= ctxName , "lifespanCount" .= ctxLifespanCount , "parameters" .= ctxParameters ] -- | Represents the result of conversational query or event processing. data QueryResult = QueryResult { queryText :: String -- ^ The original text of the query. , parameters :: M.Map String String -- ^ Consists of parameter_name:parameter_value pairs. , allRequiredParamsPresent :: Bool -- ^ Set to false if required parameters are missing in query. , fulfillmentText :: Maybe String -- ^ Text to be pronounced to the user or shown on the screen. , outputContexts :: Maybe [Context] -- ^ Collection of output contexts. , intent :: Maybe Intent -- ^ The intent that matched the user's query. , intentDetectionConfidence :: Maybe Float -- ^ Matching score for the intent. , diagnosticInfo :: Maybe (M.Map String String) -- ^ Free-form diagnostic info. , languageCode :: String -- ^ The language that was triggered during intent matching. } deriving (Eq, Show) instance FromJSON QueryResult where parseJSON = withObject "queryResult" $ \qr -> do queryText <- qr .: "queryText" parameters <- qr .: "parameters" allRequiredParamsPresent <- qr .: "allRequiredParamsPresent" fulfillmentText <- qr .:! "fulfillmentText" outputContexts <- qr .:! "outputContexts" intent <- qr .:! "intent" intentDetectionConfidence <- qr .:! "intentDetectionConfidence" diagnosticInfo <- qr .:! "diagnosticInfo" languageCode <- qr .: "languageCode" return QueryResult{..} instance ToJSON QueryResult where toJSON QueryResult{..} = noNullObjects [ "queryText" .= queryText , "parameters" .= parameters , "allRequiredParamsPresent" .= allRequiredParamsPresent , "fulfillmentText" .= fulfillmentText , "outputContexts" .= outputContexts , "intent" .= intent , "intentDetectionConfidence" .= intentDetectionConfidence , "diagnosticInfo" .= diagnosticInfo , "languageCode" .= languageCode ] -- | The request message for a webhook call. data WebhookRequest = WebhookRequest { responseId :: String -- ^ Unique id for request. , session :: String -- ^ Unique session id. , queryResult :: QueryResult -- ^ Result of the conversation query or event processing. } deriving(Eq, Show) instance FromJSON WebhookRequest where parseJSON = withObject "webhookRequest" $ \wr -> do responseId <- wr .: "responseId" session <- wr .: "session" queryResult <- wr .: "queryResult" return WebhookRequest{..} instance ToJSON WebhookRequest where toJSON WebhookRequest{..} = noNullObjects [ "responseId" .= responseId , "session" .= session , "queryResult" .= queryResult ] -- TODO: Check if it's possible to have multiple Contexts with the same name -- or if there's an use-case for that, and update accordingly. -- | Given a list of 'Context', find the value of a parameter of a context in -- the list. getContextParameter :: [Context] -- ^ The list of 'Context'. -> String -- ^ The name of the 'Context'. -> String -- ^ The name of the parameter. -> Maybe String getContextParameter ctxs ctx param = case filter (\Context{..} -> ctxName == ctx) ctxs of (x:_) -> M.lookup param =<< ctxParameters x [] -> Nothing