Haskell

SpockとLINE BOTでオウム返しを作ってみた

More than 3 years have passed since last update.

LINE BOT API がトライアル版ですが公開されたので早速試してみました。

APIの詳細なドキュメントはここに載っています。

https://developers.line.me/bot-api/overview

プログラムは

とりあえずLINE BOT APIでオウムを作ってみた

LINE BOT をとりあえずタダで Heroku で動かす

を参考にしながらオウム返しを作りました。

{-# LANGUAGE OverloadedLists #-}

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Control.Lens ((^?))
import Control.Monad.IO.Class (liftIO)
import Data.Aeson
import Data.Aeson.Lens (key, _Array)
import qualified Data.ByteString.Char8 as BS
import Data.Foldable (for_)
import System.Environment (lookupEnv)

import Network.HTTP.Conduit
import Web.Spock.Safe

main :: IO ()
main = do
-- 環境変数の読み込み
port <- maybe 8080 read <$> lookupEnv "PORT" :: IO Int
Just fixie_basic <- lookupEnv "FIXIE_BASIC"
Just line_channel_id <- lookupEnv "LINE_CHANNEL_ID"
Just line_channel_secret <- lookupEnv "LINE_CHANNEL_SECRET"
Just line_channel_mid <- lookupEnv "LINE_CHANNEL_MID"
-- サーバーの起動
runSpock port . spockT id $ do
-- POST /callback
post "callback" $ do
b <- body
let Just result = (b ^? key "result" . _Array)
for_ result $ \msg -> do
let Just content = msg ^? key "content"
Just from = content ^? key "from"
liftIO $ do
-- メッセージ送信リクエストの作成
req <- parseUrl "https://trialbot-api.line.me/v1/events"
manager <- newManager tlsManagerSettings
let res = object [ "to" .= Array [from]
, "toChannel" .= Number 1383378250
, "eventType" .= String "138311608800106203"
, "content" .= content]
req' = req { proxy = Just (Proxy {proxyHost = "velodrome.usefixie.com", proxyPort = 80})
, method = "POST"
, requestHeaders = [ ("Content-Type", "application/json; charser=UTF-8")
, ("X-Line-ChannelID", BS.pack line_channel_id)
, ("X-Line-ChannelSecret", BS.pack line_channel_secret)
, ("X-Line-Trusted-User-With-ACL", BS.pack line_channel_mid)
, ("Proxy-Authorization", BS.pack $ "Basic " ++ fixie_basic)
]
, requestBody = RequestBodyLBS (encode res)
}
-- 送信
httpLbs req' manager
text ""

少し躓いたのはhttp-conduitProxyはプロキシのURLのBasic認証の部分をパースしてくれないのでProxy-Authorizationのヘッダを自分で作らないといけないというところ。環境変数のFIXIE_BASICにはFixieのBasic認証のユーザー名とパスワードがBase64でエンコードされたものが入っています。

上記コードは実際にHerokuにデプロイして動作確認しました。

HaskellアプリのHerokuへのデプロイ方法は手前味噌ですが以下が参考になります。

HerokuにHaskellのアプリを公開する

Haskellはいいぞ!