我正在尝试使用telegram-api构建Telegram机器人.到目前为止,我还没有遇到任何问题,因为我可以阅读测试以了解事情是如何工作的,但是在使用Servant构建webhook端点时我遇到了很多麻烦.总的想法是,当我Update从webhook 收到一个,我发回一个回复.
问题在于我的postWebhook代码,它希望收到一个Message但是收到一个IO Message.我认为这是因为Servant不希望我在该函数内部发出请求,因为我确实应该有类型EitherT ServantError IO (IO Message)(部分应用BotHandler)EitherT ServantError IO Message.
我还在学习Haskell,但我知道我不得不从IO monad中获取消息?更新BotAPI返回a 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
Run Code Online (Sandbox Code Playgroud)
抱歉可能不是理想的Haskell代码.先感谢您 :)
你的错误是在
Just msg ? return $ reply token msg "Testing!"
Run Code Online (Sandbox Code Playgroud)
你是在
EitherT ServantErr IO Message
Run Code Online (Sandbox Code Playgroud)
monad但reply有类型
reply :: Token ? Message ? Text ? IO Message
Run Code Online (Sandbox Code Playgroud)
然后简单地将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
Run Code Online (Sandbox Code Playgroud)
(不容易我解释一下这里所涉及的所有的东西),我想你应该多练习大约单子,变压器,...之前这些复杂的例子,但你勇敢!:)
| 归档时间: |
|
| 查看次数: |
279 次 |
| 最近记录: |