【发布时间】:2016-02-11 13:37:53
【问题描述】:
我正在尝试使用 telegram-api 构建 Telegram 机器人。到目前为止,我没有遇到任何问题,因为我可以阅读测试以了解事情是如何工作的,但是在使用 Servant 构建 webhook 端点时遇到了很多麻烦。总体思路是,当我收到来自 webhook 的 Update 时,我会发回回复。
问题与我的postWebhook 代码有关,它希望收到Message,但收到IO Message。我认为这是因为 Servant 不希望我在该函数中发出请求,因为我的类型为 EitherT ServantError IO (IO Message)(部分由 BotHandler 应用),而实际上它应该是 EitherT ServantError IO Message。
我仍在学习 Haskell,但我知道我必须以某种方式从 IO monad 中获取消息?更新BotAPI 以返回Post '[JSON] (IO Message) 给了我这个:No instance for (Foldable IO) arising from a use of ‘serve’,这超出了我的初学者知识范围,我可以看到摆弄这些类型只会将相同的问题转移到代码的不同部分。我只是不知道如何解决它。
这是删除敏感字符串的代码:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Control.Monad
import Control.Monad.Trans.Either
import Data.Proxy
import Data.Text (Text, pack)
import Network.Wai.Handler.Warp
import Servant
import Web.Telegram.API.Bot
reply :: Token -> Message -> Text -> IO Message
reply token msg response = do
Right MessageResponse { message_result = m } <-
sendMessage token $ SendMessageRequest chatId response (Just Markdown) Nothing Nothing Nothing
return m
where chatId = pack . show $ chat_id (chat msg)
type BotAPI = "webhook" :> ReqBody '[JSON] Update :> Post '[JSON] Message
type BotHandler a = EitherT ServantErr IO a
botApi :: Proxy BotAPI
botApi = Proxy
initWebhook :: Token -> IO Bool
initWebhook token = do
Right SetWebhookResponse { webhook_result = w } <-
setWebhook token $ Just "https://example.com/webhook"
return w
postWebhook :: Token -> Update -> BotHandler (IO Message)
postWebhook token update = case message update of
Just msg -> return $ reply token msg "Testing!"
Nothing -> left err400
server :: Token -> Server BotAPI
server = postWebhook
main :: IO ()
main = do
initWebhook token
run port $ serve botApi (server token)
where token = Token "<token>"
port = 8080
对于可能不是理想的 Haskell 代码,我们深表歉意。提前谢谢你:)
【问题讨论】:
-
哇,有人在用它!