Giter Site home page Giter Site logo

haskell-telegram-api's Introduction

telegram-api

Join the chat at https://gitter.im/klappvisor/haskell-telegram-api

Build Status Hackage Hackage Dependencies Haskell Programming Language BSD3 License

High-level bindings to the Telegram Bot API based on servant library. Both getUpdates request or webhook can be used to receive updates for your bot. Inline mode is supported. Uploading stickers, documents, video, etc is not supported yet, but you can send items which are already uploaded on the Telegram servers.

Support of Bot-3.5 API

Usage

There are two ways of using Telegram Bot API. First and original way is to run IO directly for every Telegram servers request, another one is based on TelegramClient which is just ReaderT.

Use TelegramClient

{-# LANGUAGE OverloadedStrings #-}

import           Network.HTTP.Client      (newManager)
import           Network.HTTP.Client.TLS  (tlsManagerSettings)
import           Web.Telegram.API.Bot

main :: IO ()
main = do
  let token = Token "bot<token>" -- entire Token should be bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
  manager <- newManager tlsManagerSettings
  result <- runTelegramClient token manager $ do
    info <- getWebhookInfoM
    let request = setWebhookRequest' "https://example.com/hook"
    isSet <- setWebhookM request
    getMeM
  print result
  print "done!"

Running IO directly (planning to deprecate this option)

⚠️ This method to interact with a Telegram bot is about to be depricated and all new API calls will only have their M versions. You can run them using runTelegramClient function, for example runTelegramClient token manager $ sendMessageM message or in example below replace getMe token manager with runTelegramClient token manager getMeM to get the same behavior.

getMe example

{-# LANGUAGE OverloadedStrings #-}

import           Network.HTTP.Client      (newManager)
import           Network.HTTP.Client.TLS  (tlsManagerSettings)
import           Web.Telegram.API.Bot

main :: IO ()
main = do
  manager <- newManager tlsManagerSettings
  res <- getMe token manager
  case res of
    Left e -> do
      putStrLn "Request failed"
      print e
    Right Response { result = u } -> do
      putStrLn "Request succeded"
      print $ user_first_name u
  where token = Token "bot<token>" -- entire Token should be bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11

sendMessage example

{-# LANGUAGE OverloadedStrings #-}

import           Network.HTTP.Client      (newManager)
import           Network.HTTP.Client.TLS  (tlsManagerSettings)
import           Web.Telegram.API.Bot

main :: IO ()
main = do
  manager <- newManager tlsManagerSettings
  let request = sendMessageRequest chatId message
  res <- sendMessage token request manager
  case res of
    Left e -> do
      putStrLn "Request failed"
      print e
    Right Response { result = m } -> do
      putStrLn "Request succeded"
      print $ message_id m
      print $ text m
  where token = Token "bot<token>" -- entire Token should be bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
        chatId = ChatId <chat_id> -- use ChatId 10231 or ChatChannel "<@channelusername>"
        message = "text *bold* _italic_ [github](github.com/klappvisor/haskell-telegram-api)"

Note on requests:

Many request data records have a lot of optional parameters which are usually redundant. There are two ways to create requests:

With data type constructor:

let request = SendMessageRequest (ChatId int64_chatId) "text" Nothing (Just True) Nothing Nothing Nothing

Using default instance:

let request = sendMessageRequest (ChatId int64_chatId) "text" -- only with required fields
let request = (sendMessageRequest ChatId int64_chatId) "text") {
  message_disable_notification = Just True -- with optional fields
}

Contribution

Contributions are welcome!

  1. Fork repository
  2. Do some changes
  3. Create pull request
  4. Wait for CI build and review
  5. ??????
  6. PROFIT

Bear in mind that the CI build won't run integration test suite against your pull request since the necessary environment variables ($BOT_TOKEN, $STRIPE_TOKEN, $CHAT_ID and $BOT_NAME) aren't exported when a fork starts the build (for security reasons). If you do want to run them before creating RP, you can setup integration of your fork with CircleCI.

You can use stack to build project

stack build

To run test you have to create your own bot. Go to BotFather and create the bot. As the result you will have private bot's access token. Keep it safe!

stack test --test-arguments "--integration -c CHAT_ID -b BOT_NAME -- HSPEC_ARGS"

where

  • BOT_TOKEN is the token obtained from BotFather and must be defined as environment variable
  • PAYMENT_TOKEN is the token obtained from BotFather and must be defined as environment variable
  • CHAT_ID can be id of your chat with your bot. Send some messages to this chat in Telegram and do curl "https://api.telegram.org/bot<replace_with_token>/getUpdates", you'll have to parse some JSON with your brain ;-) or any other suitable tool and you will find chat id there.
  • BOT_NAME is the name of your bot
  • HSPEC_ARGS are the normal hspec arguments you can find here

The help option is available for the tests and for hspec:

stack test --test-arguments "-h"
stack test --test-arguments "--integration -c CHAT_ID -b BOT_NAME -- -h"

Note: Inline Spec is disabled for now...

If everything is fine after running the tests you will receive a few new messages from your bot.

haskell-telegram-api's People

Contributors

alexbiehl avatar arguggi avatar aupiff avatar cblp avatar fizruk avatar gitter-badger avatar igor-drozdov avatar josejuan avatar klappvisor avatar marcelbuesing avatar mylifeecho avatar paulrzcz avatar phadej avatar quyse avatar timjb avatar vihlayewalex avatar willsewell avatar yigitozkavci avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

haskell-telegram-api's Issues

Support for Bot API 3.1 update

  • Add new methods restrictChatMember and promoteChatMember to manage users and admins, added new parameter until_date to kickChatMember for temporary bans.
  • Add new methods exportChatInviteLink, setChatPhoto, deleteChatPhoto, setChatTitle, setChatDescription, pinChatMessage and unpinChatMessage to manage groups and channels.
  • Add the new fields photo, description and invite_link to the Chat object.
  • Add the new fields until_date, can_be_edited, can_change_info, can_post_messages, can_edit_messages, can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages, can_promote_members, can_send_messages, can_send_media_messages, can_send_other_messages and can_add_web_page_previews to the ChatMember object.

Not compatible with Aeson 1.0

There are no upper bound limits on many dependencies on this package.

aeson is one of them, and it fails to compile when the system downloads the latest package.

Preprocessing library telegram-api-0.4.3.1...
[1 of 7] Compiling Web.Telegram.API.Bot.JsonExt ( src/Web/Telegram/API/Bot/JsonExt.hs, dist/dist-sandbox-fea0daa/build/Web/Telegram/API/Bot/JsonExt.o )

src/Web/Telegram/API/Bot/JsonExt.hs:16:58:
    Expecting one more argument to ‘Rep a’
    The first argument of ‘GToJSON’ should have kind ‘*’,
      but ‘Rep a’ has kind ‘* -> *’
    In the type signature for ‘toJsonDrop’:
      toJsonDrop :: forall a. (Generic a, GToJSON (Rep a)) =>
                    Int -> a -> Value

src/Web/Telegram/API/Bot/JsonExt.hs:23:50:
    Expecting one more argument to ‘Rep a’
    The first argument of ‘GFromJSON’ should have kind ‘*’,
      but ‘Rep a’ has kind ‘* -> *’
    In the type signature for ‘parseJsonDrop’:
      parseJsonDrop :: forall a. (Generic a, GFromJSON (Rep a)) =>
                       Int -> Value -> Parser a
cabal: Error: some packages failed to install:

Either ensure compatibility, or put an upper limit to avoid this and migrate later.

Inconsistent newlines

Some files have CRLF terminators some don't.

$ find ./* -path \(./.git\|./.stack-work\) -prune -o -type f -exec file {} \;
./CHANGELOG.md: ASCII text
./circle.yml: ASCII text, with CRLF line terminators
./LICENSE: ASCII text
./README.md: ASCII text, with CRLF line terminators
./Setup.hs: ASCII text
./src/Web/Telegram/API/Bot/JsonExt.hs: ASCII text, with CRLF line terminators
./src/Web/Telegram/API/Bot/API.hs: UTF-8 Unicode text, with very long lines, with CRLF line terminators
./src/Web/Telegram/API/Bot/Data.hs: UTF-8 Unicode text, with very long lines, with CRLF line terminators
./src/Web/Telegram/API/Bot/Responses.hs: ASCII text, with CRLF line terminators
./src/Web/Telegram/API/Bot/Requests.hs: UTF-8 Unicode text, with very long lines, with CRLF line terminators
./src/Web/Telegram/API/Bot.hs: ASCII text
./stack.yaml: ASCII text
./telegram-api.cabal: ASCII text
./test/JsonSpec.hs: ASCII text
./test/MainSpec.hs: ASCII text
./test/InlineSpec.hs: UTF-8 Unicode text
./test/Spec.hs: UTF-8 Unicode text

NEW Multilingual Bots

The User object now may have a language_code field that contains the IETF language tag of the user's language.
Thanks to this, your bot can now offer localized responses to users that speak different languages.

Bot 3.5 support

  • Add the new method sendMediaGroup and two kinds of InputMedia objects to support the new albums feature.
  • Add support for pinning messages in channels. pinChatMessage and unpinChatMessage accept channels.
  • Add the new field provider_data to sendInvoice for sharing information about the invoice with the payment provider.

New inline keyboards with callback and URL buttons.

Add new objects InlineKeyboardMarkup, InlineKeyboardButton and CallbackQuery, added reply_markup fields to all InlineQueryResult objects.
Add field callback_query to the Update object, new method answerCallbackQuery.

November update - game api

  • You can now update high scores to a lower value by using the new force parameter in setGameScore. Handy for punishing cheaters or fixing errors in your game's High Score table.
  • Starting today, messages with high scores will be updated with new high scores by default. Use disable_edit_message in setGameScore if you don't want this.
  • The edit_message parameter from setGameScore is no longer in use. For backward compatibility, it will be taken into account for a while, unless disable_edit_message is passed explicitly.

November update

  • Your bot can now get updates about posts in channels. Added new fields channel_post and edited_channel_post to Update.
  • Added the new field forward_from_message_id to Message.
  • Added the new parameter cache_time to answerCallbackQuery. Will eventually work in Telegram apps — somewhere after version 3.14, maybe 3.15.
  • Renamed hide_keyboard to remove_keyboard in ReplyKeyboardRemove for clarity. hide_keyboard will still work for a while for backward compatibility.

Add to stackage

The package seems to build fine with the lastest lts and nightly from stackage, so maybe you could try and add it by sending a PR to the stackage repo?

I'm not sure if more specific versions for dependencies in the cabal file are needed or recommended though.

Add support of telegram bot api 2.1

Added more tools for group administrator bots. Your bot can now get a list of administrators and members count in a group, check a user's current status (administrator, creator, left the group, kicked from the group), and leave a group.
Added new methods: getChat, leaveChat, getChatAdministrators, getChatMember, getChatMembersCount.
Added support for edited messages and new mentions from Telegram v.3.9. New fields: edited_message in Update, edit_date in Message, user in MessageEntity. New value text_mention for the type field in MessageEntity.

Failed to build against GHC-8.2

https://matrix.hackage.haskell.org/package/telegram-api#GHC-8.2/telegram-api-0.7.0.0

Configuring library for telegram-api-0.7.0.0..
Preprocessing library for telegram-api-0.7.0.0..
Building library for telegram-api-0.7.0.0..
[ 1 of 15] Compiling Servant.Client.MultipartFormData ( src/Servant/Client/MultipartFormData.hs, /tmp/matrix-worker/1513201967/dist-newstyle/build/x86_64-linux/ghc-8.2.2/telegram-api-0.7.0.0/build/Servant/Client/MultipartFormData.o )
[ 2 of 15] Compiling Web.Telegram.API.Bot.API.Core ( src/Web/Telegram/API/Bot/API/Core.hs, /tmp/matrix-worker/1513201967/dist-newstyle/build/x86_64-linux/ghc-8.2.2/telegram-api-0.7.0.0/build/Web/Telegram/API/Bot/API/Core.o )
[ 3 of 15] Compiling Web.Telegram.API.Bot.JsonExt ( src/Web/Telegram/API/Bot/JsonExt.hs, /tmp/matrix-worker/1513201967/dist-newstyle/build/x86_64-linux/ghc-8.2.2/telegram-api-0.7.0.0/build/Web/Telegram/API/Bot/JsonExt.o )
[ 4 of 15] Compiling Web.Telegram.API.Bot.Data ( src/Web/Telegram/API/Bot/Data.hs, /tmp/matrix-worker/1513201967/dist-newstyle/build/x86_64-linux/ghc-8.2.2/telegram-api-0.7.0.0/build/Web/Telegram/API/Bot/Data.o )

src/Web/Telegram/API/Bot/Data.hs:79:1: warning: [-Wunused-imports]
    The import of ‘Data.Aeson.Types’ is redundant
      except perhaps to import instances from ‘Data.Aeson.Types’
    To import instances alone, use: import Data.Aeson.Types()
   |
79 | import           Data.Aeson.Types
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cabal: Failed to build telegram-api-0.7.0.0. The build process was killed (i.e. SIGKILL). The typical reason for this is that there is not enough memory available (e.g. the OS killed a process using lots of memory).

NEW Video Messages

As of Telegram v.4.0, users can send short rounded video messages, using an interface similar to that of voice notes.
Add the sendVideoNote method, the new field video_note to Message, the fields record_video_note or upload_video_note to sendChatAction.

Build failing:

[5 of 6] Compiling Web.Telegram.API.Bot.API ( src/Web/Telegram/API/Bot/API.hs, dist/build/Web/Telegram/API/Bot/API.o )

src/Web/Telegram/API/Bot/API.hs:53:10:
Not in scope: type constructor or class ToText' Perhaps you meantText' (imported from Data.Text)

src/Web/Telegram/API/Bot/API.hs:56:10:
Not in scope: type constructor or class `FromText'
cabal: Error: some packages failed to install:
telegram-api-0.2.1.1 failed during the building phase. The exception was:
ExitFailure 1

Bot doesn't send document, when use FileUploadBS or FileUploadLBS

Hello!
In constructor FileUpload,
when I use for the field fileUpload_content constructor
FileUploadFile FilePath - the bot successfully sends the file,
but when I use
FileUploadBS ByteString or FileUploadLBS ByteString - there is no response.
Maybe it's a bug. Or how to use this constructors?
Thanks!

October, 3 update - other changes

https://core.telegram.org/bots/api-changelog

  • New method getWebhookInfo to check current webhook status.
  • Use the new url parameter in answerCallbackQuery to create buttons that open your bot with user-specific parameters.
  • Added new field switch_inline_query_current_chat in InlineKeyboardButton.
  • Added caption fields to sendAudio, sendVoice, InlineQueryResultAudio, InlineQueryResultVoice, InlineQueryResultCachedAudio, and InlineQueryResultCachedVoice.
  • New field all_members_are_admins in the Chat object.
  • Certain server responses may now contain the new parameters field with expanded info on errors that occurred while processing your requests.

[Help] Usage example

I'm trying to get working a basic usage but when I tried to send a message my compiler crash:

src/Main.hs:21:18: error:
    • No instance for (Data.String.IsString ChatId)
        arising from the literal ‘"7055881"’
    • In the expression: "7055881"
      In an equation for ‘chatId’: chatId = "7055881"
      In an equation for ‘main’:
          main
            = do { manager <- newManager tlsManagerSettings;
                   let request = ...;
                   res <- sendMessage token request manager;
                   .... }
            where
                token = Token "botXXXXXXX"
                chatId = "XXXXXX"
                message
                  = "text *bold* _italic_ [github](github.com/klappvisor/haskell-telegram-api)"

I want some code to start learning this library, thanks in advance.

Bot API 3.4 support

  • Bots can now send and receive Live Locations. Add new field live_period to the sendLocation method and the editMessageLiveLocation and stopMessageLiveLocation methods as well as the necessary objects for inline bots.
  • Bots can use the new setChatStickerSet and deleteChatStickerSet methods to manage group sticker sets.
  • The getChat request now returns the group's sticker set for supergroups if available.
  • Bots now receive entities from media captions in the new field caption_entities in Message.

Minor changes

  • Replac the field new_chat_member in Message with new_chat_members (the old field will still be available for a while for compatibility purposes).
  • Inline keyboards with switch_inline_query and switch_inline_query_current_chat can no longer be sent to channels because they are useless there.
  • New fields gif_duration in InlineQueryResultGif and mpeg4_duration in InlineQueryResultMpeg4Gif.

Optional field for Telegram

Telegram no return some field (e.g. Message.from) and the client fail since is currently mandatory.

Should not be optional? (e.g. from :: Maybe User)

sendMessage (Token "bot01234567:ABCDEFGHIJK")
            (SendMessageRequest "-123456789"
                                "Hi World!"
                                (Just Markdown)
                                Nothing 
                                Nothing 
                                Nothing)

Left (DecodeFailure {decodeError = "The key \"from\" was not found", responseContentType = application/json, responseBody = "{\"ok\":true,\"result\":{\"message_id\":12,\"chat\":{\"id\":-123456789,\"title\":\"Bookingland Alerts\",\"type\":\"channel\"},\"date\":1461677951,\"text\":\"Hi World!\"}}"})

Great job and thank you!

New payment platform

Your bot can now accept payments for goods and services via Telegram.

  • Add new kinds of updates, shipping_query and pre_checkout_query, and new types of message content, invoice and successful_payment.
  • Add new methods for payments: sendInvoice, answerShippingQuery, and answerPreCheckoutQuery.
  • Add a new type of button, the pay button to InlineKeyboardButton.
  • Add test

inlineKeyboardMarkup for SendMessageRequest

Hi Klappvisor,

thank you for very much your package.

I noticed that I cannot specify inlineKeyboardMarkup for ordinary SendMessageRequest messages, which the Telegram API supports though.

I am just porting a nodejs bot to your haskell-telegram-api to get my hands dirty with Haskell. I am not confident enough yet to send you a pull request.

Best regards,
HC

Bot API 3.2 support

  • Add new methods for working with stickers: getStickerSet, uploadStickerFile, createNewStickerSet, addStickerToSet, setStickerPositionInSet, and deleteStickerFromSet.
  • Added the fields set_name and mask_position to the Sticker object, plus two new objects, StickerSet, and MaskPosition.
  • add tests for stickers

Bot API 3.3 support

  • getChat now also returns pinned messages in supergroups, if present. Add the new field pinned_message to the Chat object.
  • Add the new fields author_signature and forward_signature to the Message object.
  • Add the new field is_bot to the User object.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.