> For the complete documentation index, see [llms.txt](https://docs.chiliz.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chiliz.com/vi/phat-trien/nang-cao/thong-bao-telegram-fan-token.md).

# Thông báo Telegram cho Fan Token

Theo dõi các giao dịch Fan Token™ diễn ra trên Chiliz Chain là một cách tuyệt vời để cập nhật các động thái giá trị cao và giữ cho cộng đồng của bạn luôn được thông tin.

Với một chút cấu hình và code, bạn có thể thiết lập một bot Telegram để thông báo cho nhóm mỗi khi một giao dịch Fan Token™ vượt quá một ngưỡng nhất định.

## Cách thực hiện bằng Envio?

[Envio](https://envio.dev/) là một công cụ indexing mạnh mẽ cho phép các nhà phát triển lắng nghe các sự kiện smart contract trên Chiliz và thực hiện hành động dựa trên sự kiện đó.

Trong hướng dẫn này, bạn sẽ thấy cách cấu hình bot, bắt các sự kiện liên quan và tự động kích hoạt cảnh báo Telegram, biến thiết lập của bạn thành một "whale watcher" cho các giao dịch lớn.

### Bước 1: Cài đặt các công cụ cần thiết

Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt [các công cụ cần thiết](https://docs.envio.dev/docs/HyperIndex/getting-started#prerequisites):

* [pnpm](https://pnpm.io/)
* [Node.js](https://nodejs.org/en)
* [Docker](https://www.docker.com/)

{% hint style="info" %}
Toàn bộ dự án có thể tìm thấy [trên GitHub repository này](https://github.com/DenhamPreen/fc-barce-fan-token-indexer/tree/main).
{% endhint %}

### Bước 2: Khởi tạo Envio Indexer

Chạy lệnh sau để khởi tạo một Envio indexer và làm theo các hướng dẫn để tạo template ERC-20 trên Chiliz Chain (một blockchain tương thích EVM):

```bash
pnpx envio init
```

Dưới đây là các lựa chọn bạn nên thực hiện khi được nhắc:

<figure><img src="/files/jQAXYZTu3gxjmkbVwiy4" alt=""><figcaption></figcaption></figure>

### Bước 3: Cấu hình `config.yaml`

Chỉnh sửa file `config.yaml` để chỉ định địa chỉ hợp đồng của FC Barcelona Fan Token™ (hoặc bất kỳ Fan Token™ nào bạn muốn theo dõi):

{% code overflow="wrap" lineNumbers="true" %}

```yaml
# yaml-language-server: $schema=./node_modules/envio/evm.schema.json
name: fan-token-watcher
description: A simple indexer for Fan Tokens that posts notifications to Telegram on large transfers
networks:
  - id: 8888 # Chiliz
    start_block: 0
    contracts:
      - name: ERC20
        address: "0xFD3C73b3B09D418841dd6Aff341b2d6e3abA433b" # FC Barcelona
        handler: src/EventHandlers.ts
        events:          
          - event: "Transfer(address indexed from, address indexed to, uint256 value)"
field_selection:
  transaction_fields:
    - "hash"
```

{% endcode %}

**Lưu ý:** Chúng ta bỏ sự kiện `approval` vì chúng ta chỉ quan tâm đến các giao dịch chuyển nhượng.

### Bước 4: Đơn giản hóa GraphQL Schema

Chỉnh sửa file `schema.graphql` để chỉ theo dõi số dư tài khoản:

```graphql
type Account {
  id: ID!   # Address of the account
  balance: BigInt! # Account balance of tokens
}
```

Đến đây, chúng ta đã có một ERC-20 indexer lắng nghe các sự kiện.

Bây giờ, hãy thêm logic để gửi thông báo Telegram.

### Bước 5: Triển khai logic thông báo Telegram

Chỉnh sửa file `/src/EventHandlers.ts` để thêm logic phát hiện các giao dịch lớn và gửi cảnh báo Telegram.

{% code overflow="wrap" lineNumbers="true" %}

```typescript
import { ERC20 } from "generated";
import { isIndexingAtHead, indexBalances } from "./libs/helpers";
import { fetchEnsHandle } from "./libs/ens";
import { sendMessageToTelegram } from "./libs/telegram";
import { WHALE_THRESHOLD, explorerUrlAddress, explorerUrlTx } from "./constants";

ERC20.Transfer.handler(async ({ event, context }) => {
  if (isIndexingAtHead(event.block.timestamp) && event.params.value >= BigInt(WHALE_THRESHOLD)) {
    const ensHandleOrFromAddress = await fetchEnsHandle(event.params.from); 
    const ensHandleOrToAddress = await fetchEnsHandle(event.params.to);
    const msg = `FC Barcelona WHALE ALERT 🐋: A new transfer has been made by <a href="${explorerUrlAddress(
      event.params.from
    )}">${ensHandleOrFromAddress}</a> to <a href="${explorerUrlAddress(
      event.params.to
    )}">${ensHandleOrToAddress}</a> for ${event.params.value} FC Barcelona! 🔥 - <a href="${explorerUrlTx(
      event.transaction.hash
    )}">transaction</a>`;

    await sendMessageToTelegram(msg);
  }

  await indexBalances(context, event);
});
```

{% endcode %}

{% hint style="success" %}
Thư mục mẫu `/libs/` có thể tìm thấy [ngay tại đây trên GitHub](https://github.com/DenhamPreen/fc-barce-fan-token-indexer/tree/main/src/libs), bao gồm các file `helpers.ts` và `ens.ts`.
{% endhint %}

### Bước 6: Cấu hình các hằng số

Tạo file `constants.ts` để lưu trữ các biến môi trường:

{% code overflow="wrap" lineNumbers="true" %}

```typescript
export const EXPLORER_URL_MONAD = process.env.ENVIO_EXPLORER_URL_MONAD;
export const WHALE_THRESHOLD: string = process.env.ENVIO_WHALE_THRESHOLD ?? "1000";
export const BOT_TOKEN = process.env.ENVIO_BOT_TOKEN;
export const CHANNEL_ID = process.env.ENVIO_TELEGRAM_CHANNEL_ID;
export const MESSAGE_THREAD_ID = process.env.ENVIO_TELEGRAM_MESSAGE_THREAD_ID;

export const explorerUrlAddress = (address: string) =>
  EXPLORER_URL_MONAD + "address/" + address;
export const explorerUrlTx = (txHash: string) =>
  EXPLORER_URL_MONAD + "tx/" + txHash;
```

{% endcode %}

### Bước 7: Gửi tin nhắn Telegram

Cài đặt [Axios HTTP client](https://axios-http.com/):

```bash
pnpm i axios
```

Tạo một hàm helper trong `libs/telegram.ts` để gửi tin nhắn bằng Axios:

{% code overflow="wrap" lineNumbers="true" %}

```typescript
import axios from "axios";
import { CHANNEL_ID, MESSAGE_THREAD_ID, BOT_TOKEN } from "../constants";

export const sendMessageToTelegram = async (message: string): Promise<void> => {
  try {
    const apiUrl = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
    await axios.post(apiUrl, {
      chat_id: CHANNEL_ID,
      text: message,
      parse_mode: "HTML",
    });
  } catch (error) {
    console.error("Error sending message:", error);
  }
};
```

{% endcode %}

### Bước 8: Cấu hình cuối cùng và chạy Indexer

#### Cấu hình file `.env`

```sh
cp .env.example .env
```

Chỉnh sửa `.env` với thông tin xác thực bot Telegram của bạn:

```sh
ENVIO_BOT_TOKEN=
ENVIO_TELEGRAM_CHANNEL_ID=
ENVIO_TELEGRAM_MESSAGE_THREAD_ID=
ENVIO_EXPLORER_URL="https://chiliscan.com/"
ENVIO_WHALE_THRESHOLD=1000
```

#### Tạo một bot Telegram

1. Nhắn tin cho `@BotFather` trên Telegram và chạy:

   ```
   /newbot
   ```
2. Làm theo các hướng dẫn để lấy token của bot.
3. Thêm bot vào nhóm Telegram của bạn và chạy `/start`.
4. Truy cập `https://api.telegram.org/bot<YourBOTToken>/getUpdates` để tìm ID chat của nhóm.

{% hint style="success" %}
Nếu bạn đã tạo nhóm mới cùng với bot và chỉ nhận được `{"ok":true,"result":[]}`, hãy xóa bot khỏi nhóm và thêm lại.
{% endhint %}

#### Cuối cùng, cài đặt các dependency và khởi động indexer

```sh
pnpm i
pnpm envio dev
```

Với thiết lập này, bạn đã có một indexer chạy trên Envio lắng nghe các giao dịch Fan Token và đăng cảnh báo cá voi lên Telegram.

Để tiến xa hơn, bạn có thể tự host indexer hoặc triển khai lên dịch vụ hosted của Envio.

Và vì chúng ta đang lưu số dư, nó cũng có thể được sử dụng như một GraphQL balance API.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.chiliz.com/vi/phat-trien/nang-cao/thong-bao-telegram-fan-token.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
