commit 7e94d8bd48ba45264af83eb076a105f5d203bfd6 Author: Archie Fox Date: Wed May 21 19:35:54 2025 +0300 Init commit diff --git a/clients/telegram/telegram.go b/clients/telegram/telegram.go new file mode 100644 index 0000000..5b2db02 --- /dev/null +++ b/clients/telegram/telegram.go @@ -0,0 +1,96 @@ +package telegram + +import ( + "encoding/json" + "io" + "net/http" + "net/url" + "path" + "strconv" + "tgbot/lib/e" +) + +type Client struct { + host string + basePath string + client http.Client +} + +const ( + getUpdatesMethod = "getUpdates" + sendMessageMethod = "sendMessage" +) + +func New(host, token string) Client { + return Client{ + host: host, + basePath: newBasePath(token), + client: http.Client{}, + } +} + +func newBasePath(token string) string { + return "bot" + token +} + +func (c *Client) Updates(offset int, limit int) ([]Update, error) { + q := url.Values{} + q.Add("offset", strconv.Itoa(offset)) + q.Add("limit", strconv.Itoa(limit)) + + data, err := c.doRequest(getUpdatesMethod, q) + if err != nil { + return nil, err + } + + var res UpdateResponse + + if err := json.Unmarshal(data, &res); err != nil { + return nil, err + } + + return res.Result, nil +} + +func (c *Client) SendMessage(chatID int, text string) error { + q := url.Values{} + q.Add("chat_id", strconv.Itoa(chatID)) + q.Add("text", text) + + _, err := c.doRequest(sendMessageMethod, q) + if err != nil { + return e.Wrap("can't send message", err) + } + + return nil +} + +func (c *Client) doRequest(method string, query url.Values) (data []byte, err error) { + defer func() { err = e.WrapIfErr("can't do request", err) }() + const errMsg = "can't do request" + u := url.URL{ + Scheme: "https", + Host: c.host, + Path: path.Join(c.basePath, method), + } + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return nil, err + } + + req.URL.RawQuery = query.Encode() + + resp, err := c.client.Do(req) + if err != nil { + return nil, err + } + defer func() { _ = resp.Body.Close() }() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return body, nil +} diff --git a/clients/telegram/types.go b/clients/telegram/types.go new file mode 100644 index 0000000..eaecbd5 --- /dev/null +++ b/clients/telegram/types.go @@ -0,0 +1,11 @@ +package telegram + +type UpdateResponse struct { + Ok bool `json:"ok"` + Result []Update `json:"result"` +} + +type Update struct { + ID int `json:"update_id"` + Message string `json:"message"` +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..114f599 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module tgbot + +go 1.24.3 diff --git a/lib/e/e.go b/lib/e/e.go new file mode 100644 index 0000000..a3651f2 --- /dev/null +++ b/lib/e/e.go @@ -0,0 +1,16 @@ +package e + +import "fmt" + +func Wrap(msg string, err error) error { + + return fmt.Errorf("%s: %w", msg, err) +} + +func WrapIfErr(msg string, err error) error { + if err == nil { + return nil + } + + return Wrap(msg, err) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..d90ae02 --- /dev/null +++ b/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "flag" + "log" + "tgbot/clients/telegram" +) + +const ( + tgBotHost = "api.telegram.org" +) + +func main() { + tgClient = telegram.New(tgBotHost, mustToken()) +} + +func mustToken() string { + token := flag.String("token-bot-token", "", "token for access to telegram bot") + + flag.Parse() + + if *token == "" { + log.Fatal("token is not specified") + } + + return *token +}