{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Concurrent
import Control.Monad
import Data.Maybe
import Data.Semigroup ((<>))
import Options.Applicative
import qualified Data.ByteString.Char8 as B8
import qualified Data.Text as T
import qualified Data.Text.IO as TI
import Network.PushNotify.APN
data ApnOptions = ApnOptions
{ certpath :: !String
, keypath :: !String
, capath :: !String
, topic :: !String
, tokens :: !([String])
, sandbox :: !Bool
, interactive :: !Bool
, text :: !(Maybe String) }
p :: Parser ApnOptions
p = ApnOptions
<$> strOption
( short 'c'
<> metavar "CERTIFICATE"
<> help "Path to the certificate" )
<*> strOption
( short 'k'
<> metavar "PRIVATEKEY"
<> help "Path to the certificate's private key" )
<*> strOption
( short 'a'
<> metavar "CATRUSTSTORE"
<> help "Path to the CA truststore" )
<*> strOption
( short 'b'
<> metavar "BUNDLEID"
<> help "Bundle ID of the app to send the notification to. Must correspond to the certificate." )
<*> many ( strOption
( short 't'
<> metavar "TOKEN"
<> help "Tokens of the devices to send the notification to" ) )
<*> switch
( long "sandbox"
<> short 's'
<> help "Whether to use the sandbox (non-production deployments)" )
<*> switch
( long "interactive"
<> short 'i'
<> help "Run an interactive mode; each line must have this format: token:message " )
<*> optional (strOption
( short 'm'
<> metavar "MESSAGE"
<> help "Message to send to the device" ))
main :: IO ()
main = send =<< execParser opts
where
opts = info (p <**> helper)
( fullDesc
<> progDesc "Sends a push notification to an apple device"
<> header "apn- a test for the apn library" )
send :: ApnOptions -> IO ()
send o = do
let mkSession = newSession (keypath o) (certpath o) (capath o) (sandbox o) 10 (B8.pack $ topic o)
session <- mkSession
if interactive o
then
let loop sess = do
TI.putStrLn "Message in the form token:sound:title:message please"
line <- TI.getLine
let parts = T.splitOn ":" line
if length parts >= 4
then
let token = hexEncodedToken $ head parts
text = T.intercalate ":" (drop 3 parts)
title = parts !! 2
sound = parts !! 1
payload = setSound sound . alertMessage title $ text
message = newMessage payload
in (sendMessage sess token message >>= TI.putStrLn . T.pack . show) >> loop sess
else case line of
"close" -> closeSession sess >> loop sess
"reset" -> mkSession >>= loop
"quit" -> return ()
_ -> TI.putStrLn "Erroneous format" >> loop sess
in loop session
else do
when (isNothing $ text o) $ error "You need to specify a message with -m"
let payload = alertMessage "push-notify-apn" (T.pack $ fromJust $ text o)
message = newMessage payload
forM_ (tokens o) $ \token ->
let apntoken = hexEncodedToken . T.pack $ token
in sendMessage session apntoken message >>= print