Move to using a bot interface instead of a bot struct. This requires quite a large refactor of the core "bot" concept to allow it to work that way, but hopefully all worth it.
There are two main reasons for the move to the interface:
1. Middlewares
The use of an interface means we can chain interfaces together to create middlewares.
This is a big change, allowing us to drastically improve metrics, logs, and error handling.
Examples (Click to expand!)
Adding the following code
```
type LoggingBot struct {
gotgbot.BotClient
}
func (lb *LoggingBot) PostWithContext(ctx context.Context, method string, params map[string]string, data map[string]gotgbot.NamedReader, opts *gotgbot.RequestOpts) (json.RawMessage, error) {
fmt.Println("Applying middleware to", method)
return lb.BotClient.PostWithContext(ctx, method, params, data, opts)
}
func LogEverythingBot(b gotgbot.BotClient) gotgbot.BotClient {
return &LoggingBot{b}
}
```
Then, wrapping an existing bot instance with
```
b.UseMiddleware(LogEverythingBot)
```
Allows you to intercept every POST request directly. You can then modify fields, log errors, and add metrics to track all your requests.
2. Testing framework
This opens the door for a built-in testing framework with the type-safe guarantees that we have in the library now. All one would need is an interface of a BotClient mock! (Note: needs more exploring. Not ready yet!)
Impact
Are your changes backwards compatible?
No. This changes how the Bot struct works, using a BotClient to perform POST calls instead. I expect this to be a small enough change for it to be acceptable.
Have you included documentation, or updated existing documentation? Where possible.
Do errors and log messages provide enough context? N/A.
What
Move to using a bot interface instead of a bot struct. This requires quite a large refactor of the core "bot" concept to allow it to work that way, but hopefully all worth it.
There are two main reasons for the move to the interface:
1. Middlewares
The use of an interface means we can chain interfaces together to create middlewares. This is a big change, allowing us to drastically improve metrics, logs, and error handling.
Examples (Click to expand!)
Adding the following code ``` type LoggingBot struct { gotgbot.BotClient } func (lb *LoggingBot) PostWithContext(ctx context.Context, method string, params map[string]string, data map[string]gotgbot.NamedReader, opts *gotgbot.RequestOpts) (json.RawMessage, error) { fmt.Println("Applying middleware to", method) return lb.BotClient.PostWithContext(ctx, method, params, data, opts) } func LogEverythingBot(b gotgbot.BotClient) gotgbot.BotClient { return &LoggingBot{b} } ``` Then, wrapping an existing bot instance with ``` b.UseMiddleware(LogEverythingBot) ``` Allows you to intercept every POST request directly. You can then modify fields, log errors, and add metrics to track all your requests.2. Testing framework
This opens the door for a built-in testing framework with the type-safe guarantees that we have in the library now. All one would need is an interface of a BotClient mock! (Note: needs more exploring. Not ready yet!)
Impact
Bot
struct works, using aBotClient
to performPOST
calls instead. I expect this to be a small enough change for it to be acceptable.