{-# LANGUAGE OverloadedStrings #-} module IRC ( -- connectIRC ) where -- import Control.Monad (sequence_) -- import Control.Monad.IO.Class (liftIO) -- import Control.Monad.Trans.Class (lift) -- import Control.Monad.Trans.Maybe (MaybeT(MaybeT), runMaybeT) -- import qualified Data.ByteString as B -- import qualified Data.Text as T -- -- import qualified Network.IRC.Client as IRC -- -- -- import Bot (Bot) -- import Bot (Bot, runBot) -- import Message -- import Plugin (matchPlugin, performPlugin) -- import Plugin.Base (queryOnly) -- -- connectIRC :: B.ByteString -> Int -> T.Text -> IO () -- connectIRC host port nick = do -- conn <- IRC.connectWithTLS host port 0.2 -- let cfg = IRC.defaultIRCConf nick -- let cfg' = cfg -- { -- IRC._eventHandlers = handlePrivmsg : IRC._eventHandlers cfg -- , IRC._channels = ["#test-chan-13513"] -- } -- IRC.start conn cfg' -- -- handlePrivmsg :: IRC.EventHandler s -- handlePrivmsg = IRC.EventHandler -- { IRC._description = "" -- , IRC._matchType = IRC.EPrivmsg -- , IRC._eventFunc = \evt -> dispatchEvent evt -- } -- where -- dispatchEvent :: IRC.UnicodeEvent -> IRC.StatefulIRC s () -- dispatchEvent (IRC.Event _ (IRC.User nick) (IRC.Privmsg _ (Right msg))) = do -- let message = Message -- { text = msg -- , channel = nick -- , nick = nick -- } -- response <- lift $ runMaybeT $ privmsgFromPlugin message -- case response of -- Nothing -> return () -- Just r -> sequence_ r -- dispatchEvent (IRC.Event -- _ (IRC.Channel chan nick) (IRC.Privmsg _ (Right msg))) = do -- let message = Message -- { text = msg -- , channel = chan -- , nick = nick -- } -- case messageForBot message of -- Nothing -> return () -- Just message -> do -- response <- lift $ runMaybeT $ privmsgFromPlugin message -- case response of -- Nothing -> return () -- Just r -> sequence_ r -- -- privmsgFromPlugin :: Message -> MaybeT Bot [IRC.StatefulIRC s ()] -- privmsgFromPlugin message = do -- plugin <- liftMaybe $ matchPlugin message -- response <- lift $ performPlugin plugin message -- -- plugin' <- liftMaybe plugin -- return $ case response of -- Left err -> [IRC.send $ IRC.Privmsg -- (toChannel plugin message) -- (Right err)] -- Right r -> map -- (\r -> IRC.send $ IRC.Privmsg -- (toChannel plugin message) -- (Right r) ) -- (splitAtNewlines $ splitLongLines r) -- where -- liftMaybe = MaybeT . return -- -- -- IRC only permits 512 bytes per line. Use less to allow for protocol -- -- information that gets sent in addition to the message content. -- splitLongLines txt = T.chunksOf 400 txt -- -- splitAtNewlines lst = foldr (\s acc -> (T.lines s) ++ acc) [] lst -- -- toChannel plugin message = case queryOnly plugin of -- False -> channel message -- True -> nick message -- -- messageForBot :: Message -> Maybe Message -- messageForBot m = case T.stripPrefix "sorbot: " (text m) of -- Nothing -> Nothing -- Just t -> Just m { text = t }