-- GSoC 2013 - Communicating with mobile devices. {-# LANGUAGE FlexibleContexts , OverloadedStrings #-} -- | This Module define the main data types for sending Push Notifications through Google Cloud Messaging. module Network.PushNotify.Gcm.Types ( -- * GCM Settings GCMHttpConfig(..) , RegId -- * GCM Messages , GCMmessage(..) -- * GCM Result , GCMresult(..) ) where import Network.PushNotify.Gcm.Constants import Control.Monad.Writer import qualified Data.HashMap.Strict as HM import qualified Data.HashSet as HS import Data.Aeson.Types import Data.Default import Data.Monoid import Data.Text -- | 'GCMHttpConfig' represents the main necessary information for sending notifications through GCM. data GCMHttpConfig = GCMHttpConfig { apiKey :: Text -- ^ Api key provided by Google. , numRet :: Int -- ^ Number of attemps to send the message to the server. } deriving Show instance Default GCMHttpConfig where def = GCMHttpConfig "" 5 -- | 'RegId' is an unique identifier of an app/device, provided by GCM. type RegId = Text -- | 'GCMmessage' represents a message to be sent through GCM. In general cases, you can use the 'Default' value and only specify 'registration_ids' and 'data_object'. -- --On the other hand, if you want to use the rest of specific aspects, you can find more information on GCM website. data GCMmessage = GCMmessage { registration_ids :: HS.HashSet RegId -- ^ Destination. , collapse_key :: Maybe Text , data_object :: Maybe Object -- ^ Main JSON data to be sent. , delay_while_idle :: Bool , time_to_live :: Maybe Int , restricted_package_name :: Maybe Text , dry_run :: Bool } deriving Show instance Default GCMmessage where def = GCMmessage { registration_ids = HS.empty , collapse_key = Nothing , data_object = Nothing , delay_while_idle = False , time_to_live = Nothing , restricted_package_name = Nothing , dry_run = False } -- | 'GCMresult' represents information about messages after a communication with GCM Servers. data GCMresult = GCMresult { multicast_id :: Maybe Integer -- ^ Unique ID (number) identifying the multicast message. , success :: Maybe Int -- ^ Number of messages that were processed without an error. , failure :: Maybe Int -- ^ Number of messages that could not be processed. , canonical_ids :: Maybe Int -- ^ Number of results that contain a canonical registration ID. , newRegids :: HM.HashMap RegId RegId -- ^ RegIds that need to be replaced. , messagesIds :: HM.HashMap RegId Text -- ^ Successful RegIds, and its \"message_id\". , errorUnRegistered :: HS.HashSet RegId -- ^ Failed regIds that need to be removed. , errorToReSend :: HS.HashSet RegId -- ^ Failed regIds that is necessary to resend the message to, -- because there was an internal problem in GCM servers. , errorRest :: HM.HashMap RegId Text -- ^ Failed regIds with the rest of the possible errors -- (probably non-recoverable errors). } deriving Show instance Default GCMresult where def = GCMresult { multicast_id = Nothing , success = Nothing , failure = Nothing , canonical_ids = Nothing , newRegids = HM.empty , messagesIds = HM.empty , errorUnRegistered = HS.empty , errorToReSend = HS.empty , errorRest = HM.empty } instance Monoid GCMresult where mempty = def mappend (GCMresult _ x1 y1 z1 a1 b1 c1 d1 e1) (GCMresult _ x2 y2 z2 a2 b2 c2 d2 e2) = GCMresult Nothing (add x1 x2) (add y1 y2) (add z1 z2) (HM.union a1 a2) (HM.union b1 b2) (HS.union c1 c2) (HS.union d1 d2) (HM.union e1 e2) where add x Nothing = x add (Just n) (Just m) = Just (n+m) add (Nothing) (Just m) = Just m ifNotDef :: (ToJSON a,MonadWriter [Pair] m,Eq a) => Text -> (GCMmessage -> a) -> GCMmessage -> m () ifNotDef label f msg = if f def /= f msg then tell [(label .= (f msg))] else tell [] instance ToJSON GCMmessage where toJSON msg = object $ execWriter $ do ifNotDef cREGISTRATION_IDS (HS.toList . registration_ids) msg ifNotDef cTIME_TO_LIVE time_to_live msg ifNotDef cDATA data_object msg ifNotDef cCOLLAPSE_KEY collapse_key msg ifNotDef cRESTRICTED_PACKAGE_NAME restricted_package_name msg ifNotDef cDELAY_WHILE_IDLE delay_while_idle msg ifNotDef cDRY_RUN dry_run msg