{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import qualified Data.Conduit as C
import qualified Data.Conduit.List as CL
import Data.DateTime
import qualified Data.ByteString.Char8 as B
import Control.Lens
import Text.Regex.Posix
import qualified Data.Text as T
import System.Environment
import Web.Twitter.Conduit ( call , update , inReplyToStatusId , StreamingAPI ( SStatus ) )
import Web.Twitter.Conduit.Stream
import Web.Twitter.Conduit.Monad
import Web.Twitter.Types ( statusId , statusText , statusUser , userScreenName )
import Web.Authenticate.OAuth
import Control.Monad.Logger
import Control.Monad
import Control.Monad.IO.Class ( liftIO )
import Database.Persist ( insert_ , selectList , SelectOpt ( Desc ) , Entity ( Entity ) )
import Database.Persist.Sqlite ( runSqlite , runMigration )
import Database.Persist.TH
share [ mkPersist sqlSettings , mkMigrate "migrateAll" ] [persistLowerCase|
Memo
memo T.Text
time DateTime default=CURRENT_TIME
|]
dbName = "memo.sqlite3"
tokens = do
ck <- getEnv "OAUTH_CONSUMER_KEY"
cs <- getEnv "OAUTH_CONSUMER_SECRET"
return $ twitterOAuth
{ oauthConsumerKey = B.pack ck
, oauthConsumerSecret = B.pack cs
}
credential = do
token <- getEnv "OAUTH_TOKEN"
token_secret <- getEnv "OAUTH_TOKEN_SECRET"
return $ Credential
[ ("oauth_token", B.pack token)
, ("oauth_token_secret", B.pack token_secret )
]
twInfo = do
tokens' <- tokens
credential' <- credential
return $ setCredential tokens' credential' def
pingPongImpl ( SStatus status ) = do
case ( T.unpack ( statusText status ) =~ ( "@minamiyama1994_ " :: String ) ) :: ( String , String , String ) of
( "" , _ , "ping" ) -> do
call $ ( update $ T.pack $ "@" ++ ( T.unpack $ userScreenName $ statusUser status ) ++ " pong" ) & inReplyToStatusId ?~ statusId status
return ( )
( "" , _ , "now" ) -> do
current <- liftIO getCurrentTime
call $ ( update $ T.pack $ "@" ++ ( T.unpack $ userScreenName $ statusUser status ) ++ " Now is " ++ show current ) & inReplyToStatusId ?~ statusId status
return ( )
( "" , _ , "help" ) -> do
call $ ( update $ T.pack $ "@" ++ ( T.unpack $ userScreenName $ statusUser status ) ++ " Please see https://github.com/minamiyama1994/chomado-bot-on-haskell/blob/minamiyama1994/README.md" ) & inReplyToStatusId ?~ statusId status
return ( )
( "" , _ , 'm' : 'e' : 'm' : 'o' : ' ' : memo ) -> if ( userScreenName $ statusUser status ) == "minamiyama1994"
then do
current <- liftIO getCurrentTime
liftIO $ runSqlite dbName $ insert_ $ Memo ( T.pack memo ) current
call $ update $ T.pack $ "#南山まさかずメモ " ++ memo
return ( )
else return ( )
( "" , _ , "list memo" ) -> do
memos <- liftIO $ runSqlite dbName $ selectList [ ] [ Desc MemoTime ]
forM_ memos $ \ ( Entity _ ( Memo memo time ) ) -> call $ update $ T.pack $ "#南山まさかずメモ " ++ T.unpack memo ++ " at " ++ show time
_ -> return ( )
pingPongImpl _ = return ( )
pingPong = do
tl <- stream userstream
tl C.$$+- CL.mapM_ ( ^! act ( pingPongImpl ) )
main = do
runSqlite dbName $ do
runMigration migrateAll
info <- twInfo
runNoLoggingT . runTW info $ do
current <- liftIO getCurrentTime
call $ update $ T.pack $ "南山まさかずbotが起動しました : " ++ show current
pingPong