@@ -20,6 +20,7 @@ type Bot struct {
2020 FileBaseURL string
2121 Client * http.Client
2222 DailyTokenBudget int64
23+ log Logger
2324}
2425
2526// NewBot creates a new Bot with the given token and a default HTTP client
@@ -32,9 +33,19 @@ func NewBot(token string) *Bot {
3233 Client : & http.Client {
3334 Timeout : 30 * time .Second ,
3435 },
36+ log : NewNopLogger (),
3537 }
3638}
3739
40+ // SetLogger sets the logger for this bot. If nil, a NopLogger is used (no-op).
41+ func (b * Bot ) SetLogger (l Logger ) {
42+ if l == nil {
43+ b .log = NewNopLogger ()
44+ return
45+ }
46+ b .log = l
47+ }
48+
3849// url builds the full API endpoint URL for the given method.
3950func (b * Bot ) url (method string ) string {
4051 return fmt .Sprintf ("%s/%s" , b .BaseURL , method )
@@ -48,19 +59,22 @@ func (b *Bot) doJSON(method string, body any, dest any) error {
4859 var err error
4960 reqBody , err = json .Marshal (body )
5061 if err != nil {
62+ b .log .Error ("marshal request failed" , "method" , method , "error" , err )
5163 return fmt .Errorf ("telegram: marshal request: %w" , err )
5264 }
5365 }
5466
5567 url := b .url (method )
5668 resp , err := b .Client .Post (url , "application/json" , bytes .NewReader (reqBody ))
5769 if err != nil {
70+ b .log .Error ("http post failed" , "method" , method , "error" , err )
5871 return fmt .Errorf ("telegram: post %s: %w" , method , err )
5972 }
6073 defer resp .Body .Close ()
6174
6275 respBody , err := io .ReadAll (resp .Body )
6376 if err != nil {
77+ b .log .Error ("read response body failed" , "method" , method , "error" , err )
6478 return fmt .Errorf ("telegram: read response: %w" , err )
6579 }
6680
@@ -71,15 +85,18 @@ func (b *Bot) doJSON(method string, body any, dest any) error {
7185 ErrorCode int `json:"error_code"`
7286 }
7387 if err := json .Unmarshal (respBody , & apiResp ); err != nil {
88+ b .log .Error ("unmarshal response failed" , "method" , method , "error" , err )
7489 return fmt .Errorf ("telegram: unmarshal response: %w" , err )
7590 }
7691
7792 if ! apiResp .OK {
93+ b .log .Error ("api error" , "method" , method , "description" , apiResp .Description , "error_code" , apiResp .ErrorCode )
7894 return fmt .Errorf ("telegram: %s failed: %s (code %d)" , method , apiResp .Description , apiResp .ErrorCode )
7995 }
8096
8197 if dest != nil && len (apiResp .Result ) > 0 {
8298 if err := json .Unmarshal (apiResp .Result , dest ); err != nil {
99+ b .log .Error ("unmarshal result failed" , "method" , method , "error" , err )
83100 return fmt .Errorf ("telegram: unmarshal result: %w" , err )
84101 }
85102 }
@@ -91,6 +108,7 @@ func (b *Bot) doJSON(method string, body any, dest any) error {
91108func (b * Bot ) doUpload (method string , field string , path string , params map [string ]any , dest any ) error {
92109 file , err := os .Open (path )
93110 if err != nil {
111+ b .log .Error ("open file failed" , "method" , method , "path" , path , "error" , err )
94112 return fmt .Errorf ("telegram: open file %s: %w" , path , err )
95113 }
96114 defer file .Close ()
@@ -101,42 +119,50 @@ func (b *Bot) doUpload(method string, field string, path string, params map[stri
101119 // Write the file part.
102120 part , err := writer .CreateFormFile (field , filepath .Base (path ))
103121 if err != nil {
122+ b .log .Error ("create form file failed" , "method" , method , "field" , field , "error" , err )
104123 return fmt .Errorf ("telegram: create form file: %w" , err )
105124 }
106125 if _ , err := io .Copy (part , file ); err != nil {
126+ b .log .Error ("copy file content failed" , "method" , method , "path" , path , "error" , err )
107127 return fmt .Errorf ("telegram: copy file content: %w" , err )
108128 }
109129
110130 // Write extra parameters as JSON parts.
111131 for key , val := range params {
112132 jsonVal , err := json .Marshal (val )
113133 if err != nil {
134+ b .log .Error ("marshal param failed" , "method" , method , "key" , key , "error" , err )
114135 return fmt .Errorf ("telegram: marshal param %s: %w" , key , err )
115136 }
116137 if err := writer .WriteField (key , string (jsonVal )); err != nil {
138+ b .log .Error ("write field failed" , "method" , method , "key" , key , "error" , err )
117139 return fmt .Errorf ("telegram: write field %s: %w" , key , err )
118140 }
119141 }
120142
121143 if err := writer .Close (); err != nil {
144+ b .log .Error ("close multipart writer failed" , "method" , method , "error" , err )
122145 return fmt .Errorf ("telegram: close multipart writer: %w" , err )
123146 }
124147
125148 url := b .url (method )
126149 req , err := http .NewRequest (http .MethodPost , url , & buf )
127150 if err != nil {
151+ b .log .Error ("create request failed" , "method" , method , "error" , err )
128152 return fmt .Errorf ("telegram: create request: %w" , err )
129153 }
130154 req .Header .Set ("Content-Type" , writer .FormDataContentType ())
131155
132156 resp , err := b .Client .Do (req )
133157 if err != nil {
158+ b .log .Error ("http post failed" , "method" , method , "error" , err )
134159 return fmt .Errorf ("telegram: post %s: %w" , method , err )
135160 }
136161 defer resp .Body .Close ()
137162
138163 respBody , err := io .ReadAll (resp .Body )
139164 if err != nil {
165+ b .log .Error ("read response body failed" , "method" , method , "error" , err )
140166 return fmt .Errorf ("telegram: read response: %w" , err )
141167 }
142168
@@ -147,15 +173,18 @@ func (b *Bot) doUpload(method string, field string, path string, params map[stri
147173 ErrorCode int `json:"error_code"`
148174 }
149175 if err := json .Unmarshal (respBody , & apiResp ); err != nil {
176+ b .log .Error ("unmarshal response failed" , "method" , method , "error" , err )
150177 return fmt .Errorf ("telegram: unmarshal response: %w" , err )
151178 }
152179
153180 if ! apiResp .OK {
181+ b .log .Error ("api error" , "method" , method , "description" , apiResp .Description , "error_code" , apiResp .ErrorCode )
154182 return fmt .Errorf ("telegram: %s failed: %s (code %d)" , method , apiResp .Description , apiResp .ErrorCode )
155183 }
156184
157185 if dest != nil && len (apiResp .Result ) > 0 {
158186 if err := json .Unmarshal (apiResp .Result , dest ); err != nil {
187+ b .log .Error ("unmarshal result failed" , "method" , method , "error" , err )
159188 return fmt .Errorf ("telegram: unmarshal result: %w" , err )
160189 }
161190 }
0 commit comments