Giter VIP home page Giter VIP logo

telegram-bot-api's People

Contributors

733amir avatar alexandear avatar arman92 avatar bcmk avatar dmitriy-kharchenko avatar emadgh avatar erikpelli avatar gobwas avatar henner25 avatar ilyakaznacheev avatar jqs7 avatar m90 avatar mamal72 avatar mr-linch avatar mryadro avatar nemod503 avatar pr0head avatar quenbyako avatar raulsntos avatar ros-tel avatar rozha avatar savely-krasovsky avatar sirlori avatar syfaro avatar temamagic avatar tjhorner avatar yi-jiayu avatar zergon321 avatar zhuharev avatar zhulik 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  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

telegram-bot-api's Issues

Question : making keyboard button with loop

First of all, It is not an issue though but I really hard to work on making keyboard button.
But sadly, I could not make it. it is beyond my ability, so i am posting this article for any help or tips.
i want to make keyboard buttons from data that from looping.
One data get one button row.
like

data1

data2

data3

Any help or tips would be great for me. thanks.

Unable to retrieve full error information from APIResponse

When a request fails, the Telegram API responds with some useful information in error_code, description, and parameters as per https://core.telegram.org/bots/api#making-requests

Unfortunately, this line of code prevents reading anything from the returned api response other than the description as passed through the error:

return APIResponse{}, errors.New(apiResp.Description)

The most obvious fix would be to change the returned empty struct APIResponse{} to the retrieved apiResp on that line.

This will this flow on to other functions such as AnswerInlineQuery, AnswerCallbackQuery, etc that simply return bot.MakeRequest() directly.

413 Request Entity Too Large

I'm failing to send a document or a video which is considered not too small, something like ~60Mb, with the debug set to true, the following lines will be shown:

<html>
<head><title>413 Request Entity Too Large</title></head>
<body bgcolor="white">
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>nginx/1.9.1</center>
</body>
</html>

the code

package main

import (
    "log"

    "github.com/Syfaro/telegram-bot-api"
)

func main() {
    bot, err := tgbotapi.NewBotAPI("DatToken")
    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, err := bot.GetUpdatesChan(u)

    for update := range updates {
        log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

        msg := tgbotapi.NewDocumentUpload(update.Message.Chat.ID, "NotTooSmallOfaFile")

        bot.Send(msg)
    }
}

SendVideo doesn't work for iPhone

the testing has been done with the following code.

package main

import (
    "log"

    "github.com/Syfaro/telegram-bot-api"
)

func main() {
    bot, err := tgbotapi.NewBotAPI("YourAwesomeAPIToken")
    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

    err = bot.UpdatesChan(u)
    if err != nil {
        log.Panic(err)
    }

    videofile := "1.mp4"
    for update := range bot.Updates {
        log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

        msg := tgbotapi.NewMessage(update.Message.Chat.ID, "video on the way")
        msg.ReplyToMessageID = update.Message.MessageID

        bot.SendMessage(msg)

        newVid := tgbotapi.NewVideoUpload(update.Message.Chat.ID, videofile)
        if _, err := bot.SendVideo(newVid); err != nil {
            log.Panic(err)
        }
    }
}

I tested sending videos with multiple mp4 files and they all show the same behavior, when the bot sends them they will have no thumbnail, and the time of the video will be 00:00, also I should mention that on the iPhone Telegram app they can not be played!, it will just show a black background, on the OS X client it will work, but as I said, no thumbnail and no time.

I don't think that this is an API issue, because the OS X client handles them perfectly, using the drop-in feature it will ask you to send them with compression or "in a quick way", if you choose without compression I believe it will send them as a document, with the compression they'll be okay.

for testing you could download this http://i.imgur.com/CGaKrhh.gifv

Commands handling?

That would be very interesting. There are various cases, like if you message a bot in a group and send him "/command@bot".

Sending GIFs

Is there any way to send GIFs via this package right now? I tried using tgbotapi.NewPhotoUpload but this is just sending a normal image.

NewMessage string support

NewMessage accepts chatID only in int64 format while the API method sendMessage supports Integer or String.

Is there a workaround for this? Looks like only UploadFile supports map format....

Panic: runtime error

Hello, I'm tried use the telegram-bot-api but without success.

My code is the same example of README.

Steps to reproduce the error:

Go: 1.7.3

go run main.go

Log:

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

goroutine 37 [running]:
panic(0x6213c0, 0xc42000c130)
	/home/fguedes/go/go/src/runtime/panic.go:500 +0x1a1
net/http.(*Client).deadline(0x0, 0xc42002c020, 0x8900000000000000, 0x8)
	/home/fguedes/go/go/src/net/http/client.go:193 +0x26
net/http.(*Client).doFollowingRedirects(0x0, 0xc4203723c0, 0x683bb0, 0x66bf9d, 0x21, 0xc4203f4200)
	/home/fguedes/go/go/src/net/http/client.go:446 +0x8b
net/http.(*Client).Post(0x0, 0xc42039c270, 0x27, 0x66bf9d, 0x21, 0x75e220, 0xc4203f4200, 0x40, 0xc42039c270, 0x27)
	/home/fguedes/go/go/src/net/http/client.go:579 +0xe2
net/http.(*Client).PostForm(0x0, 0xc42039c270, 0x27, 0xc42039c240, 0x2, 0xc42039c270, 0x27)
	/home/fguedes/go/go/src/net/http/client.go:605 +0xdd
gopkg.in/telegram-bot-api%2ev4.(*BotAPI).MakeRequest(0xc4200e2060, 0x665077, 0xa, 0xc42039c240, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/home/fguedes/go/gandalf/src/gopkg.in/telegram-bot-api.v4/bot.go:60 +0x1b8
gopkg.in/telegram-bot-api%2ev4.(*BotAPI).GetUpdates(0xc4200e2060, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0)
	/home/fguedes/go/gandalf/src/gopkg.in/telegram-bot-api.v4/bot.go:386 +0xc8
gopkg.in/telegram-bot-api%2ev4.(*BotAPI).GetUpdatesChan.func1(0xc4200e2060, 0xc4203f41a0, 0xc4200e2180)
	/home/fguedes/go/gandalf/src/gopkg.in/telegram-bot-api.v4/bot.go:456 +0x72
created by gopkg.in/telegram-bot-api%2ev4.(*BotAPI).GetUpdatesChan
	/home/fguedes/go/gandalf/src/gopkg.in/telegram-bot-api.v4/bot.go:472 +0xa9

Anyone can help me?

FAIL gopkg.in/telegram-bot-api.v4 [build failed]

tag v4.1.0

$ go test -v      
bot/src/gopkg.in/telegram-bot-api.v4  
# gopkg.in/telegram-bot-api.v4_test
./helpers_test.go:60: undefined: tgbotapi.NewInlineQueryResultAudio
./helpers_test.go:71: undefined: tgbotapi.NewInlineQueryResultVoice
./helpers_test.go:82: undefined: tgbotapi.NewInlineQueryResultDocument
./helpers_test.go:94: undefined: tgbotapi.NewInlineQueryResultLocation
FAIL    gopkg.in/telegram-bot-api.v4 [build failed]

Allow negative offset when getting updates

The Telegram API allows to specify a negative offset ("The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue."), but (bot *BotAPI) GetUpdates accepts only a positive offset:

if config.Offset > 0 { 
    v.Add("offset", strconv.Itoa(config.Offset))
}

More flexible logging options

At the moment this library does not allow a developer to replace the golang default log package to capture logs to redirect to say syslog as is common with services.

This is mainly apparent in the UpdatesChan goroutine when an error occurs during the poll.

Send photo by url

If I use

file := "http://...../img.jpg"
msg := tgbotapi.NewPhotoUpload(update.Message.Chat.ID, file)
bot.Send(msg)

I got "Bad Request: there is no photo in the request"

If I use

file := "http://...../img.jpg"
msg := tgbotapi.NewPhotoUpload(update.Message.Chat.ID, nil)
msg.FileID = file
bot.Send(msg)

I got "open ...: no such file or directory"

but if I use

file := "http://...../img.jpg"
msg := tgbotapi.NewPhotoUpload(update.Message.Chat.ID, nil)
msg.FileID = file
msg.UseExisting = true
bot.Send(msg)

all works

It may be possible to make to support this method in NewPhotoUpload if last argument is url?

Markdown has a limit ?

This is probably unrelated to tgbotapi but I'm not sure what's causing this issue, could be telegram's markdown parser ?

while running the following:

package main

import (
    "fmt"
    "log"

    "gopkg.in/telegram-bot-api.v4"
)

func main() {
    bot, err := tgbotapi.NewBotAPI("ThatAwesomeToken")
    if err != nil {
        log.Panic(err)
    }

    log.Printf("Authorized on account %s", bot.Self.UserName)

    u := tgbotapi.NewUpdate(0)
    u.Timeout = 60

    updates, err := bot.GetUpdatesChan(u)

    for update := range updates {
        if update.Message == nil {
            continue
        }

        log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

        var text string
        for i := 1; i < 35; i++ {
            text += fmt.Sprintf("*%d*- *%s*, `%s`\n", i, "Hello", "World!")
        }
        fmt.Println(len(text))
        msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)

        msg.ParseMode = "markdown"
        bot.Send(msg)
    }
}

it'll just respond with 34 <n> Hello, World! with some markdown. notice that all of them will be correctly formatted until the 34th, after the 34th the markdown will vanish!

screen shot 2016-07-08 at 2 34 52 am

choosing the right type for uploading

I'm having a bytes.Buffer with a photo in it, trying to send &bytes.Buffer will hit bad file type, I'm not sure what to use to get a FileBytes or FileReader, google did not help :-/

    switch f := file.(type) {
    case string:
        fileHandle, err := os.Open(f)
        if err != nil {
            return APIResponse{}, err
        }
        defer fileHandle.Close()

        fi, err := os.Stat(f)
        if err != nil {
            return APIResponse{}, err
        }

        ms.WriteReader(fieldname, fileHandle.Name(), fi.Size(), fileHandle)
    case FileBytes:
        buf := bytes.NewBuffer(f.Bytes)
        ms.WriteReader(fieldname, f.Name, int64(len(f.Bytes)), buf)
    case FileReader:
        if f.Size != -1 {
            ms.WriteReader(fieldname, f.Name, f.Size, f.Reader)

            break
        }

        data, err := ioutil.ReadAll(f.Reader)
        if err != nil {
            return APIResponse{}, err
        }

        buf := bytes.NewBuffer(data)

        ms.WriteReader(fieldname, f.Name, int64(len(data)), buf)
    default:
        return APIResponse{}, errors.New("bad file type")
    }

Panic when sending Photo by URL

Trying to send a Photo by URL results in nil pointer dereference

This is the panic:

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

goroutine 52 [running]:
panic(0x6224a0, 0xc42000c0d0)
        /usr/lib/go/src/runtime/panic.go:500 +0x1a1
io.(*multiReader).Read(0xc42023c1a0, 0xc4204572e7, 0x44, 0xd19, 0x1cc, 0x0, 0x0)
        /usr/lib/go/src/io/multi.go:20 +0x98
io/ioutil.(*nopCloser).Read(0xc42022a270, 0xc4204572e7, 0x44, 0xd19, 0x1cc, 0x0, 0x0)
        <autogenerated>:4 +0x6b
io.(*LimitedReader).Read(0xc420376640, 0xc4204572e7, 0xd19, 0xd19, 0x1cc, 0x0, 0x0)
        /usr/lib/go/src/io/io.go:436 +0x6c
bufio.(*Writer).ReadFrom(0xc420322f80, 0x75f9e0, 0xc420376640, 0xc4200fcbb8, 0x1, 0x18)
        /usr/lib/go/src/bufio/bufio.go:693 +0xcc
io.copyBuffer(0x75f660, 0xc420322f80, 0x75f9e0, 0xc420376640, 0x0, 0x0, 0x0, 0x631bc0, 0x1, 0xc420376640)
        /usr/lib/go/src/io/io.go:384 +0x323
io.Copy(0x75f660, 0xc420322f80, 0x75f9e0, 0xc420376640, 0xf, 0xc420379100, 0x581d02)
        /usr/lib/go/src/io/io.go:360 +0x68
net/http.(*transferWriter).WriteBody(0xc4202fa7e0, 0x75f660, 0xc420322f80, 0x2, 0x2)
        /usr/lib/go/src/net/http/transfer.go:227 +0x677
net/http.(*Request).write(0xc4200c01e0, 0x75f660, 0xc420322f80, 0x0, 0xc420365890, 0x0, 0x0, 0x0)
        /usr/lib/go/src/net/http/request.go:565 +0x778
net/http.(*persistConn).writeLoop(0xc420474300)
        /usr/lib/go/src/net/http/transport.go:1649 +0x1ac
created by net/http.(*Transport).dialConn
        /usr/lib/go/src/net/http/transport.go:1063 +0x50e
exit status 2

This is my code:

package main

import (
        "log"
        "github.com/go-telegram-bot-api/telegram-bot-api"
        "net/url"
)

func main() {
        bot, err := tgbotapi.NewBotAPI("pls enter some token here")
        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, err := bot.GetUpdatesChan(u)

        url_ptr, _ := url.Parse("https://assets-cdn.github.com/images/modules/site/home-ill-platform.png")
        url := *url_ptr

        for update := range updates {
                if update.Message == nil {
                        continue
                }
                log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
                msg := tgbotapi.NewPhotoUpload(update.Message.Chat.ID, url)
                bot.Send(msg);
        }
}

The panic is caused by this line:

res, err := bot.Client.Do(req)

The panic only happens when sending a Photo via URL, if NewPhotoUpload is called with file path, no panic happens and the Photo is sent correctly.

Are all structs serializable?

Since the telegram group is not working I ask it here.

We have updates that we receive and chattables that we send and messages which are the result of sending chattables. But chattables are private interfaces which made me suspect if they have also private state.

Can we serialize Update, Message and Chattables to/from JSON safely?

BUTTON_TYPE_INVALID

Bad Request: BUTTON_TYPE_INVALID if I try remove InlineKeyboard in message by this code:

edit := tgbotapi.NewEditMessageReplyMarkup(
    callback.Message.Chat.ID,
    callback.Message.MessageID,
    tgbotapi.InlineKeyboardMarkup{},
)
bot.Send(edit)

P.S.: Also, as and with this variant:

var markup tgbotapi.InlineKeyboardMarkup
edit := tgbotapi.NewEditMessageText(
    callback.Message.Chat.ID,
    callback.Message.MessageID,
    "sample text",
)
edit.ReplyMarkup = &markup
bot.Send(edit)

Not possible edit message by InlineMessageId

When we set InlineMessageId in BaseEdit struct of EditMessageTextConfig , values of ChatID and MessageID not omitted and sets to 0. This gives Chat not found error. We need test InlineMessageId existence in BaseEdit.values func and Add either inline_message_id or chat_id and message_id

HTTP server

Create an internal HTTP server to get webhooks (only started when needed), and provide updates with the Updates chan.

No keyboard in edit messages

On new message keyboard show, on inline not.

package main

import (
    "log"
    "strconv"

    "github.com/go-telegram-bot-api/telegram-bot-api"
)

func main() {
    bot, err := tgbotapi.NewBotAPI("")
    if err != nil {
        log.Panic(err)
    }

    bot.Debug = true

    u := tgbotapi.NewUpdate(0)
    u.Timeout = 60

    updates, err := bot.GetUpdatesChan(u)
    lastid := 0
    for update := range updates {
        if lastid != 0 && update.CallbackQuery != nil {
            msg := tgbotapi.NewEditMessageText(update.CallbackQuery.Message.Chat.ID, lastid, "li:"+strconv.Itoa(lastid))
            butt := tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Next 2", "next"))
            keyb := tgbotapi.NewInlineKeyboardMarkup(butt)
            msg.ReplyMarkup = &keyb
            sm, _ := bot.Send(msg)
            lastid = sm.MessageID
        } else if update.Message != nil {
            msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
            butt := tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Next 1", "next"))
            keyb := tgbotapi.NewInlineKeyboardMarkup(butt)
            msg.ReplyMarkup = &keyb
            sm, _ := bot.Send(msg)
            lastid = sm.MessageID
        }
    }
}

I made for myself corrections, but not sure that they are correct:

diff --git a/configs.go b/configs.go
index 64a88e4..85310bf 100644
--- a/configs.go
+++ b/configs.go
@@ -560,7 +560,6 @@ type EditMessageTextConfig struct {
        Text                  string
        ParseMode             string
        DisableWebPagePreview bool
-       ReplyMarkup           *InlineKeyboardMarkup
 }

 func (config EditMessageTextConfig) values() (url.Values, error) {
@@ -580,8 +579,7 @@ func (config EditMessageTextConfig) method() string {
 // EditMessageCaptionConfig allows you to modify the caption of a message.
 type EditMessageCaptionConfig struct {
        BaseEdit
-       Caption     string
-       ReplyMarkup *InlineKeyboardMarkup
+       Caption string
 }

 func (config EditMessageCaptionConfig) values() (url.Values, error) {
@@ -600,7 +598,6 @@ func (config EditMessageCaptionConfig) method() string {
 // of a message.
 type EditMessageReplyMarkupConfig struct {
        BaseEdit
-       ReplyMarkup *InlineKeyboardMarkup
 }

 func (config EditMessageReplyMarkupConfig) values() (url.Values, error) {
diff --git a/helpers.go b/helpers.go
index 6af3e65..d6e6a38 100644
--- a/helpers.go
+++ b/helpers.go
@@ -421,10 +421,10 @@ func NewEditMessageCaption(chatID int64, messageID int, caption string) EditMess
 func NewEditMessageReplyMarkup(chatID int64, messageID int, replyMarkup InlineKeyboardMarkup) EditMessageReplyMarkupConfig {
        return EditMessageReplyMarkupConfig{
                BaseEdit: BaseEdit{
-                       ChatID:    chatID,
-                       MessageID: messageID,
+                       ChatID:      chatID,
+                       MessageID:   messageID,
+                       ReplyMarkup: &replyMarkup,
                },
-               ReplyMarkup: &replyMarkup,
        }
 }

Update to support Webhook responses

From telegram bot api official page:

Recent changes

August 29, 2015
You can now make new requests when responding to webhook updates.

Would be cool to have a helper method to ease this task.

APIResponse contents discarded other than Result

I've been having an issue with a Telegram Bot silently failing to send messages intermittently. The SendPhoto function is returning error == nil in such cases indicating no failure occurred but the message has not delivered.

While looking into what could cause a nil error while still having an error I noticed that the APIResponce returned by MakeRequest is not checked at all, more specifically the Ok and ErrorCode fields.

While I haven't monkeypatched anything in yet to see if the server is rejecting my sent messages gracefully, it seems like this library should be checking the values or at least making the APIResponse accessible to the user user code if required.

Memory leak

Sending large files with SendDocument or SendVideo will result in high memory usage, and after the file done sending, this memory won't get freed

consider the following code

package main

import (
    "log"

    "github.com/Syfaro/telegram-bot-api"
)

func main() {
    bot, err := tgbotapi.NewBotAPI("MyAwesomeToken")
    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

    err = bot.UpdatesChan(u)
    if err != nil {
        log.Panic(err)
    }

    filename := "file.dat" // ~33Mb, should be fairly a big file to notice
    for update := range bot.Updates {
        log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

        msg := tgbotapi.NewMessage(update.Message.Chat.ID, "the file on its way")
        msg.ReplyToMessageID = update.Message.MessageID
        bot.SendMessage(msg)

        newDoc := tgbotapi.NewDocumentUpload(update.Message.Chat.ID, filename)
        if _, err := bot.SendDocument(newDoc); err != nil {
            log.Panic(err)
        }

    }
}

Now running this bot on OS X will start with 8.2 MB of Real Mem "according to Activity Monitor"
after sending the first message, the bot will start sending file.dat, Real Mem will jump to 107.6 MB it will finish sending but it will not free the memory, requesting the file again will rise Real Mem again to 180 MB ... etc

I took a look at the code and I figured it has to be in the UploadFile method, and I found that a usage to os.Open() bond to a variable called f hasn't get closed, I tried closing it, but it did not solve the problem.

Improvement: Option to stop the update loop of the bot

This is a proposal for a feature which will allow a user to stop the update loop (the goroutine) that is created on a call to GetUpdatesChan.

Rationale

The rationale behind this request is to allow safe cleaning of a bot listener created with the polling method, without killing the whole program.

Use case

An example for such a need would be in an application which starts multiple listeners for different bots, and from time to time needs to stop some of them, and listen to new ones, according to a configuration.
What would happen currently is there is currently no way to stop a bot update loop - a user can use goroutines, and exit them according to some signal in his application, but the update loop will still run internally, and if in the future the user will try to create a listener to the same bot, he will get conflicts on calls to the Telegram API.

Solution

I've written code that allows to do that, and will submit a PR, hope it'll get accepted as I think this is a useful feature, anyways, if it's not implemented good enough we can discuss how it should be implemented here :)

Why this example will not work

our project is github.com/pyed/example contains one package telegram that uses telegram-bot-api and a main.go

$GOPATH/src/github.com/pyed/example
├── main.go
└── telegram
    └── telegram.go

telegram/telegram.go

package telegram

import (
    "log"

    "github.com/Syfaro/telegram-bot-api"
)

var Bot *tgbotapi.BotAPI

func init() {
    Bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken")
    if err != nil {
        log.Panic(err)
    }

    u := tgbotapi.NewUpdate(0)
    u.Timeout = 60

    err = Bot.UpdatesChan(u)
    if err != nil {
        log.Panic(err)
    }

    log.Printf("Authorized on account %s", Bot.Self.UserName)
}

example/main.go

package main

import (
    "log"

    "github.com/pyed/example/telegram"
)

func main() {
    for update := range telegram.Bot.Updates {
        log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
    }
}

trying to go run main.go will produce the following

2015/08/07 07:41:47 Authorized on account myawesomebot
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x50 pc=0x2038]

goroutine 1 [running]:
main.main()
    $GOPATH/src/github.com/pyed/example/main.go:10 +0x38

goroutine 1 [select]:
net/http.(*persistConn).roundTrip(0xc20806e000, 0xc208267640, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:1082 +0x7ad
net/http.(*Transport).RoundTrip(0xc208064000, 0xc208033930, 0xc20826b6e0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:235 +0x558
net/http.send(0xc208033930, 0x611cd8, 0xc208064000, 0x54, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/client.go:219 +0x4fc
net/http.(*Client).send(0xc20803a9f0, 0xc208033930, 0x54, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/client.go:142 +0x15b
net/http.(*Client).doFollowingRedirects(0xc20803a9f0, 0xc208033930, 0x367330, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/client.go:367 +0xb25
net/http.(*Client).Post(0xc20803a9f0, 0xc20826b680, 0x54, 0x327210, 0x21, 0x611d28, 0xc20825f9a0, 0x54, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/client.go:441 +0x10d
net/http.(*Client).PostForm(0xc20803a9f0, 0xc20826b680, 0x54, 0xc2081eefc0, 0x2, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/client.go:461 +0x11c
github.com/Syfaro/telegram-bot-api.(*BotAPI).MakeRequest(0xc208058060, 0x2f33b0, 0xa, 0xc2081eefc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    $GOPATH/src/github.com/Syfaro/telegram-bot-api/methods.go:150 +0x1ee
github.com/Syfaro/telegram-bot-api.(*BotAPI).GetUpdates(0xc208058060, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0)
    $GOPATH/src/github.com/Syfaro/telegram-bot-api/methods.go:771 +0x671
github.com/Syfaro/telegram-bot-api.func·001()
    $GOPATH/src/github.com/Syfaro/telegram-bot-api/updates.go:14 +0x58
created by github.com/Syfaro/telegram-bot-api.(*BotAPI).UpdatesChan
    $GOPATH/src/github.com/Syfaro/telegram-bot-api/updates.go:34 +0x12e

goroutine 9 [IO wait]:
net.(*pollDesc).Wait(0xc2080101b0, 0x72, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/fd_poll_runtime.go:84 +0x47
net.(*pollDesc).WaitRead(0xc2080101b0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/fd_poll_runtime.go:89 +0x43
net.(*netFD).Read(0xc208010150, 0xc208030800, 0x400, 0x400, 0x0, 0x611ae0, 0xc2082674e8)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/fd_unix.go:242 +0x40f
net.(*conn).Read(0xc208036048, 0xc208030800, 0x400, 0x400, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/net.go:121 +0xdc
crypto/tls.(*block).readFromUntil(0xc20803ac90, 0x612ec0, 0xc208036048, 0x5, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/crypto/tls/conn.go:454 +0xe6
crypto/tls.(*Conn).readRecord(0xc208072000, 0x17, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/crypto/tls/conn.go:539 +0x2da
crypto/tls.(*Conn).Read(0xc208072000, 0xc20809c000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/crypto/tls/conn.go:904 +0x166
net/http.noteEOFReader.Read(0x6179d8, 0xc208072000, 0xc20806e058, 0xc20809c000, 0x1000, 0x1000, 0x257600, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:1270 +0x6e
net/http.(*noteEOFReader).Read(0xc20825f6a0, 0xc20809c000, 0x1000, 0x1000, 0xc208012000, 0x0, 0x0)
    <autogenerated>:125 +0xd4
bufio.(*Reader).fill(0xc20826b4a0)
    /usr/local/Cellar/go/1.4.2/libexec/src/bufio/bufio.go:97 +0x1ce
bufio.(*Reader).Peek(0xc20826b4a0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/bufio/bufio.go:132 +0xf0
net/http.(*persistConn).readLoop(0xc20806e000)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:842 +0xa4
created by net/http.(*Transport).dialConn
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:660 +0xc9f

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:2232 +0x1

goroutine 10 [select]:
net/http.(*persistConn).writeLoop(0xc20806e000)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:945 +0x41d
created by net/http.(*Transport).dialConn
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:661 +0xcbc
exit status 2

Return Response in SetWebhook method

For consistency its good to have the response feedback from this API method, I could even submit a PR doing this, it will be trivial, anyway I like how you have done this API client, its awesome, thanks.

NewInlineKeyboardMarkup

Please show example with NewInlineKeyboardMarkup with callbacks for processing . I dont understand how i should procces the event when user click inline button.

answering inline query

I think that we need an example of answering inline-query, I'm having a little problem making one myself, so hopefully the following code will demonstrate a question/example to be used in README.md

package main

import (
    "log"

    "gopkg.in/telegram-bot-api.v1"
)

func main() {
    bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken")
    if err != nil {
        log.Panic(err)
    }

    log.Printf("Authorized on account %s", bot.Self.UserName)

    u := tgbotapi.NewUpdate(0)
    u.Timeout = 60

    updates, err := bot.GetUpdatesChan(u)

    for update := range updates {
        if update.InlineQuery.Query == "" {
            continue
        }

        answer := tgbotapi.InlineQueryResultArticle{
            InlineQueryResult: tgbotapi.InlineQueryResult{ // ??
                Type: "article",
                ID:   update.InlineQuery.ID,
            },

            Title:       "Echo",
            MessageText: update.InlineQuery.Query,
        }

        inlineConf := tgbotapi.InlineConfig{
            InlineQueryID: update.InlineQuery.Query,
            Results:       []tgbotapi.InlineQueryResult{answer.InlineQueryResult}, // ??
        }

        if _, err := bot.AnswerInlineQuery(inlineConf); err != nil {
            log.Println(err)
        }

    }
}

I'm not sure how to deal with InlineQueryResult, this example will hit this error: [Error]: Bad request: Can't find field "message_text"

inline query panic

package main

import (
    "log"

    "gopkg.in/telegram-bot-api.v4"
)

func main() {
    bot, err := tgbotapi.NewBotAPI("XXXX")
    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, err := bot.GetUpdatesChan(u)

    for update := range updates {
        if update.InlineQuery.Query != "" {  // this will cause a panic, it didn't in v2
            log.Printf("This was an inline query update\n")
        }
        log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

        msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
        msg.ReplyToMessageID = update.Message.MessageID

        bot.Send(msg)
    }
}

CallbackQuery always returns an empty Message

This is strange, but the sent callback through pressing the keyboard button from the inline search result does not return the body of the parent. Only identifiers, data and date.

Add the option to send Reader or [] bytes in fileSending methods (sendPictures, sendAudio, sendDocument)

Some of us (like me) have their bots in GAE (Google App Engine) since the sendPicture method only takes a file path it can't be used in GAE because the system is readonly so would be cool to add a param or override those methods that send files picture, audio, document, etc to have to posiblity to send a ReaderCloser (like response.Body) or a []bytes that can be parsed inside them.

This is an example on how I achieved this with the same library you're using:

    ms.WriteReader(paramType, "card." + extension, contentLength, resp.Body)
    req, _ := http.NewRequest("POST", BASE_URL + methodName, nil)
    ms.SetupRequest(req)

ReplyKeyboardMarkup does not work anymore

itemsSel := [][]string{}
itemsSel = append(itemsSel, []string{item1.Caption, item2.Caption, item3.Caption})

msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Select item")
msg.ReplyMarkup = &tgbotapi.ReplyKeyboardMarkup{
    Keyboard:       itemsSel,
    ResizeKeyboard: true,
    OneTimeKeyboard: false,
    Selective:       false,
}

log.Println(msg.ReplyMarkup)

msg.ReplyToMessageID = update.Message.MessageID
_, err = bot.Send(msg)

But the keyboard is no longer displayed in the chat.
Logs:

2015/11/25 14:43:37 &{[[Hot set Samurai set Sunrise set]] true false false}
2015/11/25 14:43:37 SendMessage {"ok":true,"result":{"message_id":238,"from":{"id":xxx,"first_name":"xxx","username":"xxx"},"chat":{"id":xxx,"first_name":"xxx","last_name":"xxx","username":"xxx","type":"private"},"date":1448444617,"reply_to_message":{"message_id":234,"from":{"id":xxx,"first_name":"xxx","last_name":"xxx","username":"xxx"},"chat":{"id":xxx,"first_name":"xxx","last_name":"xxx","username":"xxx","type":"private"},"date":1448444615,"text":"new"},"text":"xxx"}}
2015/11/25 14:43:37 SendMessage req : map[chat_id:[xxx] reply_to_message_id:[234] text:[Select item] disable_web_page_preview:[false]]

Before commit #29 it worked. Or I'm doing something wrong?

Falling Down while getting Error "502 Bad Gateway"

2015/08/09 09:10:50 getUpdates: []
2015/08/09 09:11:10 getUpdates {"ok":true,"result":[]}
2015/08/09 09:11:10 getUpdates: []
2015/08/09 09:11:30 getUpdates {"ok":true,"result":[]}
2015/08/09 09:11:30 getUpdates: []
2015/08/09 09:11:38 getUpdates <html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.6.2</center>
</body>
</html>

panic: 

goroutine 11 [running]:
github.com/Syfaro/telegram-bot-api.func·001()
    /root/go/src/github.com/Syfaro/telegram-bot-api/updates.go:17 +0xd5
created by github.com/Syfaro/telegram-bot-api.(*BotAPI).UpdatesChan
    /root/go/src/github.com/Syfaro/telegram-bot-api/updates.go:34 +0x12e

goroutine 1 [chan receive, 607 minutes]:
main.main()
    /usr/local/src/freeswitch_golang_scripts/telegram.go:26 +0x3e4

goroutine 17 [syscall, 628 minutes, locked to thread]:
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1

goroutine 101 [runnable]:
net/http.(*persistConn).readLoop(0xc208076bb0)
    /usr/local/go/src/net/http/transport.go:928 +0x9ce
created by net/http.(*Transport).dialConn
    /usr/local/go/src/net/http/transport.go:660 +0xc9f

goroutine 102 [select]:
net/http.(*persistConn).writeLoop(0xc208076bb0)
    /usr/local/go/src/net/http/transport.go:945 +0x41d
created by net/http.(*Transport).dialConn
    /usr/local/go/src/net/http/transport.go:661 +0xcbc

Don't unmarshal the result

As I see, all the result recieved from telegram server are getting unmarshal, it's an unneeded thing,
Users can do'it their self or you could put an option that if they want it to unmarshal the result...

It would save a lot of time for server as we know Json (Un)Marshaling is a little slow in Golang...

Thanks in advance @Syfaro

Please stop changing things!

Twas using this in production, couldnt figure out why the weekly autobuild was failing till I looked at the logs....

I dont think anyone really cares if the method is called UpdatesChan as opposed to GetUpdatesChan, or Send vs SendMessage, but I can say that if every time I git pull things break because someone likes one naming scheme better I would be looking for a different library.

^ Strikethrough cuz rude. What I mean to say is this: when you release a project that ends up being used heavilly in many other projects, you need to have some stability

Some ideas going forward:

  1. Create new methods and deprecate old ones. A fancy way of doing this is to make the old methods print something to STDERR, that cannot be disabled without moving to the new methods. Gently lets users know without breaking things.
  2. Branch / fork to new repository.
  3. Document procedures for how methods will be removed/added, and provide api-lock guarantees.

updatesChannel type visibility scope

Hello, there! Just wanted to inquirer is there any reason type updatesChannel is private?

As far as I can see it has single public method Clear() which is not used anywhere in the library which in my eyes creates a contradiction where type has public method but no consumer can use it due to type being private.

The issue came up when I switched to webHook from polling. I would love to add switch from polling to webHook with single boolean parameter and use code similar to this

var updates  tgbotapi.updatesChannel
if isWebHook{
  //listen for updates
} else {
 //get updates channel
}

for update := range updates{
// deal with update
}

but since updatesChannel is private I cannot do this as updates would be uninitialised.

Stopping bot.

I have a bot manager, that creates some bot instances in goroutings. And it must have a posibility to stop them. but i don't see how to stop bot.GetUpdates() here?

func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (<-chan Update, error) {
    updatesChan := make(chan Update, 100)
    go func() {
        for {
            updates, err := bot.GetUpdates(config)
            if err != nil {
                log.Println(err)
                log.Println("Failed to get updates, retrying in 3 seconds...")
                time.Sleep(time.Second * 3)

                continue
            }

            for _, update := range updates {
                if update.UpdateID >= config.Offset {
                    config.Offset = update.UpdateID + 1
                    updatesChan <- update
                }
            }
        }
    }()
    return updatesChan, nil
}

It continues to get Updates until the whole programm is closed. Is it posible to create method for stopping bot?

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.