我正在尝试使用telegram-api构建Telegram机器人。到目前为止,我没有遇到任何问题,因为我可以阅读测试以了解事情是如何工作的,但是在使用Servant构建webhook端点时遇到了很多麻烦。总的想法是,当我从webhook收到Update
时,我会发回回复。
问题在于我的postWebhook
代码,它希望收到Message
,但会收到IO Message
。我认为这是因为Servant不希望我在该函数内部发出请求,因为我的类型为EitherT ServantError IO (IO Message)
(部分由BotHandler
应用),而实际应该是EitherT ServantError IO Message
。< / p>
我还在学习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代码。提前谢谢你:)
答案 0 :(得分:5)
您的错误发生在
Just msg → return $ reply token msg "Testing!"
你在
EitherT ServantErr IO Message
monad但reply
的类型为
reply :: Token → Message → Text → IO Message
然后只需lift
IO
对你的monad采取行动,就行了
postWebhook :: Token → Update → BotHandler Message
postWebhook token update = case message update of
Just msg → lift $ reply token msg "Testing!"
Nothing → left err400
(我不容易解释这里涉及的所有事情)我认为你应该更多地考虑monads,变形金刚......,在这些复杂的例子之前,你是勇敢的! :)