{"id":18418095,"url":"https://github.com/augustjune/canoe","last_synced_at":"2025-07-19T15:32:43.294Z","repository":{"id":39846004,"uuid":"191051490","full_name":"augustjune/canoe","owner":"augustjune","description":"Functional Telegram Bot API for Scala ","archived":false,"fork":false,"pushed_at":"2024-09-03T21:33:21.000Z","size":849,"stargazers_count":179,"open_issues_count":39,"forks_count":38,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-31T14:14:51.850Z","etag":null,"topics":["bot","cats","cats-effect","fs2","functional-programming","scala","telegram"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/augustjune.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-09T20:19:10.000Z","updated_at":"2025-02-14T11:47:26.000Z","dependencies_parsed_at":"2024-05-17T10:26:25.817Z","dependency_job_id":"8c59b66c-d6bf-4736-bf5d-c9b3f590297a","html_url":"https://github.com/augustjune/canoe","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/augustjune%2Fcanoe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/augustjune%2Fcanoe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/augustjune%2Fcanoe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/augustjune%2Fcanoe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/augustjune","download_url":"https://codeload.github.com/augustjune/canoe/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247704571,"owners_count":20982298,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","cats","cats-effect","fs2","functional-programming","scala","telegram"],"created_at":"2024-11-06T04:12:32.602Z","updated_at":"2025-04-07T18:14:25.571Z","avatar_url":"https://github.com/augustjune.png","language":"Scala","funding_links":[],"categories":["Telegram Libraries"],"sub_categories":["Scala"],"readme":"canoe\n=============\n\n[![Continuous Integration](https://github.com/augustjune/canoe/actions/workflows/ci.yml/badge.svg)](https://github.com/augustjune/canoe/actions/workflows/ci.yml)\n[![Gitter](https://badges.gitter.im/augustjune-canoe/community.svg)](https://gitter.im/augustjune-canoe/community?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.augustjune/canoe_2.12/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.augustjune/canoe_2.12)\n[![Telegram](https://img.shields.io/badge/Bot%20API-4.9%20-00aced.svg)](https://core.telegram.org/bots/api#recent-changes)\n\n### Overview\n**canoe** is a purely functional, compositional library for building interactive Telegram bots.\nIt provides functional streaming interface over [Telegram Bot API](https://core.telegram.org/bots/api)\nwith built-in abstractions for describing your chatbot behavior.\n\n### Getting started\nsbt dependency:\n```scala\nlibraryDependencies += \"org.augustjune\" %% \"canoe\" % \"\u003cversion\u003e\"\n```\nYou can find the latest version in [releases](https://github.com/augustjune/canoe/releases) tab\nor by clicking on the maven-central badge. The library is available for Scala 2.12, 2.13, Scala 3 and Scala.js.\n\nImports:\n```scala\nimport canoe.api._\nimport canoe.syntax._\n```\n\n### The problem\nBuilding interactive chatbots requires maintaining the state of each conversation,\nwith possible interaction across them and/or using shared resources.\nThe complexity of this task grows rapidly with the advancement of the bot.\n**canoe** solves this problem by decomposing behavior of the bot into a set of scenarios\nwhich the chatbot will follow.\n\n### Basic example\nHere's a quick example of how the definition of simple bot behavior looks like in **canoe**.\nMore samples can be found [here](https://github.com/augustjune/canoe/tree/master/examples/src/main/scala/samples).\n\n```scala\nimport canoe.api._\nimport canoe.syntax._\nimport cats.effect.Async\nimport fs2.Stream\n\ndef app[F[_]: Async]: F[Unit] =\n  Stream\n    .resource(TelegramClient[F](token))\n    .flatMap(implicit client =\u003e Bot.polling[F].follow(greetings))\n    .compile\n    .drain\n\ndef greetings[F[_]: TelegramClient]: Scenario[F, Unit] =\n    for {\n      chat \u003c- Scenario.expect(command(\"hi\").chat)\n      _    \u003c- Scenario.eval(chat.send(\"Hello. What's your name?\"))\n      name \u003c- Scenario.expect(text)\n      _    \u003c- Scenario.eval(chat.send(s\"Nice to meet you, $name\"))\n    } yield ()\n```\n\nScenarios are executed concurrently in a non-blocking fashion,\nallowing to handle multiple users at the same time.\nIn fact, even the same scenario can be triggered multiple times before\nthe previous execution is completed.\nThis can be extremely useful when you allow users to schedule long-running jobs\nand don't want to make them wait before they can schedule the new ones.\nAs example may serve a simple [alarm clock implementation](https://github.com/augustjune/canoe/tree/master/examples/src/main/scala/samples/TimerAlarm.scala).\n\n\n### Telegram Bot API methods\nLow level abstractions are available through standalone Telegram Bot API methods from `canoe.methods` package.\nHaving instance of `TelegramClient` in implicit scope,\nyou can use `call` method on constructed action in order to execute it in effect `F`.\n\n```scala\ndef sendText[F[_]: TelegramClient](chatId: Long, text: String): F[TextMessage] =\n  SendMessage(chatId, text).call\n```\n\nAs an alternative, all the methods from Telegram Bot API are available from corresponding models,\ne.g.`chat.kickUser(user.id)`, `message.editText(\"edited\")`.\n\n### Webhook support\n**canoe** also provides support for obtaining messages from Telegram by setting a webhook.\nFull example may be found [here](https://github.com/augustjune/canoe/blob/master/examples/src/main/scala/samples/Webhook.scala).\n\n### Handling errors\nThere's a lot of things that may go wrong during your scenarios executions,\nfrom user input to the network issues.\nFor this reason, `Scenario` forms a `MonadError` for any `F`.\nIt means that you can use built-in `handleErrorWith` and `attempt` methods,\nin order to react to the raised error or ensure that bot workflow won't break.\nFull example may be found [here](https://github.com/augustjune/canoe/blob/master/examples/src/main/scala/samples/ErrorHandling.scala).\n\n### Contribution\nIf you're interested in the project PRs are very welcomed.\nIn case it's a feature you'd like to introduce, it is recommended to discuss it first by raising an issue\nor simply using [gitter](https://gitter.im/augustjune-canoe/community).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faugustjune%2Fcanoe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faugustjune%2Fcanoe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faugustjune%2Fcanoe/lists"}