1
0

🔨 Refactor helpers

This commit is contained in:
Maxim Lebedev 2017-10-17 16:08:09 +05:00
parent 5e907b296d
commit 13a444f845
No known key found for this signature in database
GPG Key ID: F8978F46FF0FFA4F
13 changed files with 531 additions and 300 deletions

View File

@ -29,6 +29,12 @@ type AnswerCallbackQueryParameters struct {
CacheTime int `json:"cache_time,omitempty"`
}
func NewAnswerCallbackQuery(callbackQueryID string) *AnswerCallbackQueryParameters {
return &AnswerCallbackQueryParameters{
CallbackQueryID: callbackQueryID,
}
}
// AnswerCallbackQuery send answers to callback queries sent from inline
// keyboards. The answer will be displayed to the user as a notification at the
// top of the chat screen or as an alert. On success, True is returned.

View File

@ -35,6 +35,13 @@ type AnswerInlineQueryParameters struct {
SwitchPrivateMessageParameter string `json:"switch_pm_parameter,omitempty"`
}
func NewAnswerInlineQuery(inlineQueryID string, results ...InlineQueryResult) *AnswerInlineQueryParameters {
return &AnswerInlineQueryParameters{
InlineQueryID: inlineQueryID,
Results: results,
}
}
// AnswerInlineQuery send answers to an inline query. On success, True is returned.
//
// No more than 50 results per query are allowed.

View File

@ -19,6 +19,13 @@ type AnswerPreCheckoutQueryParameters struct {
ErrorMessage string `json:"error_message,omitempty"`
}
func NewAnswerPreCheckoutQuery(preCheckoutQueryID string, ok bool) *AnswerPreCheckoutQueryParameters {
return &AnswerPreCheckoutQueryParameters{
PreCheckoutQueryID: preCheckoutQueryID,
Ok: ok,
}
}
// AnswerPreCheckoutQuery respond to such pre-checkout queries.
//
// Once the user has confirmed their payment and shipping details, the Bot API

View File

@ -22,6 +22,13 @@ type AnswerShippingQueryParameters struct {
ErrorMessage string `json:"error_message,omitempty"`
}
func NewAnswerShippingQuery(shippingQueryID string, ok bool) *AnswerShippingQueryParameters {
return &AnswerShippingQueryParameters{
ShippingQueryID: shippingQueryID,
Ok: ok,
}
}
// AnswerShippingQuery reply to shipping queries.
//
// If you sent an invoice requesting a shipping address and the parameter

17
chat_helpers.go Normal file
View File

@ -0,0 +1,17 @@
package telegram
func (chat *Chat) IsPrivate() bool {
return chat.Type == ChatPrivate
}
func (chat *Chat) IsGroup() bool {
return chat.Type == ChatGroup
}
func (chat *Chat) IsSuperGroup() bool {
return chat.Type == ChatSuperGroup
}
func (chat *Chat) IsChannel() bool {
return chat.Type == ChatChannel
}

11
entities_helpers.go Normal file
View File

@ -0,0 +1,11 @@
package telegram
import "net/url"
func (entity *MessageEntity) ParseURL() (*url.URL, error) {
if entity.Type == EntityTextLink {
return url.Parse(entity.URL)
}
return nil, nil
}

View File

@ -16,6 +16,14 @@ type ForwardMessageParameters struct {
MessageID int `json:"message_id"`
}
func NewForwardMessage(from, to int64, messageID int) *ForwardMessageParameters {
return &ForwardMessageParameters{
FromChatID: from,
ChatID: to,
MessageID: messageID,
}
}
// ForwardMessage forward messages of any kind. On success, the sent Message is returned.
func (bot *Bot) ForwardMessage(params *ForwardMessageParameters) (*Message, error) {
dst, err := json.Marshal(params)

View File

@ -1,300 +0,0 @@
package telegram
import (
"fmt"
"log"
"net/url"
"strings"
"time"
json "github.com/pquerna/ffjson/ffjson"
http "github.com/valyala/fasthttp"
)
type UpdatesChannel <-chan Update
func NewAnswerCallback(id string) *AnswerCallbackQueryParameters {
return &AnswerCallbackQueryParameters{
CallbackQueryID: id}
}
func NewAnswerInline(id string, results ...InlineQueryResult) *AnswerInlineQueryParameters {
return &AnswerInlineQueryParameters{
InlineQueryID: id,
Results: results,
}
}
func NewAnswerPreCheckout(id string, ok bool) *AnswerPreCheckoutQueryParameters {
return &AnswerPreCheckoutQueryParameters{
PreCheckoutQueryID: id,
Ok: ok,
}
}
func NewAnswerShipping(id string, ok bool) *AnswerShippingQueryParameters {
return &AnswerShippingQueryParameters{
ShippingQueryID: id,
Ok: ok,
}
}
func NewMessage(chatID int64, text string) *SendMessageParameters {
return &SendMessageParameters{
ChatID: chatID,
Text: text,
}
}
func NewMessageForward(from, to int64, messageID int) *ForwardMessageParameters {
return &ForwardMessageParameters{
FromChatID: from,
ChatID: to,
MessageID: messageID,
}
}
func NewInvoice(chatID int64, title, description, payload, providerToken, startParameter, currency string, prices ...LabeledPrice) *SendInvoiceParameters {
return &SendInvoiceParameters{
ChatID: chatID,
Title: title,
Description: description,
Payload: payload,
ProviderToken: providerToken,
StartParameter: startParameter,
Currency: currency,
Prices: prices,
}
}
func NewReplyKeyboard(rows ...[]KeyboardButton) *ReplyKeyboardMarkup {
var keyboard [][]KeyboardButton
keyboard = append(keyboard, rows...)
return &ReplyKeyboardMarkup{
Keyboard: keyboard,
ResizeKeyboard: true,
}
}
func NewReplyKeyboardRow(buttons ...KeyboardButton) []KeyboardButton {
var row []KeyboardButton
row = append(row, buttons...)
return row
}
func NewReplyKeyboardButton(text string) KeyboardButton {
return KeyboardButton{
Text: text,
}
}
func NewReplyKeyboardButtonContact(text string) KeyboardButton {
return KeyboardButton{
Text: text,
RequestContact: true,
}
}
func NewReplyKeyboardButtonLocation(text string) KeyboardButton {
return KeyboardButton{
Text: text,
RequestLocation: true,
}
}
func NewInlineKeyboard(rows ...[]InlineKeyboardButton) InlineKeyboardMarkup {
var keyboard [][]InlineKeyboardButton
keyboard = append(keyboard, rows...)
return InlineKeyboardMarkup{InlineKeyboard: keyboard}
}
func NewInlineKeyboardRow(buttons ...InlineKeyboardButton) []InlineKeyboardButton {
var row []InlineKeyboardButton
row = append(row, buttons...)
return row
}
func NewInlineKeyboardButton(text, data string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
CallbackData: data,
}
}
func NewInlineKeyboardButtonURL(text, url string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
URL: url,
}
}
func NewInlineKeyboardButtonSwitch(text, query string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
SwitchInlineQuery: query,
}
}
func NewInlineKeyboardButtonSwitchSelf(text, query string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
SwitchInlineQueryCurrentChat: query,
}
}
func NewInlineKeyboardButtonGame(text string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
CallbackGame: &CallbackGame{},
}
}
func NewInlineKeyboardButtonPay(text string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
Pay: true,
}
}
func NewWebhook(url string, file interface{}) *SetWebhookParameters {
params := &SetWebhookParameters{URL: url}
if file != nil {
var input InputFile = file
params.Certificate = &input
}
return params
}
func (bot *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 := bot.GetUpdates(params)
if err != nil {
log.Println(err.Error())
log.Println("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
}
func NewWebhookChannel(serve, listen string, params *GetUpdatesParameters) UpdatesChannel {
if params == nil {
params = &GetUpdatesParameters{
Offset: 0,
Limit: 100,
Timeout: 60,
}
}
channel := make(chan Update, params.Limit)
go func() {
if err := http.ListenAndServe(serve, func(ctx *http.RequestCtx) {
log.Println("PATH:", string(ctx.Path()))
if strings.HasPrefix(string(ctx.Path()), listen) {
log.Println("rawBody:", string(ctx.Request.Body()))
var update Update
json.Unmarshal(ctx.Request.Body(), &update)
channel <- update
}
}); err != nil {
panic(err.Error())
}
}()
return channel
}
func (msg *Message) IsCommand() bool {
if len(msg.Entities) <= 0 {
return false
}
if msg.Entities[0].Type == EntityBotCommand &&
msg.Entities[0].Offset == 0 {
return true
}
return false
}
func (msg *Message) Command() string {
if !msg.IsCommand() {
return ""
}
return string([]rune(msg.Text)[1:msg.Entities[0].Length])
}
func (msg *Message) CommandArgument() string {
if !msg.IsCommand() {
return ""
}
arg := strings.TrimPrefix(
msg.Text,
fmt.Sprint("/", msg.Command()),
)
return strings.TrimPrefix(arg, " ")
}
func (msg *Message) HasArgument() bool {
if !msg.IsCommand() {
return false
}
if msg.CommandArgument() != "" {
return true
}
return false
}
func (chat *Chat) IsPrivate() bool {
return chat.Type == ChatPrivate
}
func (chat *Chat) IsGroup() bool {
return chat.Type == ChatGroup
}
func (chat *Chat) IsSuperGroup() bool {
return chat.Type == ChatSuperGroup
}
func (chat *Chat) IsChannel() bool {
return chat.Type == ChatChannel
}
func (entity *MessageEntity) ParseURL() (*url.URL, error) {
if entity.Type != EntityTextLink {
return nil, nil
}
return url.Parse(entity.URL)
}

52
messages_helpers.go Normal file
View File

@ -0,0 +1,52 @@
package telegram
import "time"
func (msg *Message) IsCommand() bool {
if len(msg.Entities) <= 0 {
return false
}
if msg.Entities[0].Type == EntityBotCommand &&
msg.Entities[0].Offset == 0 {
return true
}
return false
}
func (msg *Message) Command() string {
if !msg.IsCommand() {
return ""
}
return string([]rune(msg.Text)[1:msg.Entities[0].Length])
}
func (msg *Message) CommandArgument() string {
if !msg.IsCommand() {
return ""
}
if !msg.HasArgument() {
return ""
}
return string([]rune(msg.Text)[(msg.Entities[0].Length + 1):])
}
func (msg *Message) HasArgument() bool {
if !msg.IsCommand() {
return false
}
if msg.CommandArgument() != "" {
return true
}
return false
}
func (msg *Message) Time() time.Time {
return time.Unix(msg.Date, 0)
}

385
new_helpers.go Normal file
View File

@ -0,0 +1,385 @@
package telegram
import (
"log"
"strings"
"time"
json "github.com/pquerna/ffjson/ffjson"
http "github.com/valyala/fasthttp"
)
type UpdatesChannel <-chan Update
func NewForceReply(selective bool) *ForceReply {
return &ForceReply{
ForceReply: true,
Selective: selective,
}
}
func NewReplyKeyboardMarkup(rows ...[]KeyboardButton) *ReplyKeyboardMarkup {
var keyboard [][]KeyboardButton
keyboard = append(keyboard, rows...)
return &ReplyKeyboardMarkup{
Keyboard: keyboard,
ResizeKeyboard: true,
}
}
func NewReplyKeyboardRow(buttons ...KeyboardButton) []KeyboardButton {
var row []KeyboardButton
row = append(row, buttons...)
return row
}
func NewReplyKeyboardButton(text string) KeyboardButton {
return KeyboardButton{
Text: text,
}
}
func NewReplyKeyboardButtonContact(text string) KeyboardButton {
return KeyboardButton{
Text: text,
RequestContact: true,
}
}
func NewReplyKeyboardButtonLocation(text string) KeyboardButton {
return KeyboardButton{
Text: text,
RequestLocation: true,
}
}
func NewInlineKeyboardMarkup(rows ...[]InlineKeyboardButton) *InlineKeyboardMarkup {
var keyboard [][]InlineKeyboardButton
keyboard = append(keyboard, rows...)
return &InlineKeyboardMarkup{
InlineKeyboard: keyboard,
}
}
func NewInlineKeyboardRow(buttons ...InlineKeyboardButton) []InlineKeyboardButton {
var row []InlineKeyboardButton
row = append(row, buttons...)
return row
}
func NewInlineKeyboardButton(text, data string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
CallbackData: data,
}
}
func NewInlineKeyboardButtonURL(text, url string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
URL: url,
}
}
func NewInlineKeyboardButtonSwitch(text, query string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
SwitchInlineQuery: query,
}
}
func NewInlineKeyboardButtonSwitchSelf(text, query string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
SwitchInlineQueryCurrentChat: query,
}
}
func NewInlineKeyboardButtonGame(text string) InlineKeyboardButton {
var game CallbackGame
return InlineKeyboardButton{
Text: text,
CallbackGame: &game,
}
}
func NewInlineKeyboardButtonPay(text string) InlineKeyboardButton {
return InlineKeyboardButton{
Text: text,
Pay: true,
}
}
func NewReplyKeyboardRemove(selective bool) *ReplyKeyboardRemove {
return &ReplyKeyboardRemove{
RemoveKeyboard: true,
Selective: selective,
}
}
func NewInlineQueryResultCachedAudio(resultID, fileID string) *InlineQueryResultCachedAudio {
return &InlineQueryResultCachedAudio{
Type: TypeAudio,
ID: resultID,
AudioFileID: fileID,
}
}
func NewInlineQueryResultCachedDocument(resultID, fileID, title string) *InlineQueryResultCachedDocument {
return &InlineQueryResultCachedDocument{
Type: TypeDocument,
ID: resultID,
Title: title,
DocumentFileID: fileID,
}
}
func NewInlineQueryResultCachedGif(resultID, fileID string) *InlineQueryResultCachedGif {
return &InlineQueryResultCachedGif{
Type: TypeGIF,
ID: resultID,
GifFileID: fileID,
}
}
func NewInlineQueryResultCachedMpeg4Gif(resultID, fileID string) *InlineQueryResultCachedMpeg4Gif {
return &InlineQueryResultCachedMpeg4Gif{
Type: TypeMpeg4Gif,
ID: resultID,
Mpeg4FileID: fileID,
}
}
func NewInlineQueryResultCachedPhoto(resultID, fileID string) *InlineQueryResultCachedPhoto {
return &InlineQueryResultCachedPhoto{
Type: TypePhoto,
ID: resultID,
PhotoFileID: fileID,
}
}
func NewInlineQueryResultCachedSticker(resultID, fileID string) *InlineQueryResultCachedSticker {
return &InlineQueryResultCachedSticker{
Type: TypeSticker,
ID: resultID,
StickerFileID: fileID,
}
}
func NewInlineQueryResultCachedVideo(resultID, fileID, title string) *InlineQueryResultCachedVideo {
return &InlineQueryResultCachedVideo{
Type: TypeVideo,
ID: resultID,
VideoFileID: fileID,
Title: title,
}
}
func NewInlineQueryResultCachedVoice(resultID, fileID, title string) *InlineQueryResultCachedVoice {
return &InlineQueryResultCachedVoice{
Type: TypeVoice,
ID: resultID,
VoiceFileID: fileID,
Title: title,
}
}
func NewInlineQueryResultArticle(resultID, title string, content *InputMessageContent) *InlineQueryResultArticle {
return &InlineQueryResultArticle{
Type: TypeArticle,
ID: resultID,
Title: title,
InputMessageContent: content,
}
}
func NewInlineQueryResultAudio(resultID, audioURL, title string) *InlineQueryResultAudio {
return &InlineQueryResultAudio{
Type: TypeAudio,
ID: resultID,
AudioURL: audioURL,
Title: title,
}
}
func NewInlineQueryResultContact(resultID, phoneNumber, firstName string) *InlineQueryResultContact {
return &InlineQueryResultContact{
Type: TypeContact,
ID: resultID,
PhoneNumber: phoneNumber,
FirstName: firstName,
}
}
func NewInlineQueryResultGame(resultID, gameShortName string) *InlineQueryResultGame {
return &InlineQueryResultGame{
Type: TypeGame,
ID: resultID,
GameShortName: gameShortName,
}
}
func NewInlineQueryResultDocument(resultID, title, documentURL, mimeType string) *InlineQueryResultDocument {
return &InlineQueryResultDocument{
Type: TypeDocument,
ID: resultID,
Title: title,
DocumentURL: documentURL,
MimeType: mimeType,
}
}
func NewInlineQueryResultGif(resultID, gifURL, thumbURL string) *InlineQueryResultGif {
return &InlineQueryResultGif{
Type: TypeGIF,
ID: resultID,
GifURL: gifURL,
ThumbURL: thumbURL,
}
}
func NewInlineQueryResultLocation(resultID, title string, latitude, longitude float32) *InlineQueryResultLocation {
return &InlineQueryResultLocation{
Type: TypeLocation,
ID: resultID,
Latitude: latitude,
Longitude: longitude,
Title: title,
}
}
func NewInlineQueryResultMpeg4Gif(resultID, mpeg4URL, thumbURL string) *InlineQueryResultMpeg4Gif {
return &InlineQueryResultMpeg4Gif{
Type: TypeMpeg4Gif,
ID: resultID,
Mpeg4URL: mpeg4URL,
ThumbURL: thumbURL,
}
}
func NewInlineQueryResultPhoto(resultID, photoURL, thumbURL string) *InlineQueryResultPhoto {
return &InlineQueryResultPhoto{
Type: TypePhoto,
PhotoURL: photoURL,
ThumbURL: thumbURL,
}
}
func NewInlineQueryResultVenue(resultID, title, address string, latitude, longitude float32) *InlineQueryResultVenue {
return &InlineQueryResultVenue{
Type: TypeVenue,
ID: resultID,
Latitude: latitude,
Longitude: longitude,
Title: title,
Address: address,
}
}
func NewInlineQueryResultVideo(resultID, videoURL, mimeType, thumbURL, title string) *InlineQueryResultVideo {
return &InlineQueryResultVideo{
Type: TypeVideo,
ID: resultID,
MimeType: mimeType,
ThumbURL: thumbURL,
Title: title,
}
}
func NewInlineQueryResultVoice(resultID, voiceURL, title string) *InlineQueryResultVoice {
return &InlineQueryResultVoice{
Type: TypeVoice,
ID: resultID,
VoiceURL: voiceURL,
Title: title,
}
}
func NewInputTextMessageContent(messageText string) *InputTextMessageContent {
return &InputTextMessageContent{
MessageText: messageText,
}
}
func NewInputLocationMessageContent(latitude, longitude float32) *InputLocationMessageContent {
return &InputLocationMessageContent{
Latitude: latitude,
Longitude: longitude,
}
}
func NewInputVenueMessageContent(latitude, longitude float32, title, address string) *InputVenueMessageContent {
return &InputVenueMessageContent{
Latitude: latitude,
Longitude: longitude,
Title: title,
Address: address,
}
}
func NewInputContactMessageContent(phoneNumber, firstName string) *InputContactMessageContent {
return &InputContactMessageContent{
PhoneNumber: phoneNumber,
FirstName: firstName,
}
}
func (bot *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 := bot.GetUpdates(params)
if err != nil {
log.Println(err.Error())
log.Println("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
}
func NewWebhookChannel(set, listen, serve string, params *GetUpdatesParameters) UpdatesChannel {
if params == nil {
params = &GetUpdatesParameters{
Offset: 0,
Limit: 100,
Timeout: 60,
}
}
channel := make(chan Update, params.Limit)
go func() {
if err := http.ListenAndServe(serve, func(ctx *http.RequestCtx) {
if strings.HasPrefix(string(ctx.Path()), listen) {
var update Update
json.Unmarshal(ctx.Request.Body(), &update)
channel <- update
}
}); err != nil {
log.Fatalln(err.Error())
}
}()
return channel
}

View File

@ -73,6 +73,19 @@ type SendInvoiceParameters struct {
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
}
func NewInvoice(chatID int64, title, description, payload, providerToken, startParameter, currency string, prices ...LabeledPrice) *SendInvoiceParameters {
return &SendInvoiceParameters{
ChatID: chatID,
Title: title,
Description: description,
Payload: payload,
ProviderToken: providerToken,
StartParameter: startParameter,
Currency: currency,
Prices: prices,
}
}
// SendInvoice send invoices. On success, the sent Message is returned.
func (bot *Bot) SendInvoice(params *SendInvoiceParameters) (*Message, error) {
dst, err := json.Marshal(*params)

View File

@ -30,6 +30,13 @@ type SendMessageParameters struct {
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
}
func NewMessage(chatID int64, text string) *SendMessageParameters {
return &SendMessageParameters{
ChatID: chatID,
Text: text,
}
}
// SendMessage send text messages. On success, the sent Message is returned.
func (bot *Bot) SendMessage(params *SendMessageParameters) (*Message, error) {
dst, err := json.Marshal(*params)

View File

@ -35,6 +35,17 @@ type SetWebhookParameters struct {
AllowedUpdates []string `json:"allowed_updates,omitempty"`
}
func NewWebhook(url string, file interface{}) *SetWebhookParameters {
params := &SetWebhookParameters{URL: url}
if file != nil {
var input InputFile = file
params.Certificate = &input
}
return params
}
// SetWebhook specify a url and receive incoming updates via an outgoing webhook.
// Whenever there is an update for the bot, we will send an HTTPS POST request to
// the specified url, containing a JSON-serialized Update. In case of an