line-2.1.0.0: examples/ScottyWebhook.hs
{-|
An example code to show how to create a simple Scotty application to handle LINE
message webhooks.
-}
{-# LANGUAGE OverloadedStrings #-}
module ScottyWebhook where
import Control.Monad (forM_)
import Control.Monad.IO.Class (liftIO)
import Line.Messaging.Webhook
import Line.Messaging.Types (Text(..), Location(..))
import Web.Scotty
import qualified Data.Text as T
-- | An IO action to get channel secret. The channel secret is issued for each
-- LINE bot, and can be found in the LINE developer page.
getChannelSecret :: IO ChannelSecret
getChannelSecret = return "some channel secret"
-- | A Scotty application to handle webhook requests.
--
-- 'webhookAction' is used with a channel secret, event handler and error
-- handler.
app :: ScottyM ()
app =
post "/webhook" $ do
channelSecret <- liftIO getChannelSecret
webhookAction channelSecret handler defaultOnFailure'
-- | An event handler.
--
-- A webhook request can contain several events at once, so the first argument
-- is a list of 'Event's. The function just call the event handler for each
-- event.
handler :: [Event] -> IO ()
handler events = forM_ events handleEvent
-- | A function to handle each event.
--
-- The type of events can be decided with pattern matching. About possible
-- types, please refer to the doc of Line.Messaging.Webhook.Types module.
--
-- Basically, content of each event has a type of 'EventTuple', which may or
-- may not contain a reply token and internal data.
handleEvent :: Event -> IO ()
handleEvent (JoinEvent event) = printSource event
handleEvent (LeaveEvent event) = printSource event
handleEvent (MessageEvent event) = handleMessageEvent event
handleEvent _ = return ()
-- | An example function to print event source of event.
--
-- Event source exists for all the event tuple types, so the reply token and
-- data types can be polymorphic.
printSource :: EventTuple r a -> IO ()
printSource event = do
putStrLn . concatMap T.unpack $ case getSource event of
User identifier -> [ "A user", identifier ]
Group identifier -> [ "A group", identifier ]
Room identifier -> [ "A room", identifier ]
-- | An example function to print text and location details of a message
--
-- A message event is always replyable and has message data in it.
handleMessageEvent :: ReplyableEvent EventMessage -> IO ()
handleMessageEvent event = do
putStrLn . concatMap T.unpack $ case getMessage event of
TextEM identifier (Text text) -> -- TextEM stands for a text event message
-- print message ID and internal text
[ "A text message", identifier, text ]
LocationEM identifier (Location title address _ _) ->
-- print message ID and location information
[ "A location message", identifier, title, address ]
_ -> []