171 lines
4.3 KiB
Go
171 lines
4.3 KiB
Go
|
package telegram
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"log"
|
||
|
"time"
|
||
|
|
||
|
"github.com/kirillDanshin/dlog"
|
||
|
json "github.com/pquerna/ffjson/ffjson"
|
||
|
http "github.com/valyala/fasthttp"
|
||
|
)
|
||
|
|
||
|
// UpdatesChannel is a channel for reading updates of bot.
|
||
|
type UpdatesChannel <-chan Update
|
||
|
|
||
|
// NewLongPollingChannel creates channel for receive incoming updates using long
|
||
|
// polling.
|
||
|
func (b *Bot) NewLongPollingChannel(params *GetUpdatesParameters) UpdatesChannel {
|
||
|
if params == nil {
|
||
|
params = &GetUpdatesParameters{
|
||
|
Offset: 0,
|
||
|
Limit: 100,
|
||
|
Timeout: 60,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
channel := make(chan Update, params.Limit)
|
||
|
go func() {
|
||
|
for {
|
||
|
updates, err := b.GetUpdates(params)
|
||
|
if err != nil {
|
||
|
dlog.Ln(err.Error())
|
||
|
dlog.Ln("Failed to get updates, retrying in 3 seconds...")
|
||
|
time.Sleep(time.Second * 3)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
for _, update := range updates {
|
||
|
if update.ID >= params.Offset {
|
||
|
params.Offset = update.ID + 1
|
||
|
channel <- update
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
return channel
|
||
|
}
|
||
|
|
||
|
// NewWebhookChannel creates channel for receive incoming updates via an outgoing
|
||
|
// webhook.
|
||
|
func (b *Bot) NewWebhookChannel(setURL *http.URI, params *SetWebhookParameters, certFile, keyFile, serveAddr string) (updates UpdatesChannel) {
|
||
|
if params == nil {
|
||
|
params = &SetWebhookParameters{
|
||
|
URL: setURL.String(),
|
||
|
MaxConnections: 40,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var err error
|
||
|
channel := make(chan Update, 100)
|
||
|
handleFunc := func(ctx *http.RequestCtx) {
|
||
|
dlog.Ln("Request path:", string(ctx.Path()))
|
||
|
if !bytes.HasPrefix(ctx.Path(), setURL.Path()) {
|
||
|
dlog.Ln("Unsupported request path:", string(ctx.Path()))
|
||
|
return
|
||
|
}
|
||
|
dlog.Ln("Catched supported request path:", string(ctx.Path()))
|
||
|
|
||
|
var update Update
|
||
|
if err = json.Unmarshal(ctx.Request.Body(), &update); err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
channel <- update
|
||
|
}
|
||
|
|
||
|
go func() {
|
||
|
if certFile != "" && keyFile != "" {
|
||
|
dlog.Ln("Creating TLS router...")
|
||
|
err = http.ListenAndServeTLS(serveAddr, certFile, keyFile, handleFunc)
|
||
|
} else {
|
||
|
dlog.Ln("Creating simple router...")
|
||
|
err = http.ListenAndServe(serveAddr, handleFunc)
|
||
|
}
|
||
|
if err != nil {
|
||
|
log.Fatalln(err.Error())
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
if _, err = b.SetWebhook(params); err != nil {
|
||
|
log.Fatalln(err.Error())
|
||
|
}
|
||
|
|
||
|
return channel
|
||
|
}
|
||
|
|
||
|
// IsMessage checks that the current update is a message creation event.
|
||
|
func (u *Update) IsMessage() bool {
|
||
|
return u != nil && u.Message != nil
|
||
|
}
|
||
|
|
||
|
// IsEditedMessage checks that the current update is a editing message event.
|
||
|
func (u *Update) IsEditedMessage() bool {
|
||
|
return u != nil && u.EditedMessage != nil
|
||
|
}
|
||
|
|
||
|
// IsChannelPost checks that the current update is a post channel creation event.
|
||
|
func (u *Update) IsChannelPost() bool {
|
||
|
return u != nil && u.ChannelPost != nil
|
||
|
}
|
||
|
|
||
|
// IsEditedChannelPost checks that the current update is a editing post channel
|
||
|
// event.
|
||
|
func (u *Update) IsEditedChannelPost() bool {
|
||
|
return u != nil && u.EditedChannelPost != nil
|
||
|
}
|
||
|
|
||
|
// IsInlineQuery checks that the current update is a inline query update.
|
||
|
func (u *Update) IsInlineQuery() bool {
|
||
|
return u != nil && u.InlineQuery != nil
|
||
|
}
|
||
|
|
||
|
// IsChosenInlineResult checks that the current update is a chosen inline result
|
||
|
// update.
|
||
|
func (u *Update) IsChosenInlineResult() bool {
|
||
|
return u != nil && u.ChosenInlineResult != nil
|
||
|
}
|
||
|
|
||
|
// IsCallbackQuery checks that the current update is a callback query update.
|
||
|
func (u *Update) IsCallbackQuery() bool {
|
||
|
return u != nil && u.CallbackQuery != nil
|
||
|
}
|
||
|
|
||
|
// IsShippingQuery checks that the current update is a shipping query update.
|
||
|
func (u *Update) IsShippingQuery() bool {
|
||
|
return u != nil && u.ShippingQuery != nil
|
||
|
}
|
||
|
|
||
|
// IsPreCheckoutQuery checks that the current update is a pre checkout query
|
||
|
// update.
|
||
|
func (u *Update) IsPreCheckoutQuery() bool {
|
||
|
return u != nil && u.PreCheckoutQuery != nil
|
||
|
}
|
||
|
|
||
|
// Type return update type for current update.
|
||
|
func (u *Update) Type() string {
|
||
|
switch {
|
||
|
case u.IsCallbackQuery():
|
||
|
return UpdateCallbackQuery
|
||
|
case u.IsChannelPost():
|
||
|
return UpdateChannelPost
|
||
|
case u.IsChosenInlineResult():
|
||
|
return UpdateChosenInlineResult
|
||
|
case u.IsEditedChannelPost():
|
||
|
return UpdateEditedChannelPost
|
||
|
case u.IsEditedMessage():
|
||
|
return UpdateEditedMessage
|
||
|
case u.IsInlineQuery():
|
||
|
return UpdateInlineQuery
|
||
|
case u.IsMessage():
|
||
|
return UpdateMessage
|
||
|
case u.IsPreCheckoutQuery():
|
||
|
return UpdatePreCheckoutQuery
|
||
|
case u.IsShippingQuery():
|
||
|
return UpdateShippingQuery
|
||
|
default:
|
||
|
return ""
|
||
|
}
|
||
|
}
|