Skip to content
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

Add Cyclic hosting guide (#888) #905

Merged
merged 16 commits into from
Sep 24, 2023
4 changes: 4 additions & 0 deletions site/docs/.vitepress/configs/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ const hostingTutorials = {
text: "Vercel",
link: "/hosting/vercel",
},
{
text: "Cyclic",
link: "/hosting/cyclic",
},
{
text: "Virtual Private Server",
link: "/hosting/vps",
Expand Down
1 change: 1 addition & 0 deletions site/docs/hosting/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Instead, you will often have to have a database separately and connect to it if
| Scaleway Functions | Free | €0.15/1M req, €1.2/100K GB-s | [1M requests, 400K GB-s/mo](https://www.scaleway.com/en/pricing/?tags=serverless-functions-serverlessfunctions) | ❓ | ❓ | ❓ | |
| Scaleway Containers | Free | €0.10/100K GB-s, €1.0/100K vCPU-s | [400K GB-s, 200K vCPU-s/mo](https://www.scaleway.com/en/pricing/?tags=serverless-containers-serverlesscontainers) | ❓ | ❓ | ❓ | |
| Vercel Edge Functions | Free | $20/mo subscription for 500K | [100K req/day](https://vercel.com/pricing) | [✅](https://vercel.com/docs/concepts/functions/edge-functions/edge-runtime#compatible-node.js-modules) | ❓ | [✅](https://vercel.com/templates/edge-functions) | |
| Cyclic.sh | Free | $1/mo per app, $0.50 for for 100K | [10K req/mo](https://docs.cyclic.sh/overview/limits) | ✅ | ❓ | ❓ | |
rojvv marked this conversation as resolved.
Show resolved Hide resolved
| serverless.com | Free | | | ❓ | ❓ | ❓ | |
| Heroku | $5 | $5 for 1,000 [dyno hours](https://devcenter.heroku.com/articles/usage-and-billing#dyno-usage-and-costs)/mo | [512MB RAM, sleeps after 30 mins of inactivity](https://www.heroku.com/pricing) | ✅ | ✅ | ❓ | Deno is supported by a [third-party buildpack](https://github.com/chibat/heroku-buildpack-deno). |
| DigitalOcean Apps | $5 | | | ❓ | ❓ | ❓ | Not tested |
Expand Down
159 changes: 159 additions & 0 deletions site/docs/hosting/cyclic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
---
prev: false
next: false
---

# Hosting: Cyclic

This guide tells you how you can host your grammY bots on [Cyclic](https://cyclic.sh).

## Prerequisites

To follow along, you need to have a [Github](https://github.com) and [Cyclic](https://cyclic.sh) account.
rojvv marked this conversation as resolved.
Show resolved Hide resolved
First, initialize your project and install some dependencies:

```sh
# Initialize the project.
mkdir grammy-bot
cd grammy-bot
npm init -y

# Install main dependencies.
npm install grammy express dotenv

# Install development dependencies.
npm install -D typescript ts-node nodemon @types/express @types/node

# Initialize TypeScript config.
npx tsc --init
```

We will store our TypeScript files inside `src/`, and our compiled files in `dist/`.
After creating both of them, cd into `src/`, and create a file named `bot.ts`.
Your project's root directory should now look like this:

```asciiart:no-line-numbers
.
├── node_modules/
├── dist/
├── src/
│ └── bot.ts
├── package.json
├── package-lock.json
└── tsconfig.json
```

Then, open `tsconfig.json`, and rewrite its contents to use this configuration:

```json
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "./src",
rojvv marked this conversation as resolved.
Show resolved Hide resolved
"esModuleInterop": true,
"skipLibCheck": true,
"strict": true
}
}
```

And then we have to add `start`, `build` and `dev` scripts to our `package.json`.
Our `package.json` should now be similar to this:

```json{6}
rojvv marked this conversation as resolved.
Show resolved Hide resolved
{
"name": "grammy-bot",
"version": "1.0.0",
"description": "",
"main": "dist/bot.js",
"scripts": {
"build": "tsc",
"start": "node dist/bot.js",
"dev": "nodemon src/bot.ts"
},
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"grammy": "^1.17.2",
"dotenv": "^16.3.1"
},
"devDependencies": {
"@types/express": "^4.17.17",
"@types/node": "^20.4.9",
"typescript": "^5.1.6"
rojvv marked this conversation as resolved.
Show resolved Hide resolved
"nodemon": "^3.0.1",
"ts-node": "^10.9.1"
},
"keywords": []
}
```

### Webhooks

Open `src/bots.ts` write the following contents to it:
rojvv marked this conversation as resolved.
Show resolved Hide resolved

```ts{10}
rojvv marked this conversation as resolved.
Show resolved Hide resolved
import express from "express";
import { Bot, webhookCallback } from "grammy";
import "dotenv/config";

const bot = new Bot(process.env.BOT_TOKEN || "");

bot.command("start", (ctx) => ctx.reply("Hello World!"))

if (process.env.NODE_ENV === "DEVELOPMENT") {
bot.start();
} else {
const port = process.env.PORT || 3000;
const app = express();
app.use(express.json());
app.use(`/${bot.token}`, webhookCallback(bot, "express"));
app.listen(port, () => console.log(`listening on port ${port}`));
}
```

We recommend that you have your webhook handler on a secret path rather than `/`.
As shown in the highlighted line above, we are using the `/<bot-token>` instead of `/`.

### Local Development

Create a `.env` file at the root of your project with the following contents:

```
BOT_TOKEN=<bot-token>
NODE_ENV=DEVELOPMENT
```

After that, run your `dev` script:

```shell
rojvv marked this conversation as resolved.
Show resolved Hide resolved
npm run dev
```

Nodemon will watch your `bot.ts` file and restart your bot on every code change.

## Deploying

1. Create a repository on GitHub, it can be either private or public.
2. Push your code.

> It is recommended that you have a single stable branch and you do your testing in separate branches, so that you won't land unexpected behaviors to production.
rojvv marked this conversation as resolved.
Show resolved Hide resolved

1. Visit your [Cyclic dashboard](https://app.cyclic.sh).
rojvv marked this conversation as resolved.
Show resolved Hide resolved
2. Click "Link Your Own" and select your repository.
3. Go to Advanced > Variables and add your `BOT_TOKEN`.
rojvv marked this conversation as resolved.
Show resolved Hide resolved
4. Deploy your bot with "Connect Cyclic".

### Setting the Webhook URL

If you are using webhooks, after your first deployment, you should configure your bot's webhook settings to point to your app.
To do that, send a request to

```text
https://api.telegram.org/bot<token>/setWebhook?url=<url>/<token>
```

replacing `<token>` with your bot token, and `<url>` with the full URL of your app along with the path to the webhook handler.

Congratulations!
Your bot should now be up and running.
Loading