> 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/th/phatthana/sung-khuen/telegram-fan-token.md).

# แจ้งเตือน Telegram สำหรับ Fan Token

การติดตามการโอน Fan Token™ ที่เกิดขึ้นบน Chiliz Chain เป็นวิธีที่ดีในการติดตามข่าวสารเกี่ยวกับการเคลื่อนไหวมูลค่าสูง และแจ้งให้ชุมชนของคุณทราบ

ด้วยการตั้งค่าและโค้ดเพียงเล็กน้อย คุณสามารถตั้งค่าบอท Telegram เพื่อแจ้งเตือนกลุ่มทุกครั้งที่การโอน Fan Token™ เกินเกณฑ์ที่กำหนด

## วิธีทำโดยใช้ Envio?

[Envio](https://envio.dev/) เป็นเครื่องมือ indexing ที่มีประสิทธิภาพ ช่วยให้นักพัฒนาสามารถรับฟัง event ของ smart contract บน Chiliz และดำเนินการตาม event นั้นได้

ในบทแนะนำนี้ คุณจะได้เรียนรู้วิธีตั้งค่าบอท จับ event ที่เกี่ยวข้อง และทริกเกอร์การแจ้งเตือน Telegram โดยอัตโนมัติ เพื่อเปลี่ยนการตั้งค่าของคุณให้เป็น "whale watcher" สำหรับการโอนขนาดใหญ่

### ขั้นตอนที่ 1: ติดตั้งข้อกำหนดเบื้องต้น

ก่อนเริ่มต้น ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง [เครื่องมือที่จำเป็น](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" %}
โปรเจกต์เต็มรูปแบบสามารถพบได้ [บน GitHub repository นี้](https://github.com/DenhamPreen/fc-barce-fan-token-indexer/tree/main)
{% endhint %}

### ขั้นตอนที่ 2: เริ่มต้น Envio Indexer

รันคำสั่งต่อไปนี้เพื่อเริ่มต้น Envio indexer และทำตามคำแนะนำเพื่อสร้าง template ERC-20 บน Chiliz Chain (ซึ่งเป็น blockchain ที่รองรับ EVM):

```bash
pnpx envio init
```

นี่คือตัวเลือกต่างๆ ที่คุณควรเลือกเมื่อได้รับคำถาม:

<figure><img src="/files/2s9JAUTPrFxGAcLx5NUJ" alt=""><figcaption></figcaption></figure>

### ขั้นตอนที่ 3: ตั้งค่า `config.yaml`

แก้ไขไฟล์ `config.yaml` เพื่อระบุ address ของสัญญา FC Barcelona Fan Token™ (หรือ Fan Token™ อื่นที่คุณต้องการติดตาม):

{% 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 %}

**หมายเหตุ:** เราลบ event `approval` ออกเนื่องจากสนใจเฉพาะการโอนเท่านั้น

### ขั้นตอนที่ 4: ลดความซับซ้อนของ GraphQL Schema

แก้ไขไฟล์ `schema.graphql` เพื่อติดตามเฉพาะยอดคงเหลือของบัญชี:

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

ณ จุดนี้ เรามี ERC-20 indexer ที่คอยรับฟัง event แล้ว

ตอนนี้มาเพิ่มลอจิกสำหรับส่งการแจ้งเตือน Telegram กัน

### ขั้นตอนที่ 5: สร้างลอจิกการแจ้งเตือน Telegram

แก้ไขไฟล์ `/src/EventHandlers.ts` เพื่อเพิ่มลอจิกสำหรับตรวจจับการโอนขนาดใหญ่และส่งการแจ้งเตือน 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" %}
โฟลเดอร์ `/libs/` ตัวอย่างสามารถพบได้ [ที่นี่บน GitHub](https://github.com/DenhamPreen/fc-barce-fan-token-indexer/tree/main/src/libs) รวมถึงไฟล์ `helpers.ts` และ `ens.ts`
{% endhint %}

### ขั้นตอนที่ 6: ตั้งค่า Constants

สร้างไฟล์ `constants.ts` เพื่อเก็บตัวแปร environment:

{% 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 %}

### ขั้นตอนที่ 7: ส่งข้อความ Telegram

ติดตั้ง [Axios HTTP client](https://axios-http.com/):

```bash
pnpm i axios
```

สร้างฟังก์ชันช่วยเหลือใน `libs/telegram.ts` เพื่อส่งข้อความโดยใช้ 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 %}

### ขั้นตอนที่ 8: การตั้งค่าขั้นสุดท้ายและการรัน Indexer

#### ตั้งค่าไฟล์ `.env`

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

แก้ไข `.env` ด้วยข้อมูลประจำตัวบอท Telegram ของคุณ:

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

#### สร้างบอท Telegram

1. ส่งข้อความหา `@BotFather` บน Telegram และรัน:

   ```
   /newbot
   ```
2. ทำตามคำแนะนำเพื่อรับ token ของบอท
3. เพิ่มบอทเข้ากลุ่ม Telegram ของคุณและรัน `/start`
4. เข้าไปที่ `https://api.telegram.org/bot<YourBOTToken>/getUpdates` เพื่อค้นหา ID ของกลุ่มแชท

{% hint style="success" %}
หากคุณสร้างกลุ่มใหม่พร้อมกับบอทและได้รับเฉพาะ `{"ok":true,"result":[]}` ให้ลบบอทออกแล้วเพิ่มเข้ากลุ่มใหม่อีกครั้ง
{% endhint %}

#### สุดท้าย ติดตั้ง dependencies และเริ่มต้น indexer

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

ด้วยการตั้งค่านี้ คุณมี indexer ที่ขับเคลื่อนโดย Envio ซึ่งคอยรับฟังการโอน Fan Token และส่งการแจ้งเตือน whale ไปยัง Telegram แล้ว

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

หากต้องการก้าวไปอีกขั้น คุณสามารถ self-host indexer หรือ deploy ไปยังบริการ hosted ของ Envio ได้

และเนื่องจากเราบันทึกยอดคงเหลือไว้ จึงสามารถใช้เป็น 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/th/phatthana/sung-khuen/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.
