Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/akeboshiwind/tg-clj-server

A more framework-y library for use with tg-clj inspired by ring web-servers.
https://github.com/akeboshiwind/tg-clj-server

clojure framework telegram telegram-bot telegram-bot-api

Last synced: 26 days ago
JSON representation

A more framework-y library for use with tg-clj inspired by ring web-servers.

Awesome Lists containing this project

README

        

# tg-clj-server

A more framework-y library for use with [tg-clj](https://github.com/Akeboshiwind/tg-clj) inspired by [ring](https://github.com/ring-clojure/ring) web-servers.


Installation |
Getting Started |
Examples |
Introduction |
Persistent Storage |
tg-clj

> [!CAUTION]
> `tg-clj-server` and `tg-clj` are considered alpha!
>
> I'll put a warning in the [changelog](/CHANGELOG.md) when a breaking change happens.
> This warning will be removed once I consider the API stable.

## Why

When writing a bot that's more complicated than a few `:sendMessage`s, it's much
nicer (and more testable) to build it out of modular components:

```clojure
(defn hello-handler [{u :update}]
{:op :sendMessage
:request {:text "Hi! 🤖"
:chat_id (get-in u [:message :chat :id])}})

(defn reply-handler [{u :update}]
(-> {:op :sendMessage
:request {:text "Message received 📨"}}
(u/reply-to u)))

(def routes
[["/hello" #'hello-handler]
[(constantly true) #'reply-handler]])

(let [client (tg/make-client {:token ""})
app (defaults/make-app routes)]
(tg-poll/run-server client app))
```

For the full bot see `/examples/simple.clj`.

## Installation

Use as a dependency in `deps.edn` or `bb.edn`:

```clojure
io.github.akeboshiwind/tg-clj {:git/tag "v0.2.2" :git/sha "f742d7e"}
io.github.akeboshiwind/tg-clj-server {:git/tag "v0.3.0" :git/sha "8c66e84"}
```

## Getting Started

To get things setup you'll need some routes:

```clojure
(require '[tg-clj-server.utils :as u])

(defn poll? [request]
(get-in request [:update :message :poll]))

(def routes
[; A route is made up of:
; - A predicate that takes a request
; - Route-data which must contain a `:handler` function
[poll?
{:handler (fn [{u :update}]
; Return a map with an :op key to automatically call `tg-clj/invoke`
(-> {:op :sendMessage
:request {:text "Woah, that's a poll!"}}
; We have a handy util for replying to a message directly
(u/reply-to u)))}]
; As syntactic sugar:
; - You can supply a string command
; - A handler function
["/command"
(fn [{u :update}]
(-> {:op :sendMessage
:request {:text "Woah, that's a command!"}}
(u/reply-to u)))]])
```

Then you'll need to create an `app` with those routes:

```clojure
(require '[tg-clj-server.defaults :as defaults])

(def app
(defaults/make-app routes {; You can supply additional middleware here
:middleware []
; You can set options on provided middleware like so
; (The store is in-memory only by default)
:store/path "/path/to/store.edn"}))
```

`defaults/make-app` provides some handy middleware like [simple-router](docs/intro.md#routing) and [invoke](docs/included-middleware.md#invoke). It's not required, see `examples/no_defaults.clj`

Then finally you can run the server with a client:

```clojure
(require '[tg-clj.core :as tg]
'[tg-clj-server.poll :as tg-poll])

(let [client (tg/make-client {:token ""})]
; Warning, This will block!
(tg-poll/run-server client app))
```

And that's it! Try out your new bot 🤖

For some complete bots take a look at the `/examples` folder.

If you want to learn more start at the [intro](docs/intro.md).

## Dev

`clj -M:dev`

To run tests:

`clj -X:dev:test`

## Releasing

1. Tag the commit `v`
2. `git push --tags`
3. Update the README.md with the new version and git hash
4. Update the CHANGELOG.md