-
-
Save Toure/4fb34856d1c5192da3d6e1c994e623bd to your computer and use it in GitHub Desktop.
IRC bot in Haskell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Network | |
import System.IO | |
import Text.Printf | |
import Data.List | |
import System.Exit | |
import System.Time | |
-- Simple IRC Bot | |
data Creds = Creds { ircServer :: String | |
, ircPort :: Int | |
, ircChan :: String | |
, ircNick :: String | |
} deriving ( Show ) | |
data Message = | |
Ping String | |
| PrivMsg String String String | |
| Join String String | |
| Quit String String | |
deriving ( Show ) | |
-- General IRC Utils | |
getPrivMsg :: Message -> Maybe String | |
getPrivMsg (PrivMsg x _ _) = Just x | |
getPrivMsg _ = Nothing | |
auth :: String -> Int -> String -> String -> Creds | |
auth s p c n = | |
Creds { ircServer=s, ircPort=p, ircChan=c, ircNick=n } | |
server = "irc.freenode.org" | |
port = 6667 | |
chan = "#nordic" | |
nick = "morpheus" | |
user = nick | |
connectToIRC :: String -> Int -> String -> String -> IO Handle | |
connectToIRC server port nick user = do | |
h <- connectTo server (PortNumber (fromIntegral port)) | |
hSetBuffering h NoBuffering | |
hPrintf h "NICK %s\n" nick | |
hPrintf h "USER %s 0 * :Haskell IRC Bot\n" user | |
joinChannel h chan | |
return $ h | |
-- Write to the socket handle | |
write :: Handle -> String -> String -> IO () | |
write handle command value = do | |
hPrintf handle "%s %s\r\n" command value | |
printf "> %s %s\n" command value | |
privMsg :: Handle -> String -> IO () | |
privMsg h s = write h "PRIVMSG" (chan ++ " :" ++ s) | |
-- Dispatch function that handles the commands | |
eval :: Handle -> String -> IO () | |
eval h "!!quit" = write h "QUIT" ":Exiting" >> exitWith ExitSuccess | |
eval h "!!time" = write h "The time is : " " " | |
eval h _ = return () | |
joinChannel :: Handle -> String -> IO () | |
joinChannel h channel = do | |
write h "JOIN" channel | |
-- Listen to socket and handle | |
listen :: Handle -> IO () | |
listen h = forever $ do | |
t <- hGetLine h | |
putStrLn (init t) | |
let s = init t | |
if ping s then pong s else eval h (clean s) | |
where | |
forever a = a >> forever a | |
clean = drop 1 . dropWhile (/= ':') . drop 1 | |
ping x = "PING :" `isPrefixOf` x | |
pong x = write h "PONG" (':' : drop 6 x) | |
-- Main function | |
main :: IO() | |
main = do | |
handle <- connectToIRC server port nick nick | |
putStrLn msg | |
listen handle | |
where msg = "Connecting to " ++ server |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment