aboutsummaryrefslogtreecommitdiff
path: root/src/IRC.hs
blob: ca4e0d53aca3e86c975dca5f3e8beccfe691fcef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
module IRC where

import Control.Monad (forM_)
import Control.Monad.IO.Class (liftIO)
-- import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as Char8
import Data.Char
import Data.Text (Text)
import qualified Data.Text as T
import Network.IRC.Client hiding (stdoutLogger)
-- import Network.IRC.Client.Events
import Lens.Micro
import System.IO (hFlush, stdout)


connectIRC :: (Text -> Maybe a) -> (a -> Text -> IO [Text]) -> IO ()
connectIRC commandDetect msgFun = do
  pass <- readFile "irc-password.txt"
  let trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace

  let conn = tlsConnection (WithDefaultConfig (Char8.pack "irc.libera.chat") 6697)
               & username .~ T.pack "yahb2"
               & realname .~ T.pack "Bot operated by tomsmeding"
               & password .~ Just (T.pack (trim pass))
               & logfunc  .~ noopLogger

  let cfg = defaultInstanceConfig (T.pack "yahb2")
              & handlers .~
                  (-- some of the standard handlers
                   [pingHandler
                   ,kickHandler
                   ,ctcpPingHandler
                   ,ctcpTimeHandler
                   ,ctcpVersionHandler
                   ,welcomeNick
                   ,joinHandler]
                   ++
                   -- our custom handlers
                   [noticeHandler
                   ,privmsgHandler commandDetect msgFun]
                  )

  runClient conn cfg ()

noticeHandler :: EventHandler s
noticeHandler = EventHandler
  (\ev -> case ev ^. message of
            Notice _ (Right text)
              | T.pack "now identified for" `T.isInfixOf` text
              -> Just ()
            _ -> Nothing)
  (\_ () -> do
    liftIO $ putStrLn "Identification confirmation received, joining channel"
    liftIO $ hFlush stdout
    send $ Join (T.pack "#haskell")
    send $ Join (T.pack "#haskell-offtopic"))

privmsgHandler :: (Text -> Maybe a) -> (a -> Text -> IO [Text]) -> EventHandler s
privmsgHandler commandDetect msgFun = EventHandler
  (\ev -> case ev ^. message of
            Privmsg _ (Right text)
              | sendingUser (ev ^. source) `notElem` map Just excludedNicks
              , Just s <- commandDetect text -> Just (ev ^. source, text, s)
            _ -> Nothing)
  (\_ (src, text, s) -> do
    msgs <- liftIO $ msgFun s text
    let mtarget = case src of
                    User name -> Just name
                    Channel ch _ -> Just ch
                    Server _ -> Nothing
    forM_ mtarget $ \target ->
      forM_ msgs $ \msg ->
        send $ Privmsg target (Right msg))

sendingUser :: Source a -> Maybe a
sendingUser (User n) = Just n
sendingUser (Channel _ n) = Just n
sendingUser (Server _) = Nothing

excludedNicks :: [Text]
excludedNicks = [T.pack "lambdabot"]

-- stdoutLogger :: Origin -> ByteString -> IO ()
-- stdoutLogger origin x = do
--   putStrLn $ unwords
--     [ if origin == FromServer then "<---" else "--->"
--     , init . tail $ show x
--     ]
--   hFlush stdout