Error handling. Vendoring

Signed-off-by: Ettore Dreucci <ettore.dreucci@gmail.com>
This commit is contained in:
2018-06-19 00:26:51 +02:00
parent 0c18f8094e
commit cb07e131d9
322 changed files with 175629 additions and 113 deletions

21
vendor/gopkg.in/dixonwille/wlog.v2/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Will Dixon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

516
vendor/gopkg.in/dixonwille/wlog.v2/README.md generated vendored Normal file
View File

@@ -0,0 +1,516 @@
# WLog [![Build Status](https://travis-ci.org/dixonwille/wlog.svg?branch=master)](https://travis-ci.org/dixonwille/wlog) [![Go Report Card](https://goreportcard.com/badge/github.com/dixonwille/wlog)](https://goreportcard.com/report/github.com/dixonwille/wlog) [![GoDoc](https://godoc.org/github.com/dixonwille/wlog?status.svg)](https://godoc.org/github.com/dixonwille/wlog)
Package wlog creates simple to use UI structure. The UI is used to simply print
to the screen. There a wrappers that will wrap each other to create a good
looking UI. You can add color and prefixes as well as make it thread safe.
## Import
import "github.com/dixonwille/wlog"
## Idea Behind WLog
I used Mitchellh's [CLI](https://github.com/mitchellh/cli) structure and
wrapping for the different structures. It was a clean look and feel. Plus it
was pretty simple to use. But I didn't want all the other cli stuff that came
with the package so I created this.
For color I use DavidDenGCN's
[Go-ColorText](https://github.com/daviddengcn/go-colortext). His color package
allows for color that is available cross-platforms. I made a wrapper with all
possible color combinations with his package. So you only have to import this
package (one less line).
## Example
```go
var ui UI
reader := strings.NewReader("User Input\r\n") //Simulate user typing "User Input" then pressing [enter] when reading from os.Stdin
ui = New(reader, os.Stdout, os.Stdout)
ui = AddPrefix("?", Cross, "", "", "", "~", Check, "!", ui)
ui = AddConcurrent(ui)
ui.Ask("Ask question")
ui.Error("Error message")
ui.Info("Info message")
ui.Output("Output message")
ui.Running("Running message")
ui.Success("Success message")
ui.Warn("Warning message")
```
Output:
```
? Ask question
✗ Error message
Info message
Output message
~ Running message
✓ Success message
! Warning message
```
On Windows it outputs to this (this includes color):
![winss](https://raw.githubusercontent.com/dixonwille/wlog/master/resources/winss.png)
On Mac it outputs to this (this includes color):
![macss](https://raw.githubusercontent.com/dixonwille/wlog/master/resources/macss.png)
## Usage
```go
const (
//Check displays a checkmark
Check = "\u2713"
//Cross displays an x
Cross = "\u2717"
)
```
```go
var (
//BrightRed creates a bright red color
BrightRed = Color{ct.Red, true}
//BrightBlue creates a bright blue color
BrightBlue = Color{ct.Blue, true}
//BrightYellow creates a bright yellow color
BrightYellow = Color{ct.Yellow, true}
//Red creates a red color
Red = Color{ct.Red, false}
//Blue creaets a blue color
Blue = Color{ct.Blue, false}
//Yellow creates a yellow color
Yellow = Color{ct.Yellow, false}
//BrightGreen creates a bright green color
BrightGreen = Color{ct.Green, true}
//BrightCyan creates a bright cyan color
BrightCyan = Color{ct.Cyan, true}
//BrightMagenta creates a bright magenta color
BrightMagenta = Color{ct.Magenta, true}
//Green creates a green color
Green = Color{ct.Green, false}
//Cyan creates a cyan color
Cyan = Color{ct.Cyan, false}
//Magenta creates a magenta color
Magenta = Color{ct.Magenta, false}
//White creates a white color
White = Color{ct.White, false}
//BrightWhite creates a bright white color
BrightWhite = Color{ct.White, true}
//Black creates a black color
Black = Color{ct.Black, false}
//BrightBlack creates a bright black color
BrightBlack = Color{ct.Black, true}
//None does not change the color
None = Color{ct.None, false}
)
```
#### type BasicUI
```go
type BasicUI struct {
Reader io.Reader
Writer io.Writer
ErrorWriter io.Writer
}
```
BasicUI simply writes/reads to correct input/output It is not thread safe.
Pretty simple to wrap your own functions around
#### func New
```go
func New(reader io.Reader, writer, errorWriter io.Writer) *BasicUI
```
New creates a BasicUI. This should be the first function you call. This is not
thread safe and should only be used in serial applications.
#### func (*BasicUI) Ask
```go
func (ui *BasicUI) Ask(message string) (string, error)
```
Ask will call output with message then wait for Reader to print newline (\n). If
Reader is os.Stdin then that is when ever a user presses [enter]. It will clean
the response by removing any carriage returns and new lines that if finds. If a
message is not used ("") then it will not prompt user before waiting on a
response.
#### func (*BasicUI) Error
```go
func (ui *BasicUI) Error(message string)
```
Error writes message to ErrorWriter.
#### func (*BasicUI) Info
```go
func (ui *BasicUI) Info(message string)
```
Info calls Output to write. Useful when you want separate colors or prefixes.
#### func (*BasicUI) Log
```go
func (ui *BasicUI) Log(message string)
```
Log prefixes to message before writing to Writer.
#### func (*BasicUI) Output
```go
func (ui *BasicUI) Output(message string)
```
Output simply writes to Writer.
#### func (*BasicUI) Running
```go
func (ui *BasicUI) Running(message string)
```
Running calls Output to write. Useful when you want separate colors or prefixes.
#### func (*BasicUI) Success
```go
func (ui *BasicUI) Success(message string)
```
Success calls Output to write. Useful when you want separate colors or prefixes.
#### func (*BasicUI) Warn
```go
func (ui *BasicUI) Warn(message string)
```
Warn calls Error to write. Useful when you want separate colors or prefixes.
#### type Color
```go
type Color struct {
Code ct.Color
Bright bool
}
```
Color is a wrapper for go-colortext. Simplifies the use of this package by
assigning predefined colors that can be used.
#### type ColorUI
```go
type ColorUI struct {
LogFGColor Color
OutputFGColor Color
SuccessFGColor Color
InfoFGColor Color
ErrorFGColor Color
WarnFGColor Color
RunningFGColor Color
AskFGColor Color
ResponseFGColor Color
LogBGColor Color
OutputBGColor Color
SuccessBGColor Color
InfoBGColor Color
ErrorBGColor Color
WarnBGColor Color
RunningBGColor Color
AskBGColor Color
ResponseBGColor Color
UI UI
}
```
ColorUI is a wrapper for UI that adds color.
#### func AddColor
```go
func AddColor(askColor, errorColor, infoColor, logColor, outputColor, responseColor, runningColor, successColor, warnColor Color, ui UI) *ColorUI
```
AddColor will wrap a colorful UI on top of ui. Use wlog's color variables for
the color. All background colors are not changed by this function but you are
able to change them manually. Just create this structure manually and change any
of the background colors you want. Arguments are in alphabetical order.
#### func (*ColorUI) Ask
```go
func (ui *ColorUI) Ask(message string) (string, error)
```
Ask will call UI.Output with message then wait for UI.Ask to return a response
and/or error. It will clean the response by removing any carriage returns and
new lines that if finds. If a message is not used ("") then it will not prompt
user before waiting on a response. AskFGColor and AskBGColor are used for
message color. ResponseFGColor and ResponseBGColor are used for response color.
#### func (*ColorUI) Error
```go
func (ui *ColorUI) Error(message string)
```
Error calls UI.Error to write. ErrorFGColor and ErrorBGColor are used for color.
#### func (*ColorUI) Info
```go
func (ui *ColorUI) Info(message string)
```
Info calls UI.Info to write. Useful when you want separate colors or prefixes.
InfoFGColor and InfoBGColor are used for color.
#### func (*ColorUI) Log
```go
func (ui *ColorUI) Log(message string)
```
Log calls UI.Log to write. LogFGColor and LogBGColor are used for color.
#### func (*ColorUI) Output
```go
func (ui *ColorUI) Output(message string)
```
Output calls UI.Output to write. OutputFGColor and OutputBGColor are used for
color.
#### func (*ColorUI) Running
```go
func (ui *ColorUI) Running(message string)
```
Running calls UI.Running to write. Useful when you want separate colors or
prefixes. RunningFGColor and RunningBGColor are used for color.
#### func (*ColorUI) Success
```go
func (ui *ColorUI) Success(message string)
```
Success calls UI.Success to write. Useful when you want separate colors or
prefixes. SuccessFGColor and SuccessBGColor are used for color.
#### func (*ColorUI) Warn
```go
func (ui *ColorUI) Warn(message string)
```
Warn calls UI.Warn to write. Useful when you want separate colors or prefixes.
WarnFGColor and WarnBGColor are used for color.
#### type ConcurrentUI
```go
type ConcurrentUI struct {
UI UI
}
```
ConcurrentUI is a wrapper for UI that makes the UI thread safe.
#### func AddConcurrent
```go
func AddConcurrent(ui UI) *ConcurrentUI
```
AddConcurrent will wrap a thread safe UI on top of ui. Safe to use inside of go
routines.
#### func (*ConcurrentUI) Ask
```go
func (ui *ConcurrentUI) Ask(message string) (string, error)
```
Ask will call UI.Ask with message then wait for UI.Ask to return a response
and/or error. It will clean the response by removing any carriage returns and
new lines that if finds. If a message is not used ("") then it will not prompt
user before waiting on a response. This is a thread safe function.
#### func (*ConcurrentUI) Error
```go
func (ui *ConcurrentUI) Error(message string)
```
Error calls UI.Error to write. This is a thread safe function.
#### func (*ConcurrentUI) Info
```go
func (ui *ConcurrentUI) Info(message string)
```
Info calls UI.Info to write. Useful when you want separate colors or prefixes.
This is a thread safe function.
#### func (*ConcurrentUI) Log
```go
func (ui *ConcurrentUI) Log(message string)
```
Log calls UI.Log to write. This is a thread safe function.
#### func (*ConcurrentUI) Output
```go
func (ui *ConcurrentUI) Output(message string)
```
Output calls UI.Output to write. This is a thread safe function.
#### func (*ConcurrentUI) Running
```go
func (ui *ConcurrentUI) Running(message string)
```
Running calls UI.Running to write. Useful when you want separate colors or
prefixes. This is a thread safe function.
#### func (*ConcurrentUI) Success
```go
func (ui *ConcurrentUI) Success(message string)
```
Success calls UI.Success to write. Useful when you want separate colors or
prefixes. This is a thread safe function.
#### func (*ConcurrentUI) Warn
```go
func (ui *ConcurrentUI) Warn(message string)
```
Warn calls UI.Warn to write. Useful when you want separate colors or prefixes.
This is a thread safe function.
#### type PrefixUI
```go
type PrefixUI struct {
LogPrefix string
OutputPrefix string
SuccessPrefix string
InfoPrefix string
ErrorPrefix string
WarnPrefix string
RunningPrefix string
AskPrefix string
UI UI
}
```
PrefixUI is a wrapper for UI that prefixes all strings. It does add a space
betweem the prefix and message. If no prefix is specified ("") then it does not
prefix the space.
#### func AddPrefix
```go
func AddPrefix(askPre, errorPre, infoPre, logPre, outputPre, runningPre, successPre, warnPre string, ui UI) *PrefixUI
```
AddPrefix will wrap a UI that will prefix the message on top of ui. If a prefix
is set to nothing ("") then there will be no prefix for that message type.
Arguments are in alphabetical order.
#### func (*PrefixUI) Ask
```go
func (ui *PrefixUI) Ask(message string) (string, error)
```
Ask will call UI.Ask with message then wait for UI.Ask to return a response
and/or error. It will clean the response by removing any carriage returns and
new lines that if finds. If a message is not used ("") then it will not prompt
user before waiting on a response. AskPrefix is used to prefix message.
#### func (*PrefixUI) Error
```go
func (ui *PrefixUI) Error(message string)
```
Error writes message to ErrorWriter. ErrorPrefix is used to prefix the message.
#### func (*PrefixUI) Info
```go
func (ui *PrefixUI) Info(message string)
```
Info calls Output to write. Useful when you want separate colors or prefixes.
InfoPrefix is used to prefix the message.
#### func (*PrefixUI) Log
```go
func (ui *PrefixUI) Log(message string)
```
Log prefixes to message before writing to Writer. LogPrefix is used to prefix
the message.
#### func (*PrefixUI) Output
```go
func (ui *PrefixUI) Output(message string)
```
Output simply writes to Writer. OutputPrefix is used to prefix the message.
#### func (*PrefixUI) Running
```go
func (ui *PrefixUI) Running(message string)
```
Running calls Output to write. Useful when you want separate colors or prefixes.
RunningPrefix is used to prefix message.
#### func (*PrefixUI) Success
```go
func (ui *PrefixUI) Success(message string)
```
Success calls Output to write. Useful when you want separate colors or prefixes.
SuccessPrefix is used to prefix the message.
#### func (*PrefixUI) Warn
```go
func (ui *PrefixUI) Warn(message string)
```
Warn calls Error to write. Useful when you want separate colors or prefixes.
WarnPrefix is used to prefix message.
#### type UI
```go
type UI interface {
Log(string)
Output(string)
Success(string)
Info(string)
Error(string)
Warn(string)
Running(string)
Ask(string) (string, error)
}
```
UI simply writes to an io.Writer with a new line appended to each call. It also
has the ability to ask a question and return a response.

91
vendor/gopkg.in/dixonwille/wlog.v2/basic.go generated vendored Normal file
View File

@@ -0,0 +1,91 @@
package wlog
import (
"bufio"
"fmt"
"io"
"strings"
"time"
)
const (
timeFormat = "2006-01-02T15-04-05"
)
// BasicUI simply writes/reads to correct input/output
// It is not thread safe.
// Pretty simple to wrap your own functions around
type BasicUI struct {
Reader io.Reader
Writer io.Writer
ErrorWriter io.Writer
}
// Log prefixes to message before writing to Writer.
func (ui *BasicUI) Log(message string) {
timeString := time.Now().Format(timeFormat)
message = timeString + ": " + message
ui.Output(message)
}
// Output simply writes to Writer.
func (ui *BasicUI) Output(message string) {
fmt.Fprint(ui.Writer, message)
fmt.Fprint(ui.Writer, "\n")
}
// Success calls Output to write.
// Useful when you want separate colors or prefixes.
func (ui *BasicUI) Success(message string) {
ui.Output(message)
}
// Info calls Output to write.
// Useful when you want separate colors or prefixes.
func (ui *BasicUI) Info(message string) {
ui.Output(message)
}
// Error writes message to ErrorWriter.
func (ui *BasicUI) Error(message string) {
if ui.ErrorWriter != nil {
fmt.Fprint(ui.ErrorWriter, message)
fmt.Fprint(ui.ErrorWriter, "\n")
} else {
fmt.Fprint(ui.Writer, message)
fmt.Fprint(ui.Writer, "\n")
}
}
// Warn calls Error to write.
// Useful when you want separate colors or prefixes.
func (ui *BasicUI) Warn(message string) {
ui.Error(message)
}
// Running calls Output to write.
// Useful when you want separate colors or prefixes.
func (ui *BasicUI) Running(message string) {
ui.Output(message)
}
//Ask will call output with message then wait for Reader to print newline (\n).
//If Reader is os.Stdin then that is when ever a user presses [enter].
//It will clean the response by removing any carriage returns and new lines that if finds.
//Then it will trim the message using the trim variable.
//Use and empty string to specify you do not want to trim.
//If a message is not used ("") then it will not prompt user before waiting on a response.
func (ui *BasicUI) Ask(message, trim string) (string, error) {
if message != "" {
ui.Output(message)
}
reader := bufio.NewReader(ui.Reader)
res, err := reader.ReadString('\n')
if err != nil {
return "", err
}
res = strings.Replace(res, "\r", "", -1) //this will only be useful under windows
res = strings.Replace(res, "\n", "", -1)
res = strings.Trim(res, trim)
return res, err
}

105
vendor/gopkg.in/dixonwille/wlog.v2/colored.go generated vendored Normal file
View File

@@ -0,0 +1,105 @@
package wlog
import "github.com/daviddengcn/go-colortext"
// ColorUI is a wrapper for UI that adds color.
type ColorUI struct {
LogFGColor Color
OutputFGColor Color
SuccessFGColor Color
InfoFGColor Color
ErrorFGColor Color
WarnFGColor Color
RunningFGColor Color
AskFGColor Color
ResponseFGColor Color
LogBGColor Color
OutputBGColor Color
SuccessBGColor Color
InfoBGColor Color
ErrorBGColor Color
WarnBGColor Color
RunningBGColor Color
AskBGColor Color
ResponseBGColor Color
UI UI
}
// Log calls UI.Log to write.
// LogFGColor and LogBGColor are used for color.
func (ui *ColorUI) Log(message string) {
ct.ChangeColor(ui.LogFGColor.Code, ui.LogFGColor.Bright, ui.LogBGColor.Code, ui.LogBGColor.Bright)
ui.UI.Log(message)
ct.ResetColor()
}
// Output calls UI.Output to write.
// OutputFGColor and OutputBGColor are used for color.
func (ui *ColorUI) Output(message string) {
ct.ChangeColor(ui.OutputFGColor.Code, ui.OutputFGColor.Bright, ui.OutputBGColor.Code, ui.OutputBGColor.Bright)
ui.UI.Output(message)
ct.ResetColor()
}
// Success calls UI.Success to write.
// Useful when you want separate colors or prefixes.
// SuccessFGColor and SuccessBGColor are used for color.
func (ui *ColorUI) Success(message string) {
ct.ChangeColor(ui.SuccessFGColor.Code, ui.SuccessFGColor.Bright, ui.SuccessBGColor.Code, ui.SuccessBGColor.Bright)
ui.UI.Success(message)
ct.ResetColor()
}
// Info calls UI.Info to write.
// Useful when you want separate colors or prefixes.
// InfoFGColor and InfoBGColor are used for color.
func (ui *ColorUI) Info(message string) {
ct.ChangeColor(ui.InfoFGColor.Code, ui.InfoFGColor.Bright, ui.InfoBGColor.Code, ui.InfoBGColor.Bright)
ui.UI.Info(message)
ct.ResetColor()
}
// Error calls UI.Error to write.
// ErrorFGColor and ErrorBGColor are used for color.
func (ui *ColorUI) Error(message string) {
ct.ChangeColor(ui.ErrorFGColor.Code, ui.ErrorFGColor.Bright, ui.ErrorBGColor.Code, ui.ErrorBGColor.Bright)
ui.UI.Error(message)
ct.ResetColor()
}
// Warn calls UI.Warn to write.
// Useful when you want separate colors or prefixes.
// WarnFGColor and WarnBGColor are used for color.
func (ui *ColorUI) Warn(message string) {
ct.ChangeColor(ui.WarnFGColor.Code, ui.WarnFGColor.Bright, ui.WarnBGColor.Code, ui.WarnBGColor.Bright)
ui.UI.Warn(message)
ct.ResetColor()
}
// Running calls UI.Running to write.
// Useful when you want separate colors or prefixes.
// RunningFGColor and RunningBGColor are used for color.
func (ui *ColorUI) Running(message string) {
ct.ChangeColor(ui.RunningFGColor.Code, ui.RunningFGColor.Bright, ui.RunningBGColor.Code, ui.RunningBGColor.Bright)
ui.UI.Running(message)
ct.ResetColor()
}
//Ask will call UI.Output with message then wait for UI.Ask to return a response and/or error.
//It will clean the response by removing any carriage returns and new lines that if finds.
//Then it will trim the message using the trim variable.
//Use and empty string to specify you do not want to trim.
//If a message is not used ("") then it will not prompt user before waiting on a response.
//AskFGColor and AskBGColor are used for message color.
//ResponseFGColor and ResponseBGColor are used for response color.
func (ui *ColorUI) Ask(message, trim string) (string, error) {
if message != "" {
ct.ChangeColor(ui.AskFGColor.Code, ui.AskFGColor.Bright, ui.AskBGColor.Code, ui.AskBGColor.Bright)
ui.UI.Output(message)
ct.ResetColor()
}
ct.ChangeColor(ui.ResponseFGColor.Code, ui.ResponseFGColor.Bright, ui.ResponseBGColor.Code, ui.ResponseBGColor.Bright)
res, err := ui.UI.Ask("", trim)
ct.ResetColor()
return res, err
}

63
vendor/gopkg.in/dixonwille/wlog.v2/colors.go generated vendored Normal file
View File

@@ -0,0 +1,63 @@
package wlog
import "github.com/daviddengcn/go-colortext"
// Color is a wrapper for go-colortext.
// Simplifies the use of this package by assigning predefined colors that can be used.
type Color struct {
Code ct.Color
Bright bool
}
var (
//BrightRed creates a bright red color
BrightRed = Color{ct.Red, true}
//BrightBlue creates a bright blue color
BrightBlue = Color{ct.Blue, true}
//BrightYellow creates a bright yellow color
BrightYellow = Color{ct.Yellow, true}
//Red creates a red color
Red = Color{ct.Red, false}
//Blue creaets a blue color
Blue = Color{ct.Blue, false}
//Yellow creates a yellow color
Yellow = Color{ct.Yellow, false}
//BrightGreen creates a bright green color
BrightGreen = Color{ct.Green, true}
//BrightCyan creates a bright cyan color
BrightCyan = Color{ct.Cyan, true}
//BrightMagenta creates a bright magenta color
BrightMagenta = Color{ct.Magenta, true}
//Green creates a green color
Green = Color{ct.Green, false}
//Cyan creates a cyan color
Cyan = Color{ct.Cyan, false}
//Magenta creates a magenta color
Magenta = Color{ct.Magenta, false}
//White creates a white color
White = Color{ct.White, false}
//BrightWhite creates a bright white color
BrightWhite = Color{ct.White, true}
//Black creates a black color
Black = Color{ct.Black, false}
//BrightBlack creates a bright black color
BrightBlack = Color{ct.Black, true}
//None does not change the color
None = Color{ct.None, false}
)

82
vendor/gopkg.in/dixonwille/wlog.v2/concurrent.go generated vendored Normal file
View File

@@ -0,0 +1,82 @@
package wlog
import "sync"
// ConcurrentUI is a wrapper for UI that makes the UI thread safe.
type ConcurrentUI struct {
UI UI
l sync.Mutex
}
// Log calls UI.Log to write.
// This is a thread safe function.
func (ui *ConcurrentUI) Log(message string) {
ui.l.Lock()
defer ui.l.Unlock()
ui.UI.Log(message)
}
// Output calls UI.Output to write.
// This is a thread safe function.
func (ui *ConcurrentUI) Output(message string) {
ui.l.Lock()
defer ui.l.Unlock()
ui.UI.Output(message)
}
// Success calls UI.Success to write.
// Useful when you want separate colors or prefixes.
// This is a thread safe function.
func (ui *ConcurrentUI) Success(message string) {
ui.l.Lock()
defer ui.l.Unlock()
ui.UI.Success(message)
}
// Info calls UI.Info to write.
// Useful when you want separate colors or prefixes.
// This is a thread safe function.
func (ui *ConcurrentUI) Info(message string) {
ui.l.Lock()
defer ui.l.Unlock()
ui.UI.Info(message)
}
// Error calls UI.Error to write.
// This is a thread safe function.
func (ui *ConcurrentUI) Error(message string) {
ui.l.Lock()
defer ui.l.Unlock()
ui.UI.Error(message)
}
// Warn calls UI.Warn to write.
// Useful when you want separate colors or prefixes.
// This is a thread safe function.
func (ui *ConcurrentUI) Warn(message string) {
ui.l.Lock()
defer ui.l.Unlock()
ui.UI.Warn(message)
}
// Running calls UI.Running to write.
// Useful when you want separate colors or prefixes.
// This is a thread safe function.
func (ui *ConcurrentUI) Running(message string) {
ui.l.Lock()
defer ui.l.Unlock()
ui.UI.Running(message)
}
// Ask will call UI.Ask with message then wait for UI.Ask to return a response and/or error.
// It will clean the response by removing any carriage returns and new lines that if finds.
//Then it will trim the message using the trim variable.
//Use and empty string to specify you do not want to trim.
// If a message is not used ("") then it will not prompt user before waiting on a response.
// This is a thread safe function.
func (ui *ConcurrentUI) Ask(message, trim string) (string, error) {
ui.l.Lock()
defer ui.l.Unlock()
res, err := ui.UI.Ask(message, trim)
return res, err
}

14
vendor/gopkg.in/dixonwille/wlog.v2/interface.go generated vendored Normal file
View File

@@ -0,0 +1,14 @@
package wlog
// UI simply writes to an io.Writer with a new line appended to each call.
// It also has the ability to ask a question and return a response.
type UI interface {
Log(string)
Output(string)
Success(string)
Info(string)
Error(string)
Warn(string)
Running(string)
Ask(string, string) (string, error)
}

113
vendor/gopkg.in/dixonwille/wlog.v2/prefix.go generated vendored Normal file
View File

@@ -0,0 +1,113 @@
package wlog
// PrefixUI is a wrapper for UI that prefixes all strings.
// It does add a space betweem the prefix and message.
// If no prefix is specified ("") then it does not prefix the space.
type PrefixUI struct {
LogPrefix string
OutputPrefix string
SuccessPrefix string
InfoPrefix string
ErrorPrefix string
WarnPrefix string
RunningPrefix string
AskPrefix string
UI UI
}
// Log calls UI.Log to write.
// LogPrefix is used to prefix the message.
func (ui *PrefixUI) Log(message string) {
if ui.LogPrefix == " " { //Lets keep the space if they want one
message = ui.LogPrefix + message
} else if ui.LogPrefix != "" {
message = ui.LogPrefix + " " + message
}
ui.UI.Log(message)
}
// Output calls UI.Output to write.
// OutputPrefix is used to prefix the message.
func (ui *PrefixUI) Output(message string) {
if ui.OutputPrefix == " " { //Lets keep the space if they want one
message = ui.OutputPrefix + message
} else if ui.OutputPrefix != "" {
message = ui.OutputPrefix + " " + message
}
ui.UI.Output(message)
}
// Success calls UI.Success to write.
// Useful when you want separate colors or prefixes.
// SuccessPrefix is used to prefix the message.
func (ui *PrefixUI) Success(message string) {
if ui.SuccessPrefix == " " { //Lets keep the space if they want one
message = ui.SuccessPrefix + message
} else if ui.SuccessPrefix != "" {
message = ui.SuccessPrefix + " " + message
}
ui.UI.Success(message)
}
// Info calls UI.Info to write.
// Useful when you want separate colors or prefixes.
// InfoPrefix is used to prefix the message.
func (ui *PrefixUI) Info(message string) {
if ui.InfoPrefix == " " { //Lets keep the space if they want one
message = ui.InfoPrefix + message
} else if ui.InfoPrefix != "" {
message = ui.InfoPrefix + " " + message
}
ui.UI.Info(message)
}
// Error call UI.Error to write.
// ErrorPrefix is used to prefix the message.
func (ui *PrefixUI) Error(message string) {
if ui.ErrorPrefix == " " { //Lets keep the space if they want one
message = ui.ErrorPrefix + message
} else if ui.ErrorPrefix != "" {
message = ui.ErrorPrefix + " " + message
}
ui.UI.Error(message)
}
// Warn calls UI.Warn to write.
// Useful when you want separate colors or prefixes.
// WarnPrefix is used to prefix message.
func (ui *PrefixUI) Warn(message string) {
if ui.WarnPrefix == " " { //Lets keep the space if they want one
message = ui.WarnPrefix + message
} else if ui.WarnPrefix != "" {
message = ui.WarnPrefix + " " + message
}
ui.UI.Warn(message)
}
// Running calls Output to write.
// Useful when you want separate colors or prefixes.
// RunningPrefix is used to prefix message.
func (ui *PrefixUI) Running(message string) {
if ui.RunningPrefix == " " { //Lets keep the space if they want one
message = ui.RunningPrefix + message
} else if ui.RunningPrefix != "" {
message = ui.RunningPrefix + " " + message
}
ui.UI.Running(message)
}
//Ask will call UI.Ask with message then wait for UI.Ask to return a response and/or error.
//It will clean the response by removing any carriage returns and new lines that if finds.
//Then it will trim the message using the trim variable.
//Use and empty string to specify you do not want to trim.
//If a message is not used ("") then it will not prompt user before waiting on a response.
//AskPrefix is used to prefix message.
func (ui *PrefixUI) Ask(message, trim string) (string, error) {
if ui.AskPrefix == " " { //Lets keep the space if they want one
message = ui.AskPrefix + message
} else if ui.AskPrefix != "" {
message = ui.AskPrefix + " " + message
}
res, err := ui.UI.Ask(message, trim)
return res, err
}

12
vendor/gopkg.in/dixonwille/wlog.v2/symbols.go generated vendored Normal file
View File

@@ -0,0 +1,12 @@
package wlog
const (
//These symbols should not be used on windows.
//Use runtime.GOOS to check the OS before using.
//Check displays a checkmark
Check = "\u2713"
//Cross displays an x
Cross = "\u2717"
)

72
vendor/gopkg.in/dixonwille/wlog.v2/wlog.go generated vendored Normal file
View File

@@ -0,0 +1,72 @@
//Package wlog creates simple to use UI structure.
//The UI is used to simply print to the screen.
//There a wrappers that will wrap each other to create a good looking UI.
//You can add color and prefixes as well as make it thread safe.
package wlog
//TODO:10 Add a simple way to split writer between terminal and file
//TODO:0 Add a TableUI
import "io"
//New creates a BasicUI.
//This should be the first function you call.
//This is not thread safe and should only be used in serial applications.
func New(reader io.Reader, writer, errorWriter io.Writer) *BasicUI {
return &BasicUI{
Reader: reader,
Writer: writer,
ErrorWriter: errorWriter,
}
}
// AddConcurrent will wrap a thread safe UI on top of ui.
// Safe to use inside of go routines.
func AddConcurrent(ui UI) *ConcurrentUI {
return &ConcurrentUI{UI: ui}
}
//AddColor will wrap a colorful UI on top of ui.
//Use wlog's color variables for the color.
//All background colors are not changed by this function but you are able to change them manually.
//Just create this structure manually and change any of the background colors you want.
//Arguments are in alphabetical order.
func AddColor(askColor, errorColor, infoColor, logColor, outputColor, responseColor, runningColor, successColor, warnColor Color, ui UI) *ColorUI {
return &ColorUI{
LogFGColor: logColor,
LogBGColor: None,
OutputFGColor: outputColor,
OutputBGColor: None,
SuccessFGColor: successColor,
SuccessBGColor: None,
InfoFGColor: infoColor,
InfoBGColor: None,
ErrorFGColor: errorColor,
ErrorBGColor: None,
WarnFGColor: warnColor,
WarnBGColor: None,
RunningFGColor: runningColor,
RunningBGColor: None,
AskFGColor: askColor,
AskBGColor: None,
ResponseFGColor: responseColor,
ResponseBGColor: None,
UI: ui,
}
}
//AddPrefix will wrap a UI that will prefix the message on top of ui.
//If a prefix is set to nothing ("") then there will be no prefix for that message type.
//Arguments are in alphabetical order.
func AddPrefix(askPre, errorPre, infoPre, logPre, outputPre, runningPre, successPre, warnPre string, ui UI) *PrefixUI {
return &PrefixUI{
LogPrefix: logPre,
OutputPrefix: outputPre,
SuccessPrefix: successPre,
InfoPrefix: infoPre,
ErrorPrefix: errorPre,
WarnPrefix: warnPre,
RunningPrefix: runningPre,
AskPrefix: askPre,
UI: ui,
}
}

22
vendor/gopkg.in/tucnak/telebot.v2/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 llya Kowalewski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

442
vendor/gopkg.in/tucnak/telebot.v2/README.md generated vendored Normal file
View File

@@ -0,0 +1,442 @@
# Telebot
>"I never knew creating Telegram bots could be so _sexy_!"
[![GoDoc](https://godoc.org/gopkg.in/tucnak/telebot.v2?status.svg)](https://godoc.org/gopkg.in/tucnak/telebot.v2)
[![Travis](https://travis-ci.org/tucnak/telebot.svg?branch=v2)](https://travis-ci.org/tucnak/telebot)
```bash
go get -u gopkg.in/tucnak/telebot.v2
```
* [Overview](#overview)
* [Getting Started](#getting-started)
- [Poller](#poller)
- [Commands](#commands)
- [Files](#files)
- [Sendable](#sendable)
- [Editable](#editable)
- [Keyboards](#keyboards)
- [Inline mode](#inline-mode)
* [Contributing](#contributing)
* [Donate](#donate)
* [License](#license)
# Overview
Telebot is a bot framework for [Telegram Bot API](https://core.telegram.org/bots/api).
This package provides the best of its kind API for command routing, inline query requests and keyboards, as well
as callbacks. Actually, I went a couple steps further, so instead of making a 1:1 API wrapper I chose to focus on
the beauty of API and performance. Some of the strong sides of telebot are:
* Real concise API
* Command routing
* Middleware
* Transparent File API
* Effortless bot callbacks
All the methods of telebot API are _extremely_ easy to memorize and get used to. Also, consider Telebot a
highload-ready solution. I'll test and benchmark the most popular actions and if necessary, optimize
against them without sacrificing API quality.
# Getting Started
Let's take a look at the minimal telebot setup:
```go
package main
import (
"time"
"log"
tb "gopkg.in/tucnak/telebot.v2"
)
func main() {
b, err := tb.NewBot(tb.Settings{
Token: "TOKEN_HERE",
Poller: &tb.LongPoller{Timeout: 10 * time.Second},
})
if err != nil {
log.Fatal(err)
return
}
b.Handle("/hello", func(m *tb.Message) {
b.Send(m.Sender, "hello world")
})
b.Start()
}
```
Simple, innit? Telebot's routing system takes care of deliviering updates
to their endpoints, so in order to get to handle any meaningful event,
all you got to do is just plug your function to one of the Telebot-provided
endpoints. You can find the full list
[here](https://godoc.org/gopkg.in/tucnak/telebot.v2#pkg-constants).
```go
b, _ := tb.NewBot(settings)
b.Handle(tb.OnText, func(m *tb.Message) {
// all the text messages that weren't
// captured by existing handlers
})
b.Handle(tb.OnPhoto, func(m *tb.Message) {
// photos only
})
b.Handle(tb.OnChannelPost, func (m *tb.Message) {
// channel posts only
})
b.Handle(tb.Query, func (q *tb.Query) {
// incoming inline queries
})
```
Now there's a dozen of supported endpoints (see package consts). Let me know
if you'd like to see some endpoint or endpoint idea implemented. This system
is completely extensible, so I can introduce them without breaking
backwards-compatibity.
## Poller
Telebot doesn't really care how you provide it with incoming updates, as long
as you set it up with a Poller:
```go
// Poller is a provider of Updates.
//
// All pollers must implement Poll(), which accepts bot
// pointer and subscription channel and start polling
// synchronously straight away.
type Poller interface {
// Poll is supposed to take the bot object
// subscription channel and start polling
// for Updates immediately.
//
// Poller must listen for stop constantly and close
// it as soon as it's done polling.
Poll(b *Bot, updates chan Update, stop chan struct{})
}
```
Telegram Bot API supports long polling and webhook integration. I don't really
care about webhooks, so the only concrete Poller you'll find in the library
is the `LongPoller`. Poller means you can plug telebot into whatever existing
bot infrastructure (load balancers?) you need, if you need to. Another great thing
about pollers is that you can chain them, making some sort of middleware:
```go
poller := &tb.LongPoller{Timeout: 15 * time.Second}
spamProtected := tb.NewMiddlewarePoller(poller, func(upd *tb.Update) bool {
if upd.Message == nil {
return true
}
if strings.Contains(upd.Message.Text, "spam") {
return false
}
return true
})
bot, _ := tb.NewBot(tb.Settings{
// ...
Poller: spamProtected,
})
// graceful shutdown
go func() {
<-time.After(N * time.Second)
bot.Stop()
})()
bot.Start() // blocks until shutdown
fmt.Println(poller.LastUpdateID) // 134237
```
## Commands
When handling commands, Telebot supports both direct (`/command`) and group-like
syntax (`/command@botname`) and will never deliver messages addressed to some
other bot, even if [privacy mode](https://core.telegram.org/bots#privacy-mode) is off.
For simplified deep-linking, telebot also extracts payload:
```go
// Command: /start <PAYLOAD>
b.Handle("/start", func(m *tb.Message) {
if !m.Private() {
return
}
fmt.Println(m.Payload) // <PAYLOAD>
})
```
## Files
>Telegram allows files up to 20 MB in size.
Telebot allows to both upload (from disk / by URL) and download (from Telegram)
and files in bot's scope. Also, sending any kind of media with a File created
from disk will upload the file to Telegram automatically:
```go
a := &tb.Audio{File: tb.FromDisk("file.ogg")}
fmt.Println(a.OnDisk()) // true
fmt.Println(a.InCloud()) // false
// Will upload the file from disk and send it to recipient
bot.Send(recipient, a)
// Next time you'll be sending this very *Audio, Telebot won't
// re-upload the same file but rather utilize its Telegram FileID
bot.Send(otherRecipient, a)
fmt.Println(a.OnDisk()) // true
fmt.Println(a.InCloud()) // true
fmt.Println(a.FileID) // <telegram file id: ABC-DEF1234ghIkl-zyx57W2v1u123ew11>
```
You might want to save certain `File`s in order to avoid re-uploading. Feel free
to marshal them into whatever format, `File` only contain public fields, so no
data will ever be lost.
## Sendable
Send is undoubteldy the most important method in Telebot. `Send()` accepts a
`Recipient` (could be user, group or a channel) and a `Sendable`. FYI, not only
all telebot-provided media types (`Photo`, `Audio`, `Video`, etc.) are `Sendable`,
but you can create composite types of your own. As long as they satisfy `Sendable`,
Telebot will be able to send them out.
```go
// Sendable is any object that can send itself.
//
// This is pretty cool, since it lets bots implement
// custom Sendables for complex kind of media or
// chat objects spanning across multiple messages.
type Sendable interface {
Send(*Bot, Recipient, *SendOptions) (*Message, error)
}
```
The only type at the time that doesn't fit `Send()` is `Album` and there is a reason
for that. Albums were added not so long ago, so they are slightly quirky for backwards
compatibilities sake. In fact, an `Album` can be sent, but never received. Instead,
Telegram returns a `[]Message`, one for each media object in the album:
```go
p := &tb.Photo{File: tb.FromDisk("chicken.jpg")}
v := &tb.Video{File: tb.FromURL("http://video.mp4")}
msgs, err := b.SendAlbum(user, tb.Album{p, v})
```
### Send options
Send options are objects and flags you can pass to `Send()`, `Edit()` and friends
as optional arguments (following the recipient and the text/media). The most
important one is called `SendOptions`, it lets you control _all_ the properties of
the message supported by Telegram. The only drawback is that it's rather
inconvenient to use at times, so `Send()` supports multiple shorthands:
```go
// regular send options
b.Send(user, "text", &tb.SendOptions{
// ...
})
// ReplyMarkup is a part of SendOptions,
// but often it's the only option you need
b.Send(user, "text", &tb.ReplyMarkup{
// ...
})
// flags: no notification && no web link preview
b.Send(user, "text", tb.Silent, tb.NoPreview)
```
Full list of supported option-flags you can find
[here](https://github.com/tucnak/telebot/blob/v2/options.go#L9).
## Editable
If you want to edit some existing message, you don't really need to store the
original `*Message` object. In fact, upon edit, Telegram only requires `chat_id`
and `message_id`. So you don't really need the Message as the whole. Also you
might want to store references to certain messages in the database, so I thought
it made sense for *any* Go struct to be editable as a Telegram message, to implement
`Editable`:
```go
// Editable is an interface for all objects that
// provide "message signature", a pair of 32-bit
// message ID and 64-bit chat ID, both required
// for edit operations.
//
// Use case: DB model struct for messages to-be
// edited with, say two collums: msg_id,chat_id
// could easily implement MessageSig() making
// instances of stored messages editable.
type Editable interface {
// MessageSig is a "message signature".
//
// For inline messages, return chatID = 0.
MessageSig() (messageID int, chatID int64)
}
```
For example, `Message` type is Editable. Here is the implementation of `StoredMessage`
type, provided by telebot:
```go
// StoredMessage is an example struct suitable for being
// stored in the database as-is or being embedded into
// a larger struct, which is often the case (you might
// want to store some metadata alongside, or might not.)
type StoredMessage struct {
MessageID int `sql:"message_id" json:"message_id"`
ChatID int64 `sql:"chat_id" json:"chat_id"`
}
func (x StoredMessage) MessageSig() (int, int64) {
return x.MessageID, x.ChatID
}
```
Why bother at all? Well, it allows you to do things like this:
```go
// just two integer columns in the database
var msgs []tb.StoredMessage
db.Find(&msgs) // gorm syntax
for _, msg := range msgs {
bot.Edit(&msg, "Updated text.")
// or
bot.Delete(&msg)
}
```
I find it incredibly neat. Worth noting, at this point of time there exists
another method in the Edit family, `EditCaption()` which is of a pretty
rare use, so I didn't bother including it to `Edit()`, just like I did with
`SendAlbum()` as it would inevitably lead to unnecessary complications.
```go
var m *Message
// change caption of a photo, audio, etc.
bot.EditCaption(m, "new caption")
```
## Keyboards
Telebot supports both kinds of keyboards Telegram provides: reply and inline
keyboards. Any button can also act as an endpoints for `Handle()`:
```go
func main() {
b, _ := tb.NewBot(tb.Settings{...})
// This button will be displayed in user's
// reply keyboard.
replyBtn := tb.ReplyButton{Text: "🌕 Button #1"}
replyKeys := [][]tb.ReplyButton{
[]tb.ReplyButton{replyBtn},
// ...
}
// And this one — just under the message itself.
// Pressing it will cause the client to send
// the bot a callback.
//
// Make sure Unique stays unique as it has to be
// for callback routing to work.
inlineBtn := tb.InlineButton{
Unique: "sad_moon",
Text: "🌚 Button #2",
}
inlineKeys := [][]tb.InlineButton{
[]tb.InlineButton{inlineBtn},
// ...
}
b.Handle(&replyBtn, func(m *tb.Message) {
// on reply button pressed
})
b.Handle(&inlineBtn, func(c *tb.Callback) {
// on inline button pressed (callback!)
// always respond!
b.Respond(c, &tb.CallbackResponse{...})
})
// Command: /start <PAYLOAD>
b.Handle("/start", func(m *tb.Message) {
if !m.Private() {
return
}
b.Send(m.Sender, "Hello!", &tb.ReplyMarkup{
ReplyKeyboard: replyKeys,
InlineKeyboard: inlineKeys,
})
})
b.Start()
}
```
## Inline mode
So if you want to handle incoming inline queries you better plug the `tb.OnQuery`
endpoint and then use the `Answer()` method to send a list of inline queries
back. I think at the time of writing, telebot supports all of the provided result
types (but not the cached ones). This is how it looks like:
```go
b.Handle(tb.OnQuery, func(q *tb.Query) {
urls := []string{
"http://photo.jpg",
"http://photo2.jpg",
}
results := make(tb.Results, len(urls)) // []tb.Result
for i, url := range urls {
result := &tb.PhotoResult{
URL: url,
// required for photos
ThumbURL: url,
}
results[i] = result
results[i].SetResultID(strconv.Itoa(i)) // It's needed to set a unique string ID for each result
}
err := b.Answer(q, &tb.QueryResponse{
Results: results,
CacheTime: 60, // a minute
})
if err != nil {
fmt.Println(err)
}
})
```
There's not much to talk about really. It also support some form of authentication
through deep-linking. For that, use fields `SwitchPMText` and `SwitchPMParameter`
of `QueryResponse`.
# Contributing
1. Fork it
2. Clone it: `git clone https://github.com/tucnak/telebot`
3. Create your feature branch: `git checkout -b my-new-feature`
4. Make changes and add them: `git add .`
5. Commit: `git commit -m 'Add some feature'`
6. Push: `git push origin my-new-feature`
7. Pull request
# Donate
I do coding for fun but I also try to search for interesting solutions and
optimize them as much as possible.
If you feel like it's a good piece of software, I wouldn't mind a tip!
Bitcoin: `1DkfrFvSRqgBnBuxv9BzAz83dqur5zrdTH`
# License
Telebot is distributed under MIT.

205
vendor/gopkg.in/tucnak/telebot.v2/admin.go generated vendored Normal file
View File

@@ -0,0 +1,205 @@
package telebot
import (
"encoding/json"
"strconv"
"time"
"github.com/pkg/errors"
)
// Rights is a list of privileges available to chat members.
type Rights struct {
CanBeEdited bool `json:"can_be_edited,omitempty"` // 1
CanChangeInfo bool `json:"can_change_info,omitempty"` // 2
CanPostMessages bool `json:"can_post_messages,omitempty"` // 3
CanEditMessages bool `json:"can_edit_messages,omitempty"` // 4
CanDeleteMessages bool `json:"can_delete_messages,omitempty"` // 5
CanInviteUsers bool `json:"can_invite_users,omitempty"` // 6
CanRestrictMembers bool `json:"can_restrict_members,omitempty"` // 7
CanPinMessages bool `json:"can_pin_messages,omitempty"` // 8
CanPromoteMembers bool `json:"can_promote_members,omitempty"` // 9
CanSendMessages bool `json:"can_send_messages,omitempty"` // 10
CanSendMedia bool `json:"can_send_media_messages,omitempty"` // 11
CanSendOther bool `json:"can_send_other_messages,omitempty"` // 12
CanAddPreviews bool `json:"can_add_web_page_previews,omitempty"` // 13
}
// NoRights is the default Rights{}
func NoRights() Rights { return Rights{} }
// NoRestrictions should be used when un-restricting or
// un-promoting user.
//
// member.Rights = NoRestrictions()
// bot.Restrict(chat, member)
//
func NoRestrictions() Rights {
return Rights{
true, false, false, false, false, // 1-5
false, false, false, false, true, // 6-10
true, true, true}
}
// AdminRights could be used to promote user to admin.
func AdminRights() Rights {
return Rights{
true, true, true, true, true, // 1-5
true, true, true, true, true, // 6-10
true, true, true} // 11-13
}
// Forever is a Unixtime of "forever" banning.
func Forever() int64 {
return time.Now().Add(367 * 24 * time.Hour).Unix()
}
// Ban will ban user from chat until `member.RestrictedUntil`.
func (b *Bot) Ban(chat *Chat, member *ChatMember) error {
params := map[string]string{
"chat_id": chat.Recipient(),
"user_id": member.User.Recipient(),
"until_date": strconv.FormatInt(member.RestrictedUntil, 10),
}
respJSON, err := b.Raw("kickChatMember", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
}
// Unban will unban user from chat, who would have thought eh?
func (b *Bot) Unban(chat *Chat, user *User) error {
params := map[string]string{
"chat_id": chat.Recipient(),
"user_id": user.Recipient(),
}
respJSON, err := b.Raw("unbanChatMember", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
}
// Restrict let's you restrict a subset of member's rights until
// member.RestrictedUntil, such as:
//
// * can send messages
// * can send media
// * can send other
// * can add web page previews
//
func (b *Bot) Restrict(chat *Chat, member *ChatMember) error {
prv, until := member.Rights, member.RestrictedUntil
params := map[string]string{
"chat_id": chat.Recipient(),
"user_id": member.User.Recipient(),
"until_date": strconv.FormatInt(until, 10),
}
embedRights(params, prv)
respJSON, err := b.Raw("restrictChatMember", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
}
// Promote lets you update member's admin rights, such as:
//
// * can change info
// * can post messages
// * can edit messages
// * can delete messages
// * can invite users
// * can restrict members
// * can pin messages
// * can promote members
//
func (b *Bot) Promote(chat *Chat, member *ChatMember) error {
prv := member.Rights
params := map[string]string{
"chat_id": chat.Recipient(),
"user_id": member.User.Recipient(),
}
embedRights(params, prv)
respJSON, err := b.Raw("promoteChatMember", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
}
// AdminsOf return a member list of chat admins.
//
// On success, returns an Array of ChatMember objects that
// contains information about all chat administrators except other bots.
// If the chat is a group or a supergroup and
// no administrators were appointed, only the creator will be returned.
func (b *Bot) AdminsOf(chat *Chat) ([]ChatMember, error) {
params := map[string]string{
"chat_id": chat.Recipient(),
}
respJSON, err := b.Raw("getChatAdministrators", params)
if err != nil {
return nil, err
}
var resp struct {
Ok bool
Result []ChatMember
Description string `json:"description"`
}
err = json.Unmarshal(respJSON, &resp)
if err != nil {
return nil, errors.Wrap(err, "bad response json")
}
if !resp.Ok {
return nil, errors.Errorf("api error: %s", resp.Description)
}
return resp.Result, nil
}
// Len return the number of members in a chat.
func (b *Bot) Len(chat *Chat) (int, error) {
params := map[string]string{
"chat_id": chat.Recipient(),
}
respJSON, err := b.Raw("getChatMembersCount", params)
if err != nil {
return 0, err
}
var resp struct {
Ok bool
Result int
Description string `json:"description"`
}
err = json.Unmarshal(respJSON, &resp)
if err != nil {
return 0, errors.Wrap(err, "bad response json")
}
if !resp.Ok {
return 0, errors.Errorf("api error: %s", resp.Description)
}
return resp.Result, nil
}

187
vendor/gopkg.in/tucnak/telebot.v2/api.go generated vendored Normal file
View File

@@ -0,0 +1,187 @@
package telebot
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/pkg/errors"
)
// Raw lets you call any method of Bot API manually.
func (b *Bot) Raw(method string, payload interface{}) ([]byte, error) {
url := fmt.Sprintf("https://api.telegram.org/bot%s/%s", b.Token, method)
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(payload); err != nil {
return []byte{}, wrapSystem(err)
}
resp, err := b.client.Post(url, "application/json", &buf)
if err != nil {
return []byte{}, errors.Wrap(err, "http.Post failed")
}
resp.Close = true
defer resp.Body.Close()
json, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte{}, wrapSystem(err)
}
return json, nil
}
func (b *Bot) sendFiles(
method string,
files map[string]string,
params map[string]string) ([]byte, error) {
// ---
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
for name, path := range files {
if err := func() error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
part, err := writer.CreateFormFile(name, filepath.Base(path))
if err != nil {
return err
}
_, err = io.Copy(part, file)
return err
} (); err != nil {
return nil, wrapSystem(err)
}
}
for field, value := range params {
writer.WriteField(field, value)
}
if err := writer.Close(); err != nil {
return nil, wrapSystem(err)
}
url := fmt.Sprintf("https://api.telegram.org/bot%s/%s", b.Token, method)
req, err := http.NewRequest("POST", url, body)
if err != nil {
return nil, wrapSystem(err)
}
req.Header.Add("Content-Type", writer.FormDataContentType())
resp, err := b.client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "http.Post failed")
}
if resp.StatusCode == http.StatusInternalServerError {
return nil, errors.New("api error: internal server error")
}
json, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, wrapSystem(err)
}
return json, nil
}
func (b *Bot) sendObject(f *File, what string, params map[string]string) (*Message, error) {
sendWhat := "send" + strings.Title(what)
if what == "videoNote" {
what = "video_note"
}
var respJSON []byte
var err error
if f.InCloud() {
params[what] = f.FileID
respJSON, err = b.Raw(sendWhat, params)
} else if f.FileURL != "" {
params[what] = f.FileURL
respJSON, err = b.Raw(sendWhat, params)
} else {
respJSON, err = b.sendFiles(sendWhat,
map[string]string{what: f.FileLocal}, params)
}
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
}
func (b *Bot) getMe() (*User, error) {
meJSON, err := b.Raw("getMe", nil)
if err != nil {
return nil, err
}
var botInfo struct {
Ok bool
Result *User
Description string
}
err = json.Unmarshal(meJSON, &botInfo)
if err != nil {
return nil, errors.Wrap(err, "bad response json")
}
if !botInfo.Ok {
return nil, errors.Errorf("api error: %s", botInfo.Description)
}
return botInfo.Result, nil
}
func (b *Bot) getUpdates(offset int, timeout time.Duration) (upd []Update, err error) {
params := map[string]string{
"offset": strconv.Itoa(offset),
"timeout": strconv.Itoa(int(timeout / time.Second)),
}
updatesJSON, errCommand := b.Raw("getUpdates", params)
if errCommand != nil {
err = errCommand
return
}
var updatesReceived struct {
Ok bool
Result []Update
Description string
}
err = json.Unmarshal(updatesJSON, &updatesReceived)
if err != nil {
err = errors.Wrap(err, "bad response json")
return
}
if !updatesReceived.Ok {
err = errors.Errorf("api error: %s", updatesReceived.Description)
return
}
return updatesReceived.Result, nil
}

1144
vendor/gopkg.in/tucnak/telebot.v2/bot.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

81
vendor/gopkg.in/tucnak/telebot.v2/callbacks.go generated vendored Normal file
View File

@@ -0,0 +1,81 @@
package telebot
// CallbackEndpoint is an interface any element capable
// of responding to a callback `\f<unique>`.
type CallbackEndpoint interface {
CallbackUnique() string
}
// Callback object represents a query from a callback button in an
// inline keyboard.
type Callback struct {
ID string `json:"id"`
// For message sent to channels, Sender may be empty
Sender *User `json:"from"`
// Message will be set if the button that originated the query
// was attached to a message sent by a bot.
Message *Message `json:"message"`
// MessageID will be set if the button was attached to a message
// sent via the bot in inline mode.
MessageID string `json:"inline_message_id"`
// Data associated with the callback button. Be aware that
// a bad client can send arbitrary data in this field.
Data string `json:"data"`
}
// CallbackResponse builds a response to a Callback query.
//
// See also: https://core.telegram.org/bots/api#answerCallbackQuery
type CallbackResponse struct {
// The ID of the callback to which this is a response.
//
// Note: Telebot sets this field automatically!
CallbackID string `json:"callback_query_id"`
// Text of the notification. If not specified, nothing will be
// shown to the user.
Text string `json:"text,omitempty"`
// (Optional) If true, an alert will be shown by the client instead
// of a notification at the top of the chat screen. Defaults to false.
ShowAlert bool `json:"show_alert,omitempty"`
// (Optional) URL that will be opened by the user's client.
// If you have created a Game and accepted the conditions via
// @BotFather, specify the URL that opens your game.
//
// Note: this will only work if the query comes from a game
// callback button. Otherwise, you may use deep-linking:
// https://telegram.me/your_bot?start=XXXX
URL string `json:"url,omitempty"`
}
// InlineButton represents a button displayed in the message.
type InlineButton struct {
// Unique slagish name for this kind of button,
// try to be as specific as possible.
//
// It will be used as a callback endpoint.
Unique string `json:"unique,omitempty"`
Text string `json:"text"`
URL string `json:"url,omitempty"`
Data string `json:"callback_data,omitempty"`
InlineQuery string `json:"switch_inline_query,omitempty"`
Action func(*Callback) `json:"-"`
}
// CallbackUnique returns InlineButto.Unique.
func (t *InlineButton) CallbackUnique() string {
return "\f" + t.Unique
}
// CallbackUnique returns KeyboardButton.Text.
func (t *ReplyButton) CallbackUnique() string {
return t.Text
}

58
vendor/gopkg.in/tucnak/telebot.v2/chat.go generated vendored Normal file
View File

@@ -0,0 +1,58 @@
package telebot
import "strconv"
// User object represents a Telegram user, bot
type User struct {
ID int `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
}
// Recipient returns user ID (see Recipient interface).
func (u *User) Recipient() string {
return strconv.Itoa(u.ID)
}
// Chat object represents a Telegram user, bot, group or a channel.
type Chat struct {
ID int64 `json:"id"`
// See telebot.ChatType and consts.
Type ChatType `json:"type"`
// Won't be there for ChatPrivate.
Title string `json:"title"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
}
// Recipient returns chat ID (see Recipient interface).
func (c *Chat) Recipient() string {
if c.Type == ChatChannel {
return "@" + c.Username
}
return strconv.FormatInt(c.ID, 10)
}
// ChatMember object represents information about a single chat member.
type ChatMember struct {
Rights
User *User `json:"user"`
Role MemberStatus `json:"status"`
// Date when restrictions will be lifted for the user, unix time.
//
// If user is restricted for more than 366 days or less than
// 30 seconds from the current time, they are considered to be
// restricted forever.
//
// Use tb.Forever().
//
RestrictedUntil int64 `json:"until_date,omitempty"`
}

30
vendor/gopkg.in/tucnak/telebot.v2/editable.go generated vendored Normal file
View File

@@ -0,0 +1,30 @@
package telebot
// Editable is an interface for all objects that
// provide "message signature", a pair of 32-bit
// message ID and 64-bit chat ID, both required
// for edit operations.
//
// Use case: DB model struct for messages to-be
// edited with, say two collums: msg_id,chat_id
// could easily implement MessageSig() making
// instances of stored messages editable.
type Editable interface {
// MessageSig is a "message signature".
//
// For inline messages, return chatID = 0.
MessageSig() (messageID string, chatID int64)
}
// StoredMessage is an example struct suitable for being
// stored in the database as-is or being embedded into
// a larger struct, which is often the case (you might
// want to store some metadata alongside, or might not.)
type StoredMessage struct {
MessageID string `sql:"message_id" json:"message_id"`
ChatID int64 `sql:"chat_id" json:"chat_id"`
}
func (x StoredMessage) MessageSig() (string, int64) {
return x.MessageID, x.ChatID
}

70
vendor/gopkg.in/tucnak/telebot.v2/file.go generated vendored Normal file
View File

@@ -0,0 +1,70 @@
package telebot
import (
"os"
)
// File object represents any sort of file.
type File struct {
FileID string `json:"file_id"`
FileSize int `json:"file_size"`
// file on telegram server https://core.telegram.org/bots/api#file
FilePath string `json:"file_path"`
// file on local file system.
FileLocal string `json:"file_local"`
// file on the internet
FileURL string `json:"file_url"`
}
// FromDisk constructs a new local (on-disk) file object.
//
// Note, it returns File, not *File for a very good reason:
// in telebot, File is pretty much an embeddable struct,
// so upon uploading media you'll need to set embedded File
// with something. NewFile() returning File makes it a one-liner.
//
// photo := &tb.Photo{File: tb.FromDisk("chicken.jpg")}
//
func FromDisk(filename string) File {
return File{FileLocal: filename}
}
// FromURL constructs a new file on provided HTTP URL.
//
// Note, it returns File, not *File for a very good reason:
// in telebot, File is pretty much an embeddable struct,
// so upon uploading media you'll need to set embedded File
// with something. NewFile() returning File makes it a one-liner.
//
// photo := &tb.Photo{File: tb.FromURL("https://site.com/picture.jpg")}
//
func FromURL(url string) File {
return File{FileURL: url}
}
func (f *File) stealRef(g *File) {
if g.OnDisk() {
f.FileLocal = g.FileLocal
}
if g.FileURL != "" {
f.FileURL = g.FileURL
}
}
// InCloud tells whether the file is present on Telegram servers.
func (f *File) InCloud() bool {
return f.FileID != ""
}
// OnDisk will return true if file is present on disk.
func (f *File) OnDisk() bool {
if _, err := os.Stat(f.FileLocal); err != nil {
return false
}
return true
}

66
vendor/gopkg.in/tucnak/telebot.v2/filters.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
package telebot
// Filter is some thing that does filtering for
// incoming updates.
//
// Return false if you wish to sieve the update out.
type Filter interface {
Filter(*Update) bool
}
// FilterFunc is basically a lightweight version of Filter.
type FilterFunc func(*Update) bool
func NewChain(parent Poller) *Chain {
c := &Chain{}
c.Poller = parent
c.Filter = func(upd *Update) bool {
for _, filter := range c.Filters {
switch f := filter.(type) {
case Filter:
if !f.Filter(upd) {
return false
}
case FilterFunc:
if !f(upd) {
return false
}
case func(*Update) bool:
if !f(upd) {
return false
}
}
}
return true
}
return c
}
// Chain is a chain of middle
type Chain struct {
MiddlewarePoller
// (Filter | FilterFunc | func(*Update) bool)
Filters []interface{}
}
// Add accepts either Filter interface or FilterFunc
func (c *Chain) Add(filter interface{}) {
switch filter.(type) {
case Filter:
break
case FilterFunc:
break
case func(*Update) bool:
break
default:
panic("telebot: unsupported filter type")
}
c.Filters = append(c.Filters, filter)
}

120
vendor/gopkg.in/tucnak/telebot.v2/inline.go generated vendored Normal file
View File

@@ -0,0 +1,120 @@
package telebot
import (
"encoding/json"
"fmt"
)
// Query is an incoming inline query. When the user sends
// an empty query, your bot could return some default or
// trending results.
type Query struct {
// Unique identifier for this query. 1-64 bytes.
ID string `json:"id"`
// Sender.
From User `json:"from"`
// Sender location, only for bots that request user location.
Location *Location `json:"location"`
// Text of the query (up to 512 characters).
Text string `json:"query"`
// Offset of the results to be returned, can be controlled by the bot.
Offset string `json:"offset"`
}
// QueryResponse builds a response to an inline Query.
// See also: https://core.telegram.org/bots/api#answerinlinequery
type QueryResponse struct {
// The ID of the query to which this is a response.
//
// Note: Telebot sets this field automatically!
QueryID string `json:"inline_query_id"`
// The results for the inline query.
Results Results `json:"results"`
// (Optional) The maximum amount of time in seconds that the result
// of the inline query may be cached on the server.
CacheTime int `json:"cache_time,omitempty"`
// (Optional) Pass True, if results may be cached on the server side
// only for the user that sent the query. By default, results may
// be returned to any user who sends the same query.
IsPersonal bool `json:"is_personal"`
// (Optional) Pass the offset that a client should send in the next
// query with the same text to receive more results. Pass an empty
// string if there are no more results or if you dont support
// pagination. Offset length cant exceed 64 bytes.
NextOffset string `json:"next_offset"`
// (Optional) If passed, clients will display a button with specified
// text that switches the user to a private chat with the bot and sends
// the bot a start message with the parameter switch_pm_parameter.
SwitchPMText string `json:"switch_pm_text,omitempty"`
// (Optional) Parameter for the start message sent to the bot when user
// presses the switch button.
SwitchPMParameter string `json:"switch_pm_parameter,omitempty"`
}
// Result represents one result of an inline query.
type Result interface {
ResultID() string
SetResultID(string)
Process()
}
// Results is a slice wrapper for convenient marshalling.
type Results []Result
// MarshalJSON makes sure IQRs have proper IDs and Type variables set.
func (results Results) MarshalJSON() ([]byte, error) {
for _, result := range results {
if result.ResultID() == "" {
result.SetResultID(fmt.Sprintf("%d", &result))
}
if err := inferIQR(result); err != nil {
return nil, err
}
}
return json.Marshal([]Result(results))
}
func inferIQR(result Result) error {
switch r := result.(type) {
case *ArticleResult:
r.Type = "article"
case *AudioResult:
r.Type = "audio"
case *ContactResult:
r.Type = "contact"
case *DocumentResult:
r.Type = "document"
case *GifResult:
r.Type = "gif"
case *LocationResult:
r.Type = "location"
case *Mpeg4GifResult:
r.Type = "mpeg4_gif"
case *PhotoResult:
r.Type = "photo"
case *VenueResult:
r.Type = "venue"
case *VideoResult:
r.Type = "video"
case *VoiceResult:
r.Type = "voice"
case *StickerResult:
r.Type = "sticker"
default:
return fmt.Errorf("result %v is not supported", result)
}
return nil
}

309
vendor/gopkg.in/tucnak/telebot.v2/inline_types.go generated vendored Normal file
View File

@@ -0,0 +1,309 @@
package telebot
// ResultBase must be embedded into all IQRs.
type ResultBase struct {
// Unique identifier for this result, 1-64 Bytes.
// If left unspecified, a 64-bit FNV-1 hash will be calculated
ID string `json:"id"`
// Ignore. This field gets set automatically.
Type string `json:"type"`
// Optional. Content of the message to be sent.
Content *InputMessageContent `json:"input_message_content,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
}
// ResultID returns ResultBase.ID.
func (r *ResultBase) ResultID() string {
return r.ID
}
// SetResultID sets ResultBase.ID.
func (r *ResultBase) SetResultID(id string) {
r.ID = id
}
func (r *ResultBase) Process() {
if r.ReplyMarkup != nil {
processButtons(r.ReplyMarkup.InlineKeyboard)
}
}
// ArticleResult represents a link to an article or web page.
// See also: https://core.telegram.org/bots/api#inlinequeryresultarticle
type ArticleResult struct {
ResultBase
// Title of the result.
Title string `json:"title"`
// Message text. Shortcut (and mutually exclusive to) specifying
// InputMessageContent.
Text string `json:"message_text,omitempty"`
// Optional. URL of the result.
URL string `json:"url,omitempty"`
// Optional. Pass True, if you don't want the URL to be shown in the message.
HideURL bool `json:"hide_url,omitempty"`
// Optional. Short description of the result.
Description string `json:"description,omitempty"`
// Optional. URL of the thumbnail for the result.
ThumbURL string `json:"thumb_url,omitempty"`
}
// AudioResult represents a link to an mp3 audio file.
type AudioResult struct {
ResultBase
// Title.
Title string `json:"title"`
// A valid URL for the audio file.
URL string `json:"audio_url"`
// Optional. Performer.
Performer string `json:"performer,omitempty"`
// Optional. Audio duration in seconds.
Duration int `json:"audio_duration,omitempty"`
// If Cache != "", it'll be used instead
Cache string `json:"audio_file_id,omitempty"`
}
// ContentResult represents a contact with a phone number.
// See also: https://core.telegram.org/bots/api#inlinequeryresultcontact
type ContactResult struct {
ResultBase
// Contact's phone number.
PhoneNumber string `json:"phone_number"`
// Contact's first name.
FirstName string `json:"first_name"`
// Optional. Contact's last name.
LastName string `json:"last_name,omitempty"`
// Optional. URL of the thumbnail for the result.
ThumbURL string `json:"thumb_url,omitempty"`
}
// DocumentResult represents a link to a file.
// See also: https://core.telegram.org/bots/api#inlinequeryresultdocument
type DocumentResult struct {
ResultBase
// Title for the result.
Title string `json:"title"`
// A valid URL for the file
URL string `json:"document_url"`
// Mime type of the content of the file, either “application/pdf” or
// “application/zip”.
MIME string `json:"mime_type"`
// Optional. Caption of the document to be sent, 0-200 characters.
Caption string `json:"caption,omitempty"`
// Optional. Short description of the result.
Description string `json:"description,omitempty"`
// Optional. URL of the thumbnail (jpeg only) for the file.
ThumbURL string `json:"thumb_url,omitempty"`
// If Cache != "", it'll be used instead
Cache string `json:"document_file_id,omitempty"`
}
// GifResult represents a link to an animated GIF file.
// See also: https://core.telegram.org/bots/api#inlinequeryresultgif
type GifResult struct {
ResultBase
// A valid URL for the GIF file. File size must not exceed 1MB.
URL string `json:"gif_url"`
// Optional. Width of the GIF.
Width int `json:"gif_width,omitempty"`
// Optional. Height of the GIF.
Height int `json:"gif_height,omitempty"`
// Optional. Title for the result.
Title string `json:"title,omitempty"`
// Optional. Caption of the GIF file to be sent, 0-200 characters.
Caption string `json:"caption,omitempty"`
// URL of the static thumbnail for the result (jpeg or gif).
ThumbURL string `json:"thumb_url"`
// If Cache != "", it'll be used instead
Cache string `json:"gif_file_id,omitempty"`
}
// LocationResult represents a location on a map.
// See also: https://core.telegram.org/bots/api#inlinequeryresultlocation
type LocationResult struct {
ResultBase
Location
// Location title.
Title string `json:"title"`
// Optional. Url of the thumbnail for the result.
ThumbURL string `json:"thumb_url,omitempty"`
}
// ResultMpeg4Gif represents a link to a video animation
// (H.264/MPEG-4 AVC video without sound).
// See also: https://core.telegram.org/bots/api#inlinequeryresultmpeg4gif
type Mpeg4GifResult struct {
ResultBase
// A valid URL for the MP4 file.
URL string `json:"mpeg4_url"`
// Optional. Video width.
Width int `json:"mpeg4_width,omitempty"`
// Optional. Video height.
Height int `json:"mpeg4_height,omitempty"`
// URL of the static thumbnail (jpeg or gif) for the result.
ThumbURL string `json:"thumb_url,omitempty"`
// Optional. Title for the result.
Title string `json:"title,omitempty"`
// Optional. Caption of the MPEG-4 file to be sent, 0-200 characters.
Caption string `json:"caption,omitempty"`
// If Cache != "", it'll be used instead
Cache string `json:"mpeg4_file_id,omitempty"`
}
// ResultResult represents a link to a photo.
// See also: https://core.telegram.org/bots/api#inlinequeryresultphoto
type PhotoResult struct {
ResultBase
// A valid URL of the photo. Photo must be in jpeg format.
// Photo size must not exceed 5MB.
URL string `json:"photo_url"`
// Optional. Width of the photo.
Width int `json:"photo_width,omitempty"`
// Optional. Height of the photo.
Height int `json:"photo_height,omitempty"`
// Optional. Title for the result.
Title string `json:"title,omitempty"`
// Optional. Short description of the result.
Description string `json:"description,omitempty"`
// Optional. Caption of the photo to be sent, 0-200 characters.
Caption string `json:"caption,omitempty"`
// URL of the thumbnail for the photo.
ThumbURL string `json:"thumb_url"`
// If Cache != "", it'll be used instead
Cache string `json:"photo_file_id,omitempty"`
}
// VenueResult represents a venue.
// See also: https://core.telegram.org/bots/api#inlinequeryresultvenue
type VenueResult struct {
ResultBase
Location
// Title of the venue.
Title string `json:"title"`
// Address of the venue.
Address string `json:"address"`
// Optional. Foursquare identifier of the venue if known.
FoursquareID string `json:"foursquare_id,omitempty"`
// Optional. URL of the thumbnail for the result.
ThumbURL string `json:"thumb_url,omitempty"`
}
// VideoResult represents a link to a page containing an embedded
// video player or a video file.
// See also: https://core.telegram.org/bots/api#inlinequeryresultvideo
type VideoResult struct {
ResultBase
// A valid URL for the embedded video player or video file.
URL string `json:"video_url"`
// Mime type of the content of video url, “text/html” or “video/mp4”.
MIME string `json:"mime_type"`
// URL of the thumbnail (jpeg only) for the video.
ThumbURL string `json:"thumb_url"`
// Title for the result.
Title string `json:"title"`
// Optional. Caption of the video to be sent, 0-200 characters.
Caption string `json:"caption,omitempty"`
// Optional. Video width.
Width int `json:"video_width,omitempty"`
// Optional. Video height.
Height int `json:"video_height,omitempty"`
// Optional. Video duration in seconds.
Duration int `json:"video_duration,omitempty"`
// Optional. Short description of the result.
Description string `json:"description,omitempty"`
// If Cache != "", it'll be used instead
Cache string `json:"video_file_id,omitempty"`
}
// VoiceResult represents a link to a voice recording in an .ogg
// container encoded with OPUS.
//
// See also: https://core.telegram.org/bots/api#inlinequeryresultvoice
type VoiceResult struct {
ResultBase
// A valid URL for the voice recording.
URL string `json:"voice_url"`
// Recording title.
Title string `json:"title"`
// Optional. Recording duration in seconds.
Duration int `json:"voice_duration"`
// If Cache != "", it'll be used instead
Cache string `json:"voice_file_id,omitempty"`
}
// StickerResult represents an inline cached sticker response.
type StickerResult struct {
ResultBase
// If Cache != "", it'll be used instead
Cache string `json:"sticker_file_id,omitempty"`
}

78
vendor/gopkg.in/tucnak/telebot.v2/input_types.go generated vendored Normal file
View File

@@ -0,0 +1,78 @@
package telebot
// InputMessageContent objects represent the content of a message to be sent
// as a result of an inline query.
// See also: https://core.telegram.org/bots/api#inputmessagecontent
type InputMessageContent interface {
IsInputMessageContent() bool
}
// InputTextMessageContent represents the content of a text message to be
// sent as the result of an inline query.
// See also: https://core.telegram.org/bots/api#inputtextmessagecontent
type InputTextMessageContent struct {
// Text of the message to be sent, 1-4096 characters.
Text string `json:"message_text"`
// Optional. Send Markdown or HTML, if you want Telegram apps to show
// bold, italic, fixed-width text or inline URLs in your bot's message.
ParseMode string `json:"parse_mode,omitempty"`
// Optional. Disables link previews for links in the sent message.
DisablePreview bool `json:"disable_web_page_preview"`
}
func (input *InputTextMessageContent) IsInputMessageContent() bool {
return true
}
// InputLocationMessageContent represents the content of a location message
// to be sent as the result of an inline query.
// See also: https://core.telegram.org/bots/api#inputlocationmessagecontent
type InputLocationMessageContent struct {
Lat float32 `json:"latitude"`
Lng float32 `json:"longitude"`
}
func (input *InputLocationMessageContent) IsInputMessageContent() bool {
return true
}
// InputVenueMessageContent represents the content of a venue message to
// be sent as the result of an inline query.
// See also: https://core.telegram.org/bots/api#inputvenuemessagecontent
type InputVenueMessageContent struct {
Lat float32 `json:"latitude"`
Lng float32 `json:"longitude"`
// Name of the venue.
Title string `json:"title"`
// Address of the venue.
Address string `json:"address"`
// Optional. Foursquare identifier of the venue, if known.
FoursquareID string `json:"foursquare_id,omitempty"`
}
func (input *InputVenueMessageContent) IsInputMessageContent() bool {
return true
}
// InputContactMessageContent represents the content of a contact
// message to be sent as the result of an inline query.
// See also: https://core.telegram.org/bots/api#inputcontactmessagecontent
type InputContactMessageContent struct {
// Contact's phone number.
PhoneNumber string `json:"phone_number"`
// Contact's first name.
FirstName string `json:"first_name"`
// Optional. Contact's last name.
LastName string `json:"last_name,omitempty"`
}
func (input *InputContactMessageContent) IsInputMessageContent() bool {
return true
}

176
vendor/gopkg.in/tucnak/telebot.v2/media.go generated vendored Normal file
View File

@@ -0,0 +1,176 @@
package telebot
import (
"encoding/json"
)
// Album lets you group multiple media (so-called InputMedia)
// into a single messsage.
//
// On older clients albums look like N regular messages.
type Album []InputMedia
// InputMedia is a generic type for all kinds of media you
// can put into an album.
type InputMedia interface {
// As some files must be uploaded (instead of referencing)
// outer layers of Telebot require it.
MediaFile() *File
}
// Photo object represents a single photo file.
type Photo struct {
File
Width int `json:"width"`
Height int `json:"height"`
// (Optional)
Caption string `json:"caption,omitempty"`
}
type photoSize struct {
File
Width int `json:"width"`
Height int `json:"height"`
Caption string `json:"caption,omitempty"`
}
// MediaFile returns &Photo.File
func (p *Photo) MediaFile() *File {
return &p.File
}
// UnmarshalJSON is custom unmarshaller required to abstract
// away the hassle of treating different thumbnail sizes.
// Instead, Telebot chooses the hi-res one and just sticks to
// it.
//
// I really do find it a beautiful solution.
func (p *Photo) UnmarshalJSON(jsonStr []byte) error {
var hq photoSize
if jsonStr[0] == '{' {
if err := json.Unmarshal(jsonStr, &hq); err != nil {
return err
}
} else {
var sizes []photoSize
if err := json.Unmarshal(jsonStr, &sizes); err != nil {
return err
}
hq = sizes[len(sizes)-1]
}
p.File = hq.File
p.Width = hq.Width
p.Height = hq.Height
return nil
}
// Audio object represents an audio file.
type Audio struct {
File
// Duration of the recording in seconds as defined by sender.
Duration int `json:"duration,omitempty"`
// (Optional)
Caption string `json:"caption,omitempty"`
Title string `json:"title,omitempty"`
Performer string `json:"performer,omitempty"`
MIME string `json:"mime_type,omitempty"`
}
// Document object represents a general file (as opposed to Photo or Audio).
// Telegram users can send files of any type of up to 1.5 GB in size.
type Document struct {
File
// Original filename as defined by sender.
FileName string `json:"file_name"`
// (Optional)
Thumbnail *Photo `json:"thumb,omitempty"`
Caption string `json:"caption,omitempty"`
MIME string `json:"mime_type"`
}
// Video object represents a video file.
type Video struct {
File
Width int `json:"width"`
Height int `json:"height"`
Duration int `json:"duration,omitempty"`
// (Optional)
Caption string `json:"caption,omitempty"`
Thumbnail *Photo `json:"thumb,omitempty"`
MIME string `json:"mime_type,omitempty"`
}
// MediaFile returns &Video.File
func (v *Video) MediaFile() *File {
return &v.File
}
// Voice object represents a voice note.
type Voice struct {
File
// Duration of the recording in seconds as defined by sender.
Duration int `json:"duration"`
// (Optional)
MIME string `json:"mime_type,omitempty"`
}
// VideoNote represents a video message (available in Telegram apps
// as of v.4.0).
type VideoNote struct {
File
// Duration of the recording in seconds as defined by sender.
Duration int `json:"duration"`
// (Optional)
Thumbnail *Photo `json:"thumb,omitempty"`
}
// Contact object represents a contact to Telegram user
type Contact struct {
PhoneNumber string `json:"phone_number"`
FirstName string `json:"first_name"`
// (Optional)
LastName string `json:"last_name"`
UserID int `json:"user_id,omitempty"`
}
// Location object represents geographic position.
type Location struct {
// Latitude
Lat float32 `json:"latitude"`
// Longitude
Lng float32 `json:"longitude"`
// Period in seconds for which the location will be updated
// (see Live Locations, should be between 60 and 86400.)
LivePeriod int `json:"live_period,omitempty"`
}
// Venue object represents a venue location with name, address and
// optional foursquare ID.
type Venue struct {
Location Location `json:"location"`
Title string `json:"title"`
Address string `json:"address"`
// (Optional)
FoursquareID string `json:"foursquare_id,omitempty"`
}

267
vendor/gopkg.in/tucnak/telebot.v2/message.go generated vendored Normal file
View File

@@ -0,0 +1,267 @@
package telebot
import (
"strconv"
"time"
)
// Message object represents a message.
type Message struct {
ID int `json:"message_id"`
// For message sent to channels, Sender will be nil
Sender *User `json:"from"`
// Unixtime, use Message.Time() to get time.Time
Unixtime int64 `json:"date"`
// Conversation the message belongs to.
Chat *Chat `json:"chat"`
// For forwarded messages, sender of the original message.
OriginalSender *User `json:"forward_from"`
// For forwarded messages, chat of the original message when
// forwarded from a channel.
OriginalChat *Chat `json:"forward_from_chat"`
// For forwarded messages, unixtime of the original message.
OriginalUnixtime int `json:"forward_date"`
// For replies, ReplyTo represents the original message.
//
// Note that the Message object in this field will not
// contain further ReplyTo fields even if it
// itself is a reply.
ReplyTo *Message `json:"reply_to_message"`
// (Optional) Time of last edit in Unix
LastEdit int64 `json:"edit_date"`
// AlbumID is the unique identifier of a media message group
// this message belongs to.
AlbumID string `json:"media_group_id"`
// Author signature (in channels).
Signature string `json:"author_signature"`
// For a text message, the actual UTF-8 text of the message.
Text string `json:"text"`
// For registered commands, will contain the string payload:
//
// Ex: `/command <payload>` or `/command@botname <payload>`
Payload string `json:"-"`
// For text messages, special entities like usernames, URLs, bot commands,
// etc. that appear in the text.
Entities []MessageEntity `json:"entities,omitempty"`
// Some messages containing media, may as well have a caption.
Caption string `json:"caption,omitempty"`
// For messages with a caption, special entities like usernames, URLs,
// bot commands, etc. that appear in the caption.
CaptionEntities []MessageEntity `json:"caption_entities,omitempty"`
// For an audio recording, information about it.
Audio *Audio `json:"audio"`
// For a gneral file, information about it.
Document *Document `json:"document"`
// For a photo, all available sizes (thumbnails).
Photo *Photo `json:"photo"`
// For a sticker, information about it.
Sticker *Sticker `json:"sticker"`
// For a voice message, information about it.
Voice *Voice `json:"voice"`
// For a video note, information about it.
VideoNote *VideoNote `json:"video_note"`
// For a video, information about it.
Video *Video `json:"video"`
// For a contact, contact information itself.
Contact *Contact `json:"contact"`
// For a location, its longitude and latitude.
Location *Location `json:"location"`
// For a venue, information about it.
Venue *Venue `json:"venue"`
// For a service message, represents a user,
// that just got added to chat, this message came from.
//
// Sender leads to User, capable of invite.
//
// UserJoined might be the Bot itself.
UserJoined *User `json:"new_chat_member"`
// For a service message, represents a user,
// that just left chat, this message came from.
//
// If user was kicked, Sender leads to a User,
// capable of this kick.
//
// UserLeft might be the Bot itself.
UserLeft *User `json:"left_chat_member"`
// For a service message, represents a new title
// for chat this message came from.
//
// Sender would lead to a User, capable of change.
NewGroupTitle string `json:"new_chat_title"`
// For a service message, represents all available
// thumbnails of the new chat photo.
//
// Sender would lead to a User, capable of change.
NewGroupPhoto *Photo `json:"new_chat_photo"`
// For a service message, new members that were added to
// the group or supergroup and information about them
// (the bot itself may be one of these members).
UsersJoined []User `json:"new_chat_members"`
// For a service message, true if chat photo just
// got removed.
//
// Sender would lead to a User, capable of change.
GroupPhotoDeleted bool `json:"delete_chat_photo"`
// For a service message, true if group has been created.
//
// You would recieve such a message if you are one of
// initial group chat members.
//
// Sender would lead to creator of the chat.
GroupCreated bool `json:"group_chat_created"`
// For a service message, true if super group has been created.
//
// You would recieve such a message if you are one of
// initial group chat members.
//
// Sender would lead to creator of the chat.
SuperGroupCreated bool `json:"supergroup_chat_created"`
// For a service message, true if channel has been created.
//
// You would recieve such a message if you are one of
// initial channel administrators.
//
// Sender would lead to creator of the chat.
ChannelCreated bool `json:"channel_chat_created"`
// For a service message, the destination (super group) you
// migrated to.
//
// You would recieve such a message when your chat has migrated
// to a super group.
//
// Sender would lead to creator of the migration.
MigrateTo int64 `json:"migrate_to_chat_id"`
// For a service message, the Origin (normal group) you migrated
// from.
//
// You would recieve such a message when your chat has migrated
// to a super group.
//
// Sender would lead to creator of the migration.
MigrateFrom int64 `json:"migrate_from_chat_id"`
// Specified message was pinned. Note that the Message object
// in this field will not contain further ReplyTo fields even
// if it is itself a reply.
PinnedMessage *Message `json:"pinned_message"`
}
// MessageEntity object represents "special" parts of text messages,
// including hashtags, usernames, URLs, etc.
type MessageEntity struct {
// Specifies entity type.
Type EntityType `json:"type"`
// Offset in UTF-16 code units to the start of the entity.
Offset int `json:"offset"`
// Length of the entity in UTF-16 code units.
Length int `json:"length"`
// (Optional) For EntityTextLink entity type only.
//
// URL will be opened after user taps on the text.
URL string `json:"url,omitempty"`
// (Optional) For EntityTMention entity type only.
User *User `json:"user,omitempty"`
}
// MessageSig satisfies Editable interface (see Editable.)
func (m *Message) MessageSig() (string, int64) {
return strconv.Itoa(m.ID), m.Chat.ID
}
// Time returns the moment of message creation in local time.
func (m *Message) Time() time.Time {
return time.Unix(m.Unixtime, 0)
}
// LastEdited returns time.Time of last edit.
func (m *Message) LastEdited() time.Time {
return time.Unix(m.LastEdit, 0)
}
// IsForwarded says whether message is forwarded copy of another
// message or not.
func (m *Message) IsForwarded() bool {
return m.OriginalSender != nil || m.OriginalChat != nil
}
// IsReply says whether message is a reply to another message.
func (m *Message) IsReply() bool {
return m.ReplyTo != nil
}
// Private returns true, if it's a personal message.
func (m *Message) Private() bool {
return m.Chat.Type == ChatPrivate
}
// FromGroup returns true, if message came from a group OR
// a super group.
func (m *Message) FromGroup() bool {
return m.Chat.Type == ChatGroup || m.Chat.Type == ChatSuperGroup
}
// FromChannel returns true, if message came from a channel.
func (m *Message) FromChannel() bool {
return m.Chat.Type == ChatChannel
}
// IsService returns true, if message is a service message,
// returns false otherwise.
//
// Service messages are automatically sent messages, which
// typically occur on some global action. For instance, when
// anyone leaves the chat or chat title changes.
func (m *Message) IsService() bool {
fact := false
fact = fact || m.UserJoined != nil
fact = fact || len(m.UsersJoined) > 0
fact = fact || m.UserLeft != nil
fact = fact || m.NewGroupTitle != ""
fact = fact || m.NewGroupPhoto != nil
fact = fact || m.GroupPhotoDeleted
fact = fact || m.GroupCreated || m.SuperGroupCreated
fact = fact || (m.MigrateTo != m.MigrateFrom)
return fact
}

146
vendor/gopkg.in/tucnak/telebot.v2/options.go generated vendored Normal file
View File

@@ -0,0 +1,146 @@
package telebot
// Option is a shorcut flag type for certain message features
// (so-called options). It means that instead of passing
// fully-fledged SendOptions* to Send(), you can use these
// flags instead.
//
// Supported options are defined as iota-constants.
type Option int
const (
// NoPreview = SendOptions.DisableWebPagePreview
NoPreview Option = iota
// Silent = SendOptions.DisableNotification
Silent
// ForceReply = ReplyMarkup.ForceReply
ForceReply
// OneTimeKeyboard = ReplyMarkup.OneTimeKeyboard
OneTimeKeyboard
)
// SendOptions has most complete control over in what way the message
// must be sent, providing an API-complete set of custom properties
// and options.
//
// Despite its power, SendOptions is rather inconvenient to use all
// the way through bot logic, so you might want to consider storing
// and re-using it somewhere or be using Option flags instead.
type SendOptions struct {
// If the message is a reply, original message.
ReplyTo *Message
// See ReplyMarkup struct definition.
ReplyMarkup *ReplyMarkup
// For text messages, disables previews for links in this message.
DisableWebPagePreview bool
// Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
DisableNotification bool
// ParseMode controls how client apps render your message.
ParseMode ParseMode
}
func (og *SendOptions) copy() *SendOptions {
cp := *og
if cp.ReplyMarkup != nil {
cp.ReplyMarkup = cp.ReplyMarkup.copy()
}
return &cp
}
// ReplyMarkup controls two convenient options for bot-user communications
// such as reply keyboard and inline "keyboard" (a grid of buttons as a part
// of the message).
type ReplyMarkup struct {
// InlineKeyboard is a grid of InlineButtons displayed in the message.
//
// Note: DO NOT confuse with ReplyKeyboard and other keyboard properties!
InlineKeyboard [][]InlineButton `json:"inline_keyboard,omitempty"`
// ReplyKeyboard is a grid, consisting of keyboard buttons.
//
// Note: you don't need to set HideCustomKeyboard field to show custom keyboard.
ReplyKeyboard [][]ReplyButton `json:"keyboard,omitempty"`
// ForceReply forces Telegram clients to display
// a reply interface to the user (act as if the user
// has selected the bots message and tapped "Reply").
ForceReply bool `json:"force_reply,omitempty"`
// Requests clients to resize the keyboard vertically for optimal fit
// (e.g. make the keyboard smaller if there are just two rows of buttons).
//
// Defaults to false, in which case the custom keyboard is always of the
// same height as the app's standard keyboard.
ResizeReplyKeyboard bool `json:"resize_keyboard,omitempty"`
// Requests clients to hide the reply keyboard as soon as it's been used.
//
// Defaults to false.
OneTimeKeyboard bool `json:"one_time_keyboard,omitempty"`
// Requests clients to remove the reply keyboard.
//
// Dafaults to false.
ReplyKeyboardRemove bool `json:"remove_keyboard,omitempty"`
// Use this param if you want to force reply from
// specific users only.
//
// Targets:
// 1) Users that are @mentioned in the text of the Message object;
// 2) If the bot's message is a reply (has SendOptions.ReplyTo),
// sender of the original message.
Selective bool `json:"selective,omitempty"`
}
func (og *ReplyMarkup) copy() *ReplyMarkup {
cp := *og
cp.ReplyKeyboard = make([][]ReplyButton, len(og.ReplyKeyboard))
for i, row := range og.ReplyKeyboard {
cp.ReplyKeyboard[i] = make([]ReplyButton, len(row))
for j, btn := range row {
cp.ReplyKeyboard[i][j] = btn
}
}
cp.InlineKeyboard = make([][]InlineButton, len(og.InlineKeyboard))
for i, row := range og.InlineKeyboard {
cp.InlineKeyboard[i] = make([]InlineButton, len(row))
for j, btn := range row {
cp.InlineKeyboard[i][j] = btn
}
}
return &cp
}
// ReplyButton represents a button displayed in reply-keyboard.
//
// Set either Contact or Location to true in order to request
// sensitive info, such as user's phone number or current location.
// (Available in private chats only.)
type ReplyButton struct {
Text string `json:"text"`
Contact bool `json:"request_contact,omitempty"`
Location bool `json:"request_location,omitempty"`
Action func(*Callback) `json:"-"`
}
// InlineKeyboardMarkup represents an inline keyboard that appears
// right next to the message it belongs to.
type InlineKeyboardMarkup struct {
// Array of button rows, each represented by
// an Array of KeyboardButton objects.
InlineKeyboard [][]InlineButton `json:"inline_keyboard,omitempty"`
}

106
vendor/gopkg.in/tucnak/telebot.v2/poller.go generated vendored Normal file
View File

@@ -0,0 +1,106 @@
package telebot
import (
"time"
"github.com/pkg/errors"
)
var (
ErrCouldNotUpdate = errors.New("getUpdates() failed")
)
// Poller is a provider of Updates.
//
// All pollers must implement Poll(), which accepts bot
// pointer and subscription channel and start polling
// synchronously straight away.
type Poller interface {
// Poll is supposed to take the bot object
// subscription channel and start polling
// for Updates immediately.
//
// Poller must listen for stop constantly and close
// it as soon as it's done polling.
Poll(b *Bot, updates chan Update, stop chan struct{})
}
// MiddlewarePoller is a special kind of poller that acts
// like a filter for updates. It could be used for spam
// handling, banning or whatever.
//
// For heavy middleware, use increased capacity.
//
type MiddlewarePoller struct {
Capacity int // Default: 1
Poller Poller
Filter func(*Update) bool
}
// NewMiddlewarePoller wait for it... constructs a new middleware poller.
func NewMiddlewarePoller(original Poller, filter func(*Update) bool) *MiddlewarePoller {
return &MiddlewarePoller{
Poller: original,
Filter: filter,
}
}
// Poll sieves updates through middleware filter.
func (p *MiddlewarePoller) Poll(b *Bot, dest chan Update, stop chan struct{}) {
cap := 1
if p.Capacity > 1 {
cap = p.Capacity
}
middle := make(chan Update, cap)
stopPoller := make(chan struct{})
go p.Poller.Poll(b, middle, stopPoller)
for {
select {
// call to stop
case <-stop:
stopPoller <- struct{}{}
// poller is done
case <-stopPoller:
close(stop)
return
case upd := <-middle:
if p.Filter(&upd) {
dest <- upd
}
}
}
}
// LongPoller is a classic LongPoller with timeout.
type LongPoller struct {
Timeout time.Duration
LastUpdateID int
}
// Poll does long polling.
func (p *LongPoller) Poll(b *Bot, dest chan Update, stop chan struct{}) {
go func(stop chan struct{}) {
<-stop
close(stop)
}(stop)
for {
updates, err := b.getUpdates(p.LastUpdateID+1, p.Timeout)
if err != nil {
b.debug(ErrCouldNotUpdate)
continue
}
for _, update := range updates {
p.LastUpdateID = update.ID
dest <- update
}
}
}

188
vendor/gopkg.in/tucnak/telebot.v2/sendable.go generated vendored Normal file
View File

@@ -0,0 +1,188 @@
package telebot
import "fmt"
// Recipient is any possible endpoint you can send
// messages to: either user, group or a channel.
type Recipient interface {
// Must return legit Telegram chat_id or username
Recipient() string
}
// Sendable is any object that can send itself.
//
// This is pretty cool, since it lets bots implement
// custom Sendables for complex kind of media or
// chat objects spanning across multiple messages.
type Sendable interface {
Send(*Bot, Recipient, *SendOptions) (*Message, error)
}
// Send delivers media through bot b to recipient.
func (p *Photo) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"caption": p.Caption,
}
embedSendOptions(params, opt)
msg, err := b.sendObject(&p.File, "photo", params)
if err != nil {
return nil, err
}
msg.Photo.File.stealRef(&p.File)
*p = *msg.Photo
return msg, nil
}
// Send delivers media through bot b to recipient.
func (a *Audio) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"caption": a.Caption,
}
embedSendOptions(params, opt)
msg, err := b.sendObject(&a.File, "audio", params)
if err != nil {
return nil, err
}
msg.Audio.File.stealRef(&a.File)
*a = *msg.Audio
return msg, nil
}
// Send delivers media through bot b to recipient.
func (d *Document) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"caption": d.Caption,
}
embedSendOptions(params, opt)
msg, err := b.sendObject(&d.File, "document", params)
if err != nil {
return nil, err
}
msg.Document.File.stealRef(&d.File)
*d = *msg.Document
return msg, nil
}
// Send delivers media through bot b to recipient.
func (s *Sticker) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
}
embedSendOptions(params, opt)
msg, err := b.sendObject(&s.File, "sticker", params)
if err != nil {
return nil, err
}
msg.Sticker.File.stealRef(&s.File)
*s = *msg.Sticker
return msg, nil
}
// Send delivers media through bot b to recipient.
func (v *Video) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"caption": v.Caption,
}
embedSendOptions(params, opt)
msg, err := b.sendObject(&v.File, "video", params)
if err != nil {
return nil, err
}
msg.Video.File.stealRef(&v.File)
*v = *msg.Video
return msg, nil
}
// Send delivers media through bot b to recipient.
func (v *Voice) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
}
embedSendOptions(params, opt)
msg, err := b.sendObject(&v.File, "voice", params)
if err != nil {
return nil, err
}
msg.Voice.File.stealRef(&v.File)
*v = *msg.Voice
return msg, nil
}
// Send delivers media through bot b to recipient.
func (v *VideoNote) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
}
embedSendOptions(params, opt)
msg, err := b.sendObject(&v.File, "videoNote", params)
if err != nil {
return nil, err
}
msg.VideoNote.File.stealRef(&v.File)
*v = *msg.VideoNote
return msg, nil
}
// Send delivers media through bot b to recipient.
func (x *Location) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"latitude": fmt.Sprintf("%f", x.Lat),
"longitude": fmt.Sprintf("%f", x.Lng),
"live_period": fmt.Sprintf("%d", x.LivePeriod),
}
embedSendOptions(params, opt)
respJSON, err := b.Raw("sendLocation", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
}
// Send delivers media through bot b to recipient.
func (v *Venue) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"latitude": fmt.Sprintf("%f", v.Location.Lat),
"longitude": fmt.Sprintf("%f", v.Location.Lng),
"title": v.Title,
"address": v.Address,
"foursquare_id": v.FoursquareID,
}
embedSendOptions(params, opt)
respJSON, err := b.Raw("sendVenue", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
}

23
vendor/gopkg.in/tucnak/telebot.v2/stickers.go generated vendored Normal file
View File

@@ -0,0 +1,23 @@
package telebot
// Sticker object represents a WebP image, so-called sticker.
type Sticker struct {
File
Width int `json:"width"`
Height int `json:"height"`
Thumbnail *Photo `json:"thumb,omitempty"`
Emoji string `json:"emoji,omitempty"`
SetName string `json:"set_name,omitempty"`
MaskPosition *MaskPosition `json:"mask_position,omitempty"`
}
// MaskPosition describes the position on faces where
// a mask should be placed by default.
type MaskPosition struct {
Feature MaskFeature `json:"point"`
XShift float32 `json:"x_shift"`
YShift float32 `json:"y_shift"`
Scale float32 `json:"scale"`
}

158
vendor/gopkg.in/tucnak/telebot.v2/telebot.go generated vendored Normal file
View File

@@ -0,0 +1,158 @@
// Package telebot is a framework for Telegram bots.
//
// Example:
//
// import (
// "time"
// tb "gopkg.in/tucnak/telebot.v2"
// )
//
// func main() {
// b, err := tb.NewBot(tb.Settings{
// Token: "TOKEN_HERE",
// Poller: &tb.LongPoller{10 * time.Second},
// })
//
// if err != nil {
// return
// }
//
// b.Handle(tb.OnMessage, func(m *tb.Message) {
// b.Send(m.Sender, "hello world")
// }
//
// b.Start()
// }
//
package telebot
// These are one of the possible events Handle() can deal with.
//
// For convenience, all Telebot-provided endpoints start with
// an "alert" character \a.
const (
// Basic message handlers.
//
// Handler: func(*Message)
OnText = "\atext"
OnPhoto = "\aphoto"
OnAudio = "\aaudio"
OnDocument = "\adocument"
OnSticker = "\asticker"
OnVideo = "\avideo"
OnVoice = "\avoice"
OnVideoNote = "\avideo_note"
OnContact = "\acontact"
OnLocation = "\alocation"
OnVenue = "\avenue"
OnEdited = "\aedited"
OnPinned = "\apinned"
OnChannelPost = "\achan_post"
OnEditedChannelPost = "\achan_edited_post"
// Will fire when bot is added to a group.
OnAddedToGroup = "\aadded_to_group"
// Group events:
OnUserJoined = "\auser_joined"
OnUserLeft = "\auser_left"
OnNewGroupTitle = "\anew_chat_title"
OnNewGroupPhoto = "\anew_chat_photo"
OnGroupPhotoDeleted = "\achat_photo_del"
// Migration happens when group switches to
// a super group. You might want to update
// your internal references to this chat
// upon switching as its ID will change.
//
// Handler: func(from, to int64)
OnMigration = "\amigration"
// Will fire on callback requests.
//
// Handler: func(*Callback)
OnCallback = "\acallback"
// Will fire on incoming inline queries.
//
// Handler: func(*Query)
OnQuery = "\aquery"
// Will fire on chosen inline results.
//
// Handler: func(*ChosenInlineResult)
OnChosenInlineResult = "\achosen_inline_result"
)
// ChatAction is a client-side status indicating bot activity.
type ChatAction string
const (
Typing ChatAction = "typing"
UploadingPhoto ChatAction = "upload_photo"
UploadingVideo ChatAction = "upload_video"
UploadingAudio ChatAction = "upload_audio"
UploadingDocument ChatAction = "upload_document"
UploadingVNote ChatAction = "upload_video_note"
RecordingVideo ChatAction = "record_video"
RecordingAudio ChatAction = "record_audio"
FindingLocation ChatAction = "find_location"
)
// ParseMode determines the way client applications treat the text of the message
type ParseMode string
const (
ModeDefault ParseMode = ""
ModeMarkdown ParseMode = "Markdown"
ModeHTML ParseMode = "HTML"
)
// EntityType is a MessageEntity type.
type EntityType string
const (
EntityMention EntityType = "mention"
EntityTMention EntityType = "text_mention"
EntityHashtag EntityType = "hashtag"
EntityCommand EntityType = "bot_command"
EntityURL EntityType = "url"
EntityEmail EntityType = "email"
EntityBold EntityType = "bold"
EntityItalic EntityType = "italic"
EntityCode EntityType = "code"
EntityCodeBlock EntityType = "pre"
EntityTextLink EntityType = "text_link"
)
// ChatType represents one of the possible chat types.
type ChatType string
const (
ChatPrivate ChatType = "private"
ChatGroup ChatType = "group"
ChatSuperGroup ChatType = "supergroup"
ChatChannel ChatType = "channel"
ChatChannelPrivate ChatType = "privatechannel"
)
// MemberStatus is one's chat status
type MemberStatus string
const (
Creator MemberStatus = "creator"
Administrator MemberStatus = "administrator"
Member MemberStatus = "member"
Restricted MemberStatus = "restricted"
Left MemberStatus = "left"
Kicked MemberStatus = "kicked"
)
// MaskFeature defines sticker mask position.
type MaskFeature string
const (
FeatureForehead MaskFeature = "forehead"
FeatureEyes MaskFeature = "eyes"
FeatureMouth MaskFeature = "mouth"
FeatureChin MaskFeature = "chin"
)

209
vendor/gopkg.in/tucnak/telebot.v2/util.go generated vendored Normal file
View File

@@ -0,0 +1,209 @@
package telebot
import (
"encoding/json"
"strconv"
"github.com/pkg/errors"
)
func (b *Bot) debug(err error) {
if b.reporter != nil {
b.reporter(errors.WithStack(err))
}
}
func (b *Bot) deferDebug() {
if r := recover(); r != nil {
if err, ok := r.(error); ok {
b.debug(err)
} else if str, ok := r.(string); ok {
b.debug(errors.Errorf("%s", str))
}
}
}
func (b *Bot) sendText(to Recipient, text string, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"text": text,
}
embedSendOptions(params, opt)
respJSON, err := b.Raw("sendMessage", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
}
func wrapSystem(err error) error {
return errors.Wrap(err, "system error")
}
func isUserInList(user *User, list []User) bool {
for _, user2 := range list {
if user.ID == user2.ID {
return true
}
}
return false
}
func extractMsgResponse(respJSON []byte) (*Message, error) {
var resp struct {
Ok bool
Result *Message
Description string
}
err := json.Unmarshal(respJSON, &resp)
if err != nil {
var resp struct {
Ok bool
Result bool
Description string
}
err := json.Unmarshal(respJSON, &resp)
if err != nil {
return nil, errors.Wrap(err, "bad response json")
}
if !resp.Ok {
return nil, errors.Errorf("api error: %s", resp.Description)
}
}
if !resp.Ok {
return nil, errors.Errorf("api error: %s", resp.Description)
}
return resp.Result, nil
}
func extractOkResponse(respJSON []byte) error {
var resp struct {
Ok bool
Description string
}
err := json.Unmarshal(respJSON, &resp)
if err != nil {
return errors.Wrap(err, "bad response json")
}
if !resp.Ok {
return errors.Errorf("api error: %s", resp.Description)
}
return nil
}
func extractOptions(how []interface{}) *SendOptions {
var opts *SendOptions
for _, prop := range how {
switch opt := prop.(type) {
case *SendOptions:
opts = opt.copy()
case *ReplyMarkup:
if opts == nil {
opts = &SendOptions{}
}
opts.ReplyMarkup = opt.copy()
case Option:
if opts == nil {
opts = &SendOptions{}
}
switch opt {
case NoPreview:
opts.DisableWebPagePreview = true
case Silent:
opts.DisableNotification = true
case ForceReply:
if opts.ReplyMarkup == nil {
opts.ReplyMarkup = &ReplyMarkup{}
}
opts.ReplyMarkup.ForceReply = true
case OneTimeKeyboard:
if opts.ReplyMarkup == nil {
opts.ReplyMarkup = &ReplyMarkup{}
}
opts.ReplyMarkup.OneTimeKeyboard = true
default:
panic("telebot: unsupported flag-option")
}
case ParseMode:
if opts == nil {
opts = &SendOptions{}
}
opts.ParseMode = opt
default:
panic("telebot: unsupported send-option")
}
}
return opts
}
func embedSendOptions(params map[string]string, opt *SendOptions) {
if opt == nil {
return
}
if opt.ReplyTo != nil && opt.ReplyTo.ID != 0 {
params["reply_to_message_id"] = strconv.Itoa(opt.ReplyTo.ID)
}
if opt.DisableWebPagePreview {
params["disable_web_page_preview"] = "true"
}
if opt.DisableNotification {
params["disable_notification"] = "true"
}
if opt.ParseMode != ModeDefault {
params["parse_mode"] = string(opt.ParseMode)
}
if opt.ReplyMarkup != nil {
processButtons(opt.ReplyMarkup.InlineKeyboard)
replyMarkup, _ := json.Marshal(opt.ReplyMarkup)
params["reply_markup"] = string(replyMarkup)
}
}
func processButtons(keys [][]InlineButton) {
if keys == nil || len(keys) < 1 || len(keys[0]) < 1 {
return
}
for i, _ := range keys {
for j, _ := range keys[i] {
key := &keys[i][j]
if key.Unique != "" {
// Format: "\f<callback_name>|<data>"
data := key.Data
if data == "" {
key.Data = "\f" + key.Unique
} else {
key.Data = "\f" + key.Unique + "|" + data
}
}
}
}
}
func embedRights(p map[string]string, prv Rights) {
jsonRepr, _ := json.Marshal(prv)
json.Unmarshal(jsonRepr, p)
}