So over the weekend I was working on a telegram bot whose task is to manage a particular telegram group. Wondering what the bot does?
- The bot welcomes newly added users to the telegram group
- Deletes links sent to the group by the users aside from the Admin
- Deletes every messages sent to the group by new users until they have added a certain number of users to the group and after words they can send messages to the group
In this article, I would be showing you how to create a telegram bot with Golang and Mongodb. First search for "botfather" on telegram and create a newbot. After you have set a name for you bot and a username, a token would be sent to you. This token would be used to authenticate your bot.
This is the .env config:
TOKEN=<generated token from botfather in telegram>
USER_NAME=<the group admin username>
MONGO_URI=mongodb://localhost:27017<for local host mongodb>
DATABASE_NAME=<database name>
This is the code for the bot:
package tele
import (
"encoding/json"
"fmt"
"log"
"os"
"strings"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/iqquee/telebot/database"
"go.mongodb.org/mongo-driver/bson"
)
func urlChecker(character string) bool {
var val bool
//check if the string contains a .
if strings.Contains(character, ".") {
for i, value := range character {
//get the index of .
if string(value) == "." {
fmt.Printf("%d - %v\n", i, string(value))
prev := i - 1
next := i + 1
for e, v := range character {
//check the previous character if its an "" string
if e == prev {
if string(v) != " " && string(v) != "." {
//check the next character if its an "" string
for ee, vv := range character {
if ee == next {
if string(vv) != " " && string(vv) != "." {
val = true
}
}
}
}
}
}
}
}
}
return val
}
func Bot() {
token := os.Getenv("TOKEN")
bot, err := tgbotapi.NewBotAPI(token)
if err != nil {
log.Panic(err)
}
bot.Debug = true
log.Printf("Authorized on account %s", bot.Self.UserName)
u := tgbotapi.NewUpdate(0)
u.Timeout = 60
updates := bot.GetUpdatesChan(u)
for update := range updates {
if update.Message != nil {
log.Printf("[%s] %s\n", update.Message.From.UserName, update.Message.Text)
// THESE APPLIES TO EVERYONE IN THE GROUP EXCEPT THE ADMIN OF THE GROUP
foundUser := update.Message.From.UserName
if foundUser != os.Getenv("USER_NAME") {
//welcome new users
wc := update.Message.NewChatMembers
if wc != nil {
var byt []map[string]string
jsonM, _ := json.Marshal(wc)
json.Unmarshal(jsonM, &byt)
for val := range byt {
if byt[val]["first_name"] != "" {
firstname := byt[val]["first_name"]
sendMsg := fmt.Sprintf("your message")
msg := tgbotapi.NewMessage(update.Message.Chat.ID, sendMsg)
bot.Send(msg)
}
}
}
if update.Message.NewChatMembers != nil {
up := update.Message
var addedUsers database.AddedUsers
jsonr, _ := json.Marshal(up)
json.Unmarshal(jsonr, &addedUsers)
insertID, _ := database.CreateMongoDoc(database.UserCollection, addedUsers)
fmt.Printf("Mongodb data created with ID: %v\n", insertID)
}
usersFirstname := update.Message.From.FirstName
//delete messages that contains link sent by other users aside from the admin
domain := urlChecker(update.Message.Text)
if domain {
deleteMsg := tgbotapi.NewDeleteMessage(update.Message.Chat.ID, update.Message.MessageID)
bot.Send(deleteMsg)
//notify they user that links can't be sent to the group
sendMsg := fmt.Sprintf("%s The message you sent contains a link or you failed to add a space after the full stop(.). Links cannot be sent to this group", usersFirstname)
msg := tgbotapi.NewMessage(update.Message.Chat.ID, sendMsg)
bot.Send(msg)
} else { //if the messages sent to the group is not a link
//check if the text message sent is not empty
if update.Message.Text != "" {
//check if the user have already added _ number of users to the group
countFilter := bson.M{"from.firstname": update.Message.From.FirstName}
addedUserCount := database.CountCollection(database.UserCollection, countFilter)
fmt.Printf("This is the number of users you have added to the group %v\n....", addedUserCount)
userNum := 5
if addedUserCount < userNum {
// delete the messages sent to the group by the user who have not added the set numbers of users
deleteMsg := tgbotapi.NewDeleteMessage(update.Message.Chat.ID, update.Message.MessageID)
bot.Send(deleteMsg)
fmt.Println(deleteMsg)
// and if not delete their message and notify them to first add _ numbers of users before they can send in messages
usersToAdd := userNum - addedUserCount
sendMsg := fmt.Sprintf("%s you have only added %v user(s). You need to add %v more user(s) to be able to send messages to this group. If you can't follow the process send a DM to @EXODUSTV to pay #500 and get verified to the VCF file", usersFirstname, addedUserCount, usersToAdd)
msg := tgbotapi.NewMessage(update.Message.Chat.ID, sendMsg)
// msg.ReplyToMessageID = update.Message.MessageID
bot.Send(msg)
}
}
}
}
}
}
}
This is the mongodb code:
package database
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/joho/godotenv"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var (
UserCollection *mongo.Collection = OpenCollection(Client, "users")
)
type AddedUsers struct {
From From `json:"from"`
NewChatMembers []NewChatMembers `json:"new_chat_members"`
}
type From struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
}
type NewChatMembers struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
}
func DbInstance() *mongo.Client {
if err := godotenv.Load(); err != nil {
log.Println("no env gotten")
}
MongoDb := os.Getenv("MONGO_URI")
client, err := mongo.NewClient(options.Client().ApplyURI(MongoDb))
if err != nil {
log.Fatal(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Println("successfully connected to mongodb")
return client
}
var Client *mongo.Client = DbInstance()
func OpenCollection(client *mongo.Client, collectionName string) *mongo.Collection {
if err := godotenv.Load(); err != nil {
log.Println("no env gotten")
}
databaseName := os.Getenv("DATABASE_NAME")
var collection *mongo.Collection = client.Database(databaseName).Collection(collectionName)
return collection
}
func GetMongoDoc(colName *mongo.Collection, filter interface{}) (*AddedUsers, error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var data AddedUsers
if err := colName.FindOne(ctx, filter).Decode(&data); err != nil {
return nil, err
}
return &data, nil
}
func GetMongoDocs(colName *mongo.Collection, filter interface{}, opts ...*options.FindOptions) (*[]AddedUsers, error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var data []AddedUsers
filterCusor, err := colName.Find(ctx, filter, opts...)
if err != nil {
return nil, err
}
if err := filterCusor.All(ctx, &data); err != nil {
return nil, err
}
return &data, nil
}
func CreateMongoDoc(colName *mongo.Collection, data interface{}) (*mongo.InsertOneResult, error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
insertNum, insertErr := colName.InsertOne(ctx, data)
if insertErr != nil {
return nil, insertErr
}
return insertNum, nil
}
func CountCollection(colName *mongo.Collection, filter interface{}) int {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
count, err := colName.CountDocuments(ctx, filter)
if err != nil {
return 0
}
return int(count)
}
This is the code in my main.go file:
package main
import (
"log"
"github.com/iqquee/telebot/tele"
"github.com/joho/godotenv"
)
func main() {
if err := godotenv.Load(); err != nil {
log.Println(".env not found")
}
tele.Bot()
}
After which you are done building your bot, you would need to deploy it to a server. Heroku doesn't work well with it so I would highly recommend you deploy your bot on https://railway.app. After your bot have been successfully deployed to the server, add your bot to the group you want it to manage for you and then make the bot an admin in the group. Your bot is now set :)
I hope this helps you build your own telegram bot. You can checkout this GitHub repository github.com/iqquee/telebot for the complete code.
Top comments (2)
Thanks for this
I'm glad you found this helpful