func (c *Client) SendPhotoFile(chatID string, filename string, opts ...sendOption) (*Message, error) {
	req := url.Values{}
	req.Set("chat_id", chatID)
	for _, opt := range opts {
		opt(req)
	}
	msg := &Message{}
	err := c.doRequestWithFiles("sendPhoto", req, msg, inputFile{field: "photo", name: filename})
	return msg, err
}
/*
SendPhotoFile sends photo file contents to the chat. Pass filename to send. Available options:
- OptCaption(caption string)
- OptParseModeHTML
- OptParseModeMarkdown
- OptDisableNotification
- OptReplyToMessageID(id int)
- OptInlineKeyboardMarkup(markup *InlineKeyboardMarkup)
- OptReplyKeyboardMarkup(markup *ReplyKeyboardMarkup)
- OptReplyKeyboardRemove
- OptReplyKeyboardRemoveSelective
- OptForceReply
- OptForceReplySelective
package tbot
import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"time"
)
type Client struct {
	token         string
	baseURL       string
	url           string
	httpClient    *http.Client
	nextOffset    int
	logger        Logger
	bufferSize    int
	timeout       int
	updatesParams url.Values
}
func NewClient(token string, httpClient *http.Client, baseURL string) *Client {
	return &Client{
		token:      token,
		httpClient: httpClient,
		baseURL:    baseURL,
		url:        fmt.Sprintf("%s/bot%s/", baseURL, token) + "%s",
	}
}
type inputFile struct {
	field string
	name  string
}
type sendOption func(url.Values)
var (
	OptParseModeHTML = func(r url.Values) {
		r.Set("parse_mode", "HTML")
	}
	OptParseModeMarkdown = func(r url.Values) {
		r.Set("parse_mode", "MarkdownV2")
	}
	OptDisableNotification = func(r url.Values) {
		r.Set("disable_notification", "true")
	}
	OptReplyToMessageID = func(id int) sendOption {
		return func(r url.Values) {
			r.Set("reply_to_message_id", strconv.Itoa(id))
		}
	}
)
func structString(s interface{}) string {
	str, _ := json.Marshal(s)
	return string(str)
}
func (c *Client) GetMe() (*User, error) {
	me := &User{}
	err := c.doRequest("getMe", nil, me)
	return me, err
}
type forceReply struct {
	ForceReply bool `json:"force_reply"`
	Selective  bool `json:"selective"`
}
type replyKeyboardRemove struct {
	RemoveKeyboard bool `json:"remove_keyboard"`
	Selective      bool `json:"selective"`
}
type InlineKeyboardMarkup struct {
	InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard"`
}
type InlineKeyboardButton struct {
	Text                         string    `json:"text"`
	URL                          string    `json:"url,omitempty"`
	LoginURL                     *LoginURL `json:"login_url,omitempty"`
	CallbackData                 string    `json:"callback_data,omitempty"`
	SwitchInlineQuery            *string   `json:"switch_inline_query,omitempty"`
	SwitchInlineQueryCurrentChat *string   `json:"switch_inline_query_current_chat,omitempty"`
}
type LoginURL struct {
	URL                string  `json:"url"`
	ForwardText        *string `json:"forward_text,omitempty"`
	BotUsername        *string `json:"bot_username,omitempty"`
	RequestWriteAccess *string `json:"request_write_access,omitempty"`
}
type ReplyKeyboardMarkup struct {
	Keyboard        [][]KeyboardButton `json:"keyboard"`
	ResizeKeyboard  bool               `json:"resize_keyboard"`
	OneTimeKeyboard bool               `json:"one_time_keyboard"`
	Selective       bool               `json:"selective"`
}
type KeyboardButton struct {
	Text            string                  `json:"text"`
	RequestContact  bool                    `json:"request_contact"`
	RequestLocation bool                    `json:"request_location"`
	RequestPoll     *KeyboardButtonPollType `json:"request_poll,omitempty"`
}
type KeyboardButtonPollType struct {
	Type string `json:"type"`
}
func (c *Client) setWebhook(webhookURL string) error {
	req := url.Values{}
	req.Set("url", webhookURL)
	var set bool
	return c.doRequest("setWebhook", req, &set)
}
func (c *Client) deleteWebhook() error {
	var ok bool
	return c.doRequest("deleteWebhook", url.Values{}, &ok)
}
var (
	OptDisableWebPagePreview = func(r url.Values) {
		r.Set("disable_web_page_preview", "true")
	}
	OptInlineKeyboardMarkup = func(markup *InlineKeyboardMarkup) sendOption {
		return func(r url.Values) {
			r.Set("reply_markup", structString(markup))
		}
	}
	OptReplyKeyboardMarkup = func(markup *ReplyKeyboardMarkup) sendOption {
		return func(r url.Values) {
			r.Set("reply_markup", structString(markup))
		}
	}
	OptReplyKeyboardRemove = func(r url.Values) {
		r.Set("reply_markup", structString(&replyKeyboardRemove{RemoveKeyboard: true}))
	}
	OptReplyKeyboardRemoveSelective = func(r url.Values) {
		r.Set("reply_markup", structString(&replyKeyboardRemove{RemoveKeyboard: true, Selective: true}))
	}
	OptForceReply = func(r url.Values) {
		r.Set("reply_markup", structString(&forceReply{ForceReply: true}))
	}
	OptForceReplySelective = func(r url.Values) {
		r.Set("reply_markup", structString(&forceReply{ForceReply: true, Selective: true}))
	}
)
func (c *Client) SendMessage(chatID string, text string, opts ...sendOption) (*Message, error) {
	req := url.Values{}
	req.Set("chat_id", chatID)
	req.Set("text", text)
	for _, opt := range opts {
		opt(req)
	}
	msg := &Message{}
	err := c.doRequest("sendMessage", req, msg)
	return msg, err
}
func (c *Client) ForwardMessage(chatID, fromChatID string, messageID int, opts ...sendOption) (*Message, error) {
	req := url.Values{}
	req.Set("chat_id", chatID)
	req.Set("from_chat_id", fromChatID)
	req.Set("message_id", strconv.Itoa(messageID))
	for _, opt := range opts {
		opt(req)
	}
	msg := &Message{}
	err := c.doRequest("forwardMessage", req, msg)
	return msg, err
}
var (
	OptDuration = func(duration int) sendOption {
		return func(r url.Values) {
			r.Set("duration", strconv.Itoa(duration))
		}
	}
	OptPerformer = func(performer string) sendOption {
		return func(r url.Values) {
			r.Set("performer", performer)
		}
	}
	OptTitle = func(title string) sendOption {
		return func(r url.Values) {
			r.Set("title", title)
		}
	}
)
func (c *Client) SendAudio(chatID string, fileID string, opts ...sendOption) (*Message, error) {
	req := url.Values{}
	req.Set("chat_id", chatID)
	req.Set("audio", fileID)
	for _, opt := range opts {
		opt(req)
	}
	msg := &Message{}
	err := c.doRequest("sendAudio", req, msg)
	return msg, err
}
func (c *Client) SendAudioFile(chatID string, filename string, opts ...sendOption) (*Message, error) {
	req := url.Values{}
	req.Set("chat_id", chatID)
	for _, opt := range opts {
		opt(req)
	}
	msg := &Message{}
	err := c.doRequestWithFiles("sendAudio", req, msg, inputFile{field: "audio", name: filename})
	return msg, err
}
var (
	OptCaption = func(caption string) sendOption {
		return func(r url.Values) {
			r.Set("caption", caption)
		}
	}
)
func (c *Client) SendPhoto(chatID string, fileID string, opts ...sendOption) (*Message, error) {
	req := url.Values{}
	req.Set("chat_id", chatID)
	req.Set("photo", fileID)
	for _, opt := range opts {
		opt(req)
	}
	msg := &Message{}
	err := c.doRequest("sendPhoto", req, msg)
	return msg, err
}