Giter VIP home page Giter VIP logo

tbot's Introduction

tbot - Telegram Bot Server GoDoc Go Report Card GitHub Actions

logo

Features

  • Full Telegram Bot API 4.7 support
  • Zero dependency
  • Type-safe API client with functional options
  • Capture messages by regexp
  • Middlewares support
  • Can be used with go modules
  • Support for external logger
  • MIT licensed

Installation

With go modules:

go get github.com/yanzay/tbot/v2

Without go modules:

go get github.com/yanzay/tbot

Support

Join telegram group to get support or just to say thank you.

Documentation

Documentation: https://yanzay.github.io/tbot-doc/.

Full specification: godoc.

Usage

Simple usage example:

package main

import (
	"log"
	"os"
	"time"

	"github.com/yanzay/tbot/v2"
)

func main() {
	bot := tbot.New(os.Getenv("TELEGRAM_TOKEN"))
	c := bot.Client()
	bot.HandleMessage(".*yo.*", func(m *tbot.Message) {
		c.SendChatAction(m.Chat.ID, tbot.ActionTyping)
		time.Sleep(1 * time.Second)
		c.SendMessage(m.Chat.ID, "hello!")
	})
	err := bot.Start()
	if err != nil {
		log.Fatal(err)
	}
}

Examples

Please take a look inside examples folder.

tbot's People

Contributors

arshamalh avatar dinalt avatar eastrocky avatar eeonevision avatar guillaumeparis2000 avatar iowar avatar kondr1 avatar samar1n avatar variar avatar yanzay avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tbot's Issues

Error

2018/09/30 14:56:23 Not Foundexit status 1

I keep getting that error for no reason

package main
import (
"log"
"os"
"github.com/yanzay/tbot"
)
func main() {
bot, err := tbot.NewServer(os.Getenv("TELEGRAM_TOKEN")) //yes i used my api
if err != nil {
log.Fatal(err)
}
bot.Handle("/answer", "42")
bot.ListenAndServe()
}

The OptParseModeMarkdown option does not work in the SendMessage function since 2.1.1

The OptParseModeMarkdown option does not work in the SendMessage function since v2.1.1

Code:

bot := tbot.New(os.Getenv("TELEGRAM_TOKEN"))
c := bot.Client()
_, err := c.SendMessage(os.Getenv("CHAT_ID"), "Hello!", tbot.OptParseModeMarkdown)
if err != nil {
  log.Fatal(err)
}

Error:

Bad Request: can't parse entities: Character '!' is reserved and must be escaped with the preceding '\'

The program runs when using v2.1.0 and below

[Concept] Tree-like router with state

Concept:

bot.HandleFunc("/", IndexHandler)
bot.HandleFunc("/profile", ProfileHandler)
bot.HandleFunc("/profile/address", AddressHandler)

User goes to /profile, gets resulting profile
User goes to /address from /profile, gets address

Features:

  • there could be routes with the same name in different subtrees
  • allow specifying human-readable (and translatable?) aliases for routes, in combination with custom keyboards it'll be useful
  • user "position" should be persistent, so if bot restarted, the user will continue navigation

Creating Polls

I'm writing a bot to manager a group, I would like to use a it to make polls with inline commands I wrote this code

`
// SendPoll returns a poll about golang language
func SendPoll(m *tbot.Message) {
question := m.Text[5:]
options := []string{
"YEp",
"Alright",
"No way",
}

go client.SendPoll(m.Chat.ID, question, options)

}
`
I'd like to know how could I use messager vars, to create the options

HandleFunc and Group Commands

Hi, currently my bot works in private chat but breaks in group chats.

Telegram sends the /command in private chat but in group chat it sends /command@botname.
Currently the best solution i have is create 2 HandleFunc, one for each name. Eg:

bot.HandleFunc("/command", doFunction, "Descr")
bot.HandleFunc("/command@Botname", doFunction, "Descr")

Does tbot currently support a better method? like wildcards in command name, or automatically ignoring @groupName after commands.

Can't make examples work

All the examples give the same error

# command-line-arguments
commands/main.go:11:13: undefined: tbot.UpdateHandler
commands/main.go:12:17: undefined: tbot.Update
commands/main.go:20:9: undefined: tbot.New
commands/main.go:24:18: m.Chat undefined (type *tbot.Message has no field or method Chat)

and here is the code

package main

import (
	"log"
	"os"
	"time"

	"github.com/yanzay/tbot"
)

func stat(h tbot.UpdateHandler) tbot.UpdateHandler {
	return func(u *tbot.Update) {
		start := time.Now()
		h(u)
		log.Printf("Handle time: %v", time.Now().Sub(start))
	}
}

func main() {
	bot := tbot.New(os.Getenv("TELEGRAM_TOKEN"))
	c := bot.Client()
	bot.Use(stat) // add stat middleware to bot
	bot.HandleMessage("", func(m *tbot.Message) {
		c.SendMessage(m.Chat.ID, "hello!")
	})
	err := bot.Start()
	if err != nil {
		log.Fatal(err)
	}
}

The same is with the example from the Readme.md

Using library on Google Cloud Functions

Hi,

I'm trying to use this library on GCF, but I'm missing a point.... (I'm new on Golang...)

The function on GCF come with his own request, so I guess I shouldn't call "bot.Start" to start listening for incoming data... isn't it ?

I guess I should convert the request into a Message struct, isn't it ?

Am I missing some point ?

can't send file with MessageDocument type

func (s *Server) SendFile(chatID int64, filepath string) error {
	//return s.bot.Send(&model.Message{Type: model.MessageDocument, ChatID: chatID, Data: filepath})
	return s.bot.Send(&model.Message{Type: model.MessagePhoto, ChatID: chatID, Data: filepath})
	
}

MessageDocument don't work insted of sending document it sent just it filename
but MessagePhoto works good.

Bot is not working inside docker container

Hello and first of all thank you for your great work!
This package is really pleasant to use even with no prior expirience in building Telegram bots.

Recently i was trying to package my bot inside docker container and faced some strange behaviour.
What expected: compiled binary of the bot could be run inside docker container.
What got: container builds and runs with no errors but the bot is not responding to updates.

Steps to reproduce with code from examples/basic/main.go:

  1. build binary on the host as usual:
    go build -v -o test
  2. test if our bot works when running on host:
    export TELEGRAM_TOKEN=realTelegramTokenHere && ./test
    In my tests this works and the bot replies to messages.

If the bot works correctly on the host, we can proceed to the next step.

  1. write simple Dockerfile in the same directory as binary:
FROM ubuntu
WORKDIR /bot
COPY ./test ./test
CMD ["/bot/test"]

I'm using Ubuntu as my OS so the same binary could be run on the host and in container. If host OS is not GNU/Linux we need to use two stage Dockerfile to build inside temporary container:

FROM golang AS buildstage
WORKDIR /src
COPY *.go go.mod ./
RUN go mod tidy && go build -v -o /out/test .
FROM ubuntu
WORKDIR /bot
COPY --from=buildstage /out/test ./test
CMD ["/bot/test"]

and build the container:
docker build --no-cache -t testbot .
4. now we can test if the bot works from container:
docker run --name=testbot --rm -it -e TELEGRAM_TOKEN=realTelegramTokenHere testbot

When running inside the container bot does not replies to messages even if we use the binary that works on the host machine.
Tried different hosts, changing docker network settings to --network=host but no luck.
Since we are using ubuntu container it is possible to exec bash in it, install curl and try to make direct requests to Telegram api.
In my tests getMe and getUpdates requests work perfectly so this should be not network related issue.

How to use InlineKeyboard

Hi, I'm trying to have send a message with buttons bellow it.
there wasn't any example about this.
I don't know how to implement this with callback buttons.
can you help?

User struct

Some users hasn't set up their usernames, this is causing some problems. We need receive whole info about user to prevent problems.

upload file

Can you provide an example of how to handle upload file/picture from user?
in the previous version there was a function HandleFile(), in this it is not

Newbie question: How to handle a series of questions

this is not really an issue. I am the issue myself.
I am learning how to develop in Go and got your example code running. It's so convenient!
I was planning to make a scavenger hunt game in telegram. This would mean that the player would get a riddle, and give the correct answer. If the answer is correct he will get another question. (similar to a pizza ordering app: question1: "what would you like to order", question 2:"would you like toppings" ,etc)

I am a bit confused how I would do that. Would I need to use a series of:
bot.HandleMessage(pattern string, handler func(*tbot.Message)). So for every question a handler?

or just one HandleMessage, and have just one handler function that everytime parses the message and keeps track how far this user is?

I apologize if this not the proper channel for asking this.

Cannot install and use the library

Hi everyone, I'm trying to install the library:
go get github.com/yanzay/tbot/v2
but it gaves me the following error:

package github.com/yanzay/tbot/v2: cannot find package "github.com/yanzay/tbot/v2" in any of:
        /usr/local/go/src/github.com/yanzay/tbot/v2 (from $GOROOT)
        /root/work/src/github.com/yanzay/tbot/v2 (from $GOPATH)

I'm on a Debian 9 machine and other libraries works perfect.
What can I do to solve this error?

Crash when post edited command

the bot will crash if I re-post "edited" last command

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x12cd942]

goroutine 52 [running]:
github.com/yanzay/tbot/internal/adapter.(*Bot).adaptUpdates(0xc0000ac098, 0xc0000aea20, 0xc000082060)
/Users/sandy/.go/pkg/mod/github.com/yanzay/[email protected]/internal/adapter/adapter.go:74 +0x112
created by github.com/yanzay/tbot/internal/adapter.(*Bot).GetUpdatesChan
/Users/sandy/.go/pkg/mod/github.com/yanzay/[email protected]/internal/adapter/adapter.go:57 +0x174
exit status 2

Method bot.Stop doesn't work

package main

import (
	"log"
	"os"
	"os/signal"

	"github.com/yanzay/tbot/v2"
)

func main() {
	bot := tbot.New(os.Getenv("TELEGRAM_TOKEN"),
		tbot.WithLogger(tbot.BasicLogger{}),
		tbot.WithWebhook("https://test.com", ":8080"))
	c := bot.Client()
	bot.HandleMessage("ping", func(m *tbot.Message) {
		c.SendMessage(m.Chat.ID, "pong")
	})

	go func() {
		shutdown := make(chan os.Signal, 1)
		signal.Notify(shutdown)
		s := <-shutdown
		log.Printf("Got a %s signal", s)

		bot.Stop()
		log.Print("bot.Stop was finished")
	}()

	err := bot.Start()
	if err != nil {
		log.Fatalf("bot.Start failed, %v", err)
	}

	log.Print("Bot is shut down")
}

I've found that method bot.Stop is blocked on write to Server.stop channel because channel Server.stop is not initialized anywhere.

If this program is terminated using CTRL+Z it doesn't finish correctly.

maks@maks-Aspire-E5-575G:~/projects/go/src/github.com/yanzay/tbot/examples/webhook_fail$ go run main.go 
^Z2019/05/19 01:29:54 Got a stopped signal
[1]   Killed                  go run main.go
[2]   Killed                  go run main.go
[3]+  Stopped                 go run main.go
maks@maks-Aspire-E5-575G:~/projects/go/src/github.com/yanzay/tbot/examples/webhook_fail$ lsof -i -P -n | grep LISTEN
kdeconnec  2169 maks   12u  IPv6  33023      0t0  TCP *:1716 (LISTEN)
java       3147 maks  182u  IPv4  38266      0t0  TCP 127.0.0.1:6942 (LISTEN)
java       3147 maks  335u  IPv4  40063      0t0  TCP 127.0.0.1:63342 (LISTEN)
main      11204 maks    5u  IPv6 237875      0t0  TCP *:8080 (LISTEN)
maks@maks-Aspire-E5-575G:~/projects/go/src/github.com/yanzay/tbot/examples/webhook_fail$ ps axuf | grep main
maks     11145  0.0  0.2 784320 20648 pts/9    Tl   01:29   0:00  |           \_ go run main.go
maks     11204  0.0  0.1 861800 12172 pts/9    Sl   01:29   0:00  |           |   \_ /tmp/go-build969432621/b001/exe/main

show_alert

how to correctly set show_alert = true in reply method?

crash

when bot added to channel and bot recieves message like @examplebot /hi

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x65b7a2]

goroutine 50 [running]:
github.com/yanzay/tbot/internal/adapter.(*Bot).adaptUpdates(0xc42000e028, 0xc420102600, 0xc42026cd80)
        /home/vtolstov/go/src/github.com/yanzay/tbot/internal/adapter/adapter.go:74 +0x122
created by github.com/yanzay/tbot/internal/adapter.(*Bot).GetUpdatesChan
        /home/vtolstov/go/src/github.com/yanzay/tbot/internal/adapter/adapter.go:57 +0xee

Support Casbin as the authorization module

Hi, Casbin is an authorization library that supports models like ACL, RBAC, ABAC.

Related to RBAC, Casbin has several advantages:

  1. roles can be cascaded, aka roles can have roles.
  2. support resource roles, so users have their roles and resource have their roles too. role = group here.
  3. the permission assignments (or policy in Casbin's language) can be persisted in files or database (MySQL and Cassandra).

And you can even customize your own access control model, for example, mix RBAC and ABAC together by using roles and attributes at the same time. It's very flexible.

Casbin can provide more flexibility and security than the current while-list auth. I can make PR if needed. Let me know if there's any question:) Thanks.

Library not working in groups

Hello, I made this bot t.me/covidata19bot that monitors the pandemic data in Italy using your library, but when it comes to work in groups it doesn't work.

So, I wanted to be sure that none of my code was involved in the problem, then I used your cowsay example as test.
Here is what I tried:

  • if you create a private group and you put the bot in, it works.
  • if you convert this group into a public one the bot doesn't work anymore
  • if you convert this group again into a private one the bot still doesn't work.

Further, if you add the bot in a group that was previously a public one, it doesn't work from the start (so as in the steps just listed, it works only when the group has never been public yet).
The privacy settings in BotFather are set to enable the bot to access messages in groups.

Now, this happens if the bot runs on a Raspberry Pi 3, but if you are on a computer the situation completely changes.
So, suppose I am running the cowsay bot on Pi 3, I send messages to the bot in my group and it doesn't answer.
I turn it off.
Now I run the same bot from my computer (obviously compiled for my architecture).
All unanswered requests are now answered.

So, what causes this very important issue on this library?

Option to check connection

In the current version you can not check if bot has actually connected to the sever or not/
Even if you supply empty token, it starts and runs without problem
Would be awesome to have some method to check if bot hasn connected

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.