Telegram Bot
Step-by-step Tutorial: From Raw Repo to Telegram Bot based on Aptos stream!
Let's dive into the exciting world of building a Telegram bot that sends messages based on Data Stream from Aptos Blockchain!
- Step 0: Empty Boilerplate from Go SDK
- Step 1: Raw Repo with Boilerplate ✨
- Step 2: Added Stream🌊
- Step 3: Added Filtering🧪🔍
- Step 4: Added Telegram Bot 🤖💬
Step-by-step tutorial
-
Step 0: Empty Boilerplate from Go SDK
Step 1: Raw Repo with Boilerplate✨
-
First things first, set up your own dApp in the Developer Portal and subscribe to the Apos topic. If you prefer, you can use the following Access Token:
SAAEPLBNRA56YZTG4XN674JQXJ6L5KKVNUB7XUW5YOFJXKV2PYQ2FJJ4ZU
-
To get started, clone the repository by running the following command in your shell:
git clone [email protected]:SyntropyNet/aptos-hackathon-2023.git
-
Navigate to the project directory:
cd aptos-hackathon-2023/0-GoingOn-empty-repo
-
Once you're in the right place, let's start with the basic code inStep 0: Empty Boilerplate from Go SDK
-
Connect to the NATS server by setting the NATS server address (34.107.87.29) and adding your Access Token:
- Our NATS server address:
`wss://amberdm-sandbox-b1.syntropystack.com/
- add your or our Access token:
SAAEPLBNRA56YZTG4XN674JQXJ6L5KKVNUB7XUW5YOFJXKV2PYQ2FJJ4ZU
- Our NATS server address:
-
When you run make serve, you should see the awesome message
Connected to NATS server
in your terminal! 🚀🔌`
-
-
Step 1: Raw Repo with Boilerplate✨
Step 2: Added Stream🌊
In this step, we'll subscribe to the Aptos topic (stream) and add a handler function to handle the stream. When you receive data, a cool message sayingGot msg on: syntropy.aptos.mainnet.tx
will be printed in the terminal. Exciting, right? 😄- Subscribe to Aptos topic (stream).
aptosTopic = "syntropy.aptos.mainnet.tx"
- Add a handler function to handle the stream.
service.AddHandler(aptosTopic, func(data []byte) error { return PrintData(ctx, service, data) })
-
Add the ability to print a message in the terminal.
func PrintData(ctx context.Context, service *pubsub.NatsService, data []byte) error { message := fmt.Sprintf("Got msg on: %s", aptosTopic) log.Println(message) return nil }
-
When you type
make serve
in your terminal, you should be able to see the following message every time there's data flowing:
Got msg on: syntropy.aptos.mainnet.tx
- Subscribe to Aptos topic (stream).
-
Step 2: Added Stream🌊
Step 3: Added Filtering🧪🔍
Let's enhance our code by filtering the data. We'll use the aptos.json and aptostypes.go files to work with Aptos Transaction Data. By implementing basic filtering and event-based filtering, we'll show only user transactions. The printed message will now include the sender address, receiver address, withdraw amount, and deposit amount. Time to make sense of the data and add some order! 📉💸-
Now we have the data flowing, let's have a look at the files
aptos.json
andaptostypes.go
- first one contains a raw Aptos Transaction Data, second one - "translates" it to the Go stuct, so we can easy reuse it inPrintData
function. -
Let's use
AptosTransaction
type in the PritnData functionvar aptosTx AptosTransaction if err := json.Unmarshal(data, &aptosTx); err != nil { log.Printf("ERROR: %s", err.Error()) return nil }
-
Ok, so now we can print even more in the message:
address := aptosTx.Txn.Sender depositAddr := "" depositAmount := "" withdrawAmount := ""
-
Let's do the basic filtering and show only
user_transactions
if strings.Compare(aptosTx.Txn.Type, "user_transaction") != 0 { return nil }
-
Let's filter using
events
attached to the transaction:deposit := false withdraw := false events := aptosTx.Txn.Events for _, evt := range events { t := evt.Type depositAddr = evt.GUID.AccountAddress if strings.Contains(t, "::coin::DepositEvent") { if deposit { log.Println("Multiple deposit events found!", depositAmount, depositAddr) } depositAmount = evt.Data.Amount deposit = true } if strings.Contains(t, "::coin::WithdrawEvent") { if withdraw { log.Println("Multiple withdraw events found!", withdrawAmount) } withdrawAmount = evt.Data.Amount withdraw = true } }
-
Let's print the expected message:
message := fmt.Sprintf("Got msg on: %s, sender address: %s, receiver address: %s, withdraw amount: %s, deposit amount: %s", aptosTopic, address, depositAddr, withdrawAmount, depositAmount) log.Println(message)
-
The final message in the terminal after typing
make serve
will look like this:Got msg on: syntropy.aptos.mainnet.tx, sender address: 0x1d8727df513fa2a8785d0834e40b34223daff1affc079574082baadb74b66ee4, receiver address: 0x54ad3d30af77b60d939ae356e6606de9a4da67583f02b962d2d3f2e481484e90, withdraw amount: 520400, deposit amount: 520400
-
-
Step 3: Added Filtering🧪🔍
Step 4: Added Telegram Bot 🤖💬
-
We're almost there! The Telegram bot is ready for action. No need to worry about setting it up, it's all done for you! If you want to use your own bot, talk to @botfather on Telegram and he'll guide you. For following along, join the group here: https://t.me/+cB1n8O6xerw5ODBk 😄👥
-
Input the Telegram bot and chat details:
botToken = "6203625523:AAHGYx1judXEh6sq8sOjYSVydFGxMeXgdog" chatID = -842363663
-
Create a bot instance in the main function
// Add this after the const var bot *tgbotapi.BotAPI // Paste this in main function after connecting to NATS // Create a new bot instance var err error bot, err = tgbotapi.NewBotAPI(botToken) if err != nil { log.Panic(err) }
-
Handle sending a message.
func sendTelegramMessage(message string) { msg := tgbotapi.NewMessage(chatID, message) // Send the message _, err := bot.Send(msg) if err != nil { log.Println(err) } }
-
Send a message in the PrintData function.
sendTelegramMessage(message)
-
Updated 24 days ago