Skip to content

Remove support for local generators #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.env
cSpell.json
Dockerfile
justfile
README
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM golang:1.21-alpine3.18
COPY . /app
WORKDIR /app
RUN go build -o botatobot cmd/botatobot/main.go
CMD [ "./botatobot" ]
101 changes: 45 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,100 +6,89 @@ Yet another Telegram bot, this one generates stable diffusion images on request.

## Yes, but how?

In a nutshell, Botatobot listen for users requests for images and push them in a (bounded) worker queue, the queue gets processed by a server running a Stable Diffusion inside a either locally or as a service, like replicate.com
In a nutshell, Botatobot listens for user requests for images and forwards those request towards a image generator cloud service, waits for the response and sends it back to user.

## Pre-requisites

To run Stable Diffusion, you have two options:
Botatobot works out of the box in combination with [Replicate.com](https://www.replicate.com), [Telegram](https://www.telegram.com) and [fly.io](https://fly.io/).

- Locally, using a [Cog Container](https://github.com/replicate/cog).
- Remotely, using [Replicate.com](https://www.replicate.com).
## Configure and run Botatobot 🥔

To run the Telegram bot server you need [Go](https://go.dev/doc/install) and a [Telegram](https://www.telegram.com) account.
Create an `.env` file like so:

### Host a Cog Stable Diffusion server on your machine 🐳
```text
BOT_TOKEN=123456789:ABCDEF1234567890ABCDEF1234567890ABC
REPLICATE_TOKEN=1234567890abdfeghijklmnopqrstuvwxyz
```

First you need to [install Cog](https://github.com/replicate/cog?tab=readme-ov-file#install), [Docker](https://docs.docker.com/get-docker/) and the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html).
The `BOT_TOKEN` you got from the [@BotFather](https://t.me/BotFather), `REPLICATE_TOKEN` you get from [Replicate.com api-tokens](https://replicate.com/signin?next=/account/api-tokens)

Then clone the pre-configured [cog-stable-diffusion](https://github.com/replicate/cog-stable-diffusion) repository. Follow their instructions in the README to ensure the model is running correctly.
### Running Botatobot using Docker

In particular you need to download the weights first
Build the docker image with

```bash
cog run script/download-weights
docker build . -t botatobot
```

build your container with
and then launch it with

```bash
cog build -t stable-diffusion
docker run --env-file .env botatobot
```

and run it with
As long as the container is running the bot will answer to requests. To make it available 24/7 you need to deploy to a hosted service.

```bash
docker run -d -p 5001:5000 --gpus all stable-diffusion
```
## Deploy Botatobot

This will download, create and run a container with the stable diffusion image running on port 5001, eg.`http://127.0.0.1:5001/predictions`
If you want to deploy Botatobot you need a [fly.io](https://fly.io/) account. Create the account and [install the CLI](https://fly.io/docs/hands-on/install-flyctl/). Then simply run

### Getting a Replicate.com token and model version
```bash
fly launch
```

Go to [Replicate.com api-tokens](https://replicate.com/signin?next=/account/api-tokens) and generate your token, keep it safe.
to create your deployment follow by

You will also need to choose a Stable Diffusion model version. You can find the available versions here <https://replicate.com/stability-ai/stable-diffusion/versions>
```bash
fly secrets set BOT_TOKEN=123456789:ABCDEF1234567890ABCDEF1234567890ABC
fly secrets set REPLICATE_TOKEN=1234567890abdfeghijklmnopqrstuvwxyz
```

### Getting a Telegram bot token 🤖
and finally

1. Talk to [@BotFather](https://t.me/BotFather) on Telegram
2. Send `/newbot` to create a new bot
3. Follow the instructions to set a name and username for your bot
4. Copy the token that BotFather gives you
```bash
fly deploy
```

The token looks like this: `123456789:ABCDEF1234567890ABCDEF1234567890ABC`
## Bonus

### Configure and run Botatobot 🥔
### Change the model and version

#### Configure
The model version is controlled by `REPLICATE_VERSION` environment variable.

##### If running Stable Diffusion locally
### Run locally w/o Docker

Set the following environment variables or create a `.env` file with the following content:
If you have Go 1.21+ you can build the project with

```text
TELEGRAMBOT_TOKEN=123456789:ABCDEF1234567890ABCDEF1234567890ABC
MODEL_URL=http://127.0.0.1:5001/predictions
```bash
go build -o build/botatobot cmd/botatobot/main.go
```

The `BOT_TOKEN` you got from the [@BotFather](https://t.me/BotFather), and `MODEL_URL` indicates where the Cog Stable Diffusion is running, most likely a docker container in your local machine.
and then run

There is an optional variable `OUTPUT_PATH` that indicates the path where the generated images will be saved.

##### If using replicate.com

You need the Telegram and Replicate tokens and the Stable Diffusion model version, create an `.env` file or make them available in the environment.

```text
BOT_TOKEN=123456789:ABCDEF1234567890ABCDEF1234567890ABC
REPLICATE_TOKEN=1234567890abdfeghijklmnopqrstuvwxyz
REPLICATE_VERSION=a9758cbfbd5f3c2094457d996681af52552901775aa2d6dd0b17fd15df959bef
```bash
./build/botatobot
```

The `BOT_TOKEN` you got from the [@BotFather](https://t.me/BotFather),`REPLICATE_TOKEN` and `REPLICATE_VERSION` you get from replicate.com.
### Build and run using Just

Additionally you can set `REPLICATE_URL` to a custom url, and `OUTPUT_PATH` to indicate the path where the generated images will be saved.
If you have Go 1.21+ and [Just](https://just.systems/) you can use

#### Build and run

Build with`go build -o build/botatobot cmd/botatobot/main.go` and then run `./build/botatobot`

## Usage

Tell the bot `/help` to let him self explain.

## Notes
```bash
just -l
```

In some scenarios, like deploying to Heroku or other platforms you need a http rest health endpoint. Botatobot includes such functionality, to activate it include a `LOCAL_PORT` variable.
to check the available commands.

## Acknowledgments

Expand Down
7 changes: 6 additions & 1 deletion cmd/botatobot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"scristobal/botatobot/pkg"

"github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
)

func main() {
Expand All @@ -23,14 +24,18 @@ func main() {
}

botato.RegisterHandler(bot.HandlerTypeMessageText, string(pkg.GenerateCommand), bot.MatchTypePrefix, pkg.GenerateHandler)
botato.RegisterHandler(bot.HandlerTypeMessageText, string(pkg.HelpCommand), bot.MatchTypePrefix, pkg.HelpHandler)

ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()

generator := pkg.NewImageGenerator()
ctx = context.WithValue(ctx, pkg.ImageGeneratorKey, generator)

botato.SetMyCommands(ctx, &bot.SetMyCommandsParams{Commands: []models.BotCommand{{
Command: string(pkg.GenerateCommand),
Description: "Generate an image from a prompt",
}}})

go botato.Start(ctx)

log.Println("Bot online, listening to messages...")
Expand Down
20 changes: 20 additions & 0 deletions fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# fly.toml app configuration file generated for botatobot on 2023-11-19T17:03:52+01:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = "botatobot"
primary_region = "mad"

[build]

[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
processes = ["app"]

[env]
LOCAL_PORT = "8080"
19 changes: 2 additions & 17 deletions pkg/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
var (
LOCAL_PORT string
TELEGRAMBOT_TOKEN string
MODEL_URL string
OUTPUT_PATH string
REPLICATE_URL string
REPLICATE_TOKEN string
REPLICATE_VERSION string
Expand All @@ -39,20 +37,6 @@ func FromEnv() error {
return fmt.Errorf("BOT_TOKEN not found. Talk to @botfather in Telegram and get one")
}

OUTPUT_PATH, ok = os.LookupEnv("OUTPUT_PATH")

if !ok {
log.Println("OUTPUT_PATH not found, files will not be saved locally.")
}

MODEL_URL, ok = os.LookupEnv("MODEL_URL")

if ok {
return nil
}

log.Println("MODEL_URL not found, loading replicate.com config.")

REPLICATE_URL, ok = os.LookupEnv("REPLICATE_URL")

if !ok {
Expand All @@ -70,7 +54,8 @@ func FromEnv() error {
REPLICATE_VERSION, ok = os.LookupEnv("REPLICATE_VERSION")

if !ok {
return fmt.Errorf("REPLICATE_VERSION not found, go to replicate.com and choose a model version")
REPLICATE_VERSION = "39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b"
log.Printf("REPLICATE_VERSION not found, using default %s\n", REPLICATE_VERSION)
}

return nil
Expand Down
Loading