Compare commits

...

78 commits

Author SHA1 Message Date
c0re100
c9c7701a0d
Change example photo
before GitHub kill me :')
2026-02-13 03:55:26 +08:00
c0re100
0f088c4101
Update to TDLib 1.8.61 2026-02-09 22:29:28 +08:00
c0re100
c1bd67f199
Update to TDLib 1.8.60 2026-01-08 03:52:10 +08:00
c0re100
4597e26403
Update to TDLib 1.8.56 2025-10-16 00:27:32 +08:00
c0re100
926224f707
Update to TDLib 1.8.55 2025-09-28 17:55:16 +08:00
c0re100
9b94728dda
Update to TDLib 1.8.54 2025-09-19 19:09:58 +08:00
c0re100
14418433a4
Update to TDLib 1.8.52 2025-09-02 19:11:19 +08:00
c0re100
5c5078ec42
Fix command parser 2025-09-02 18:58:30 +08:00
c0re100
51f3ce0659
Update to TDLib 1.8.51 2025-07-02 23:52:52 +08:00
c0re100
bc2b5f5823
Update to TDLib 1.8.50 2025-06-10 23:44:57 +08:00
c0re100
969ddb4746
Update to TDLib 1.8.49 2025-05-09 14:42:54 +08:00
c0re100
e5eeec83b3
Fix command parser
Return text without argument
2025-05-02 03:40:05 +08:00
c0re100
3a8d30fd35
Add tde2e to LDFLAGS 2025-05-01 20:45:52 +08:00
c0re100
eb767ed26e
Improve command parser 2025-05-01 20:32:42 +08:00
c0re100
b943b2fe5e
Update to TDLib 1.8.48 2025-05-01 18:13:00 +08:00
c0re100
dc9ae3ed54
Fallback 2025-05-01 18:12:43 +08:00
c0re100
c695d13f46
Update to TDLib 1.8.47 2025-04-13 20:30:45 +08:00
c0re100
05b67218a9
Check space before @ 2025-03-12 00:35:34 +08:00
c0re100
8de0893227
Update to TDLib 1.8.46 2025-03-07 22:22:55 +08:00
c0re100
baee9b059d
Update to TDLib 1.8.45 2025-02-14 02:21:05 +08:00
c0re100
bda4018ed3
Update to TDLib 1.8.44 2025-01-25 06:30:12 +08:00
c0re100
2a5a6d2b76
Merge upstream fix 2025-01-03 06:16:40 +08:00
c0re100
626ffe1a7b
Update to TDLib 1.8.42 2025-01-03 06:02:55 +08:00
c0re100
58adcc4804
Update to TDLib 1.8.41 2024-12-15 02:12:12 +08:00
c0re100
930f3352f3
Update go mod 2024-12-12 14:18:11 +08:00
c0re100
4b010c3b43
Support FreeBSD 2024-11-18 13:15:17 +08:00
c0re100
098715f4f0
Update to TDLib 1.8.40 2024-11-17 21:57:42 +08:00
c0re100
4330cb2fa1
Update to TDLib 1.8.39 2024-11-01 06:19:36 +08:00
c0re100
8454bd8c86
Update to TDLib 1.8.37 2024-10-06 02:49:26 +08:00
c0re100
ec1fb9c5e2
Update to TDLib 1.8.36 2024-09-15 03:36:30 +08:00
c0re100
23e26078e9
Fix command parser 2024-08-27 22:08:45 +08:00
c0re100
4b5b0a30a0
Update to TDLib 1.8.35 2024-08-14 22:18:40 +08:00
c0re100
fa003a9460
Update to TDLib 1.8.34 2024-08-06 06:37:01 +08:00
c0re100
1f84ff6e15
Update to TDLib 1.8.32 2024-07-02 01:51:28 +08:00
c0re100
fefab36108
Update to TDLib 1.8.31 2024-06-19 14:42:06 +08:00
c0re100
b75bf70673
Fix LDFLAGS 2024-06-03 02:28:25 +08:00
c0re100
b5f52a79a6
Update to TDLib 1.8.30 2024-05-29 17:58:55 +08:00
c0re100
3052b01106
Update to TDLib 1.8.29 2024-05-15 05:13:27 +08:00
c0re100
303a126830
Update to TDLib 1.8.28 2024-04-25 00:44:23 +08:00
c0re100
0465eebee7
Update to TDLib 1.8.27 2024-04-01 02:33:46 +08:00
c0re100
7005072ba4
Update to TDLib 1.8.26 2024-03-10 23:09:37 +08:00
c0re100
97ffe5213a
Update to TDLib 1.8.25 2024-02-16 22:13:34 +08:00
c0re100
8f4de4d76e
Update to TDLib 1.8.24 2024-01-29 03:02:25 +08:00
c0re100
e30af65ec7
Update to TDLib 1.8.23 2023-12-30 05:43:03 +08:00
c0re100
af41176160
Update to TDLib 1.8.22 2023-12-03 07:26:26 +08:00
c0re100
563cd7d677
Make some delay to the UpdateMessageSendSucceeded listener 2023-11-27 03:14:17 +08:00
c0re100
ad108a3ee2
Skip check successMsgStore when DisablePatch is true 2023-11-27 01:28:22 +08:00
c0re100
7563ce479c
Allow disable sendMessage patch 2023-11-25 21:08:02 +08:00
c0re100
434963f2c9
Remove unused sync.map 2023-11-25 19:52:46 +08:00
c0re100
4459ee0f55
Fix messageSendingStatePending replacer 2023-11-25 04:24:41 +08:00
c0re100
9a3301fbd7
Update to TDLib 1.8.21 2023-11-07 05:47:05 +08:00
ɥnsʞʎ
83df5e2abb
Fix word spelling, update new UUID package 2023-09-19 00:21:53 +08:00
DukeAnn
9e42c4a4ee 修正单词拼写,更新新的UUID包。(Fix word spelling, update new UUID package) 2023-09-18 21:22:23 +08:00
c0re100
af2b93f686
Update to TDLib 1.8.18 2023-09-16 15:09:40 +08:00
c0re100
26f72d96ce
Restore sendChatScreenshotTakenNotification 2023-08-30 03:53:53 +08:00
c0re100
0b8a2f54dd
Update to TDLib 1.8.16 2023-08-16 02:28:13 +08:00
c0re100
7a1c7f37a2
Update to TDLib 1.8.15 2023-07-25 02:35:55 +08:00
c0re100
e722882047
Update to TDLib 1.8.13 2023-03-26 17:37:06 +08:00
c0re100
47887c89e1
Update to TDLib 1.8.12 2023-03-11 19:13:56 +08:00
c0re100
993b734553
Update example 2023-03-11 19:13:40 +08:00
c0re100
d0f51e73ee
Fix tl scheme 2023-02-05 07:22:52 +08:00
c0re100
869b97df28
Update to TDLib 1.8.11 2023-02-05 06:54:46 +08:00
c0re100
7df275842c
Update to TDLib 1.8.10 2022-12-31 02:28:59 +08:00
c0re100
712b01c11c
Update to TDLib 1.8.9 2022-12-08 04:04:16 +08:00
c0re100
abdd0dfd48
Update to TDLib 1.8.8 2022-11-08 02:50:52 +08:00
c0re100
65692be746
Update authorization state 2022-09-18 09:49:37 +08:00
c0re100
3b10777734
Update to TDLib 1.8.6 2022-09-18 09:34:29 +08:00
c0re100
0b0467fbb7
Remove forwardMessages handler
Bad implementation and it should handled by client side
2022-08-14 22:01:42 +08:00
c0re100
fffcf86198
Update to TDLib 1.8.5 2022-08-13 23:24:07 +08:00
c0re100
51b9da9304
Improve forwardMessages catcher 2022-08-03 09:52:06 +08:00
c0re100
52c9a63fab
Handle updateMessageSendSucceeded if client forward a message 2022-08-02 03:56:09 +08:00
c0re100
d5cf5072c8
Replace message id strictly 2022-08-02 03:53:04 +08:00
c0re100
bbfcb2f946
Update to TDLib 1.8.4 2022-06-22 02:10:07 +08:00
c0re100
1011dc13ae
Update to TDLib master 2022-05-09 19:35:19 +08:00
c0re100
94b077458b
Update to TDLib 1.8.3 2022-04-25 04:33:39 +08:00
c0re100
36a547a560
Update scheme 2022-03-31 16:54:35 +08:00
c0re100
f70d5bf7e6
Update to latest TDLib 2022-03-13 12:04:12 +08:00
c0re100
1d7608dd7c
Update to TDLib 1.8.1 2022-02-07 02:36:17 +08:00
20 changed files with 125238 additions and 48681 deletions

View file

@ -46,7 +46,7 @@ func Authorize(client *Client, authorizationStateHandler AuthorizationStateHandl
} }
type clientAuthorizer struct { type clientAuthorizer struct {
TdlibParameters chan *TdlibParameters TdlibParameters chan *SetTdlibParametersRequest
PhoneNumber chan string PhoneNumber chan string
Code chan string Code chan string
State chan AuthorizationState State chan AuthorizationState
@ -55,7 +55,7 @@ type clientAuthorizer struct {
func ClientAuthorizer() *clientAuthorizer { func ClientAuthorizer() *clientAuthorizer {
return &clientAuthorizer{ return &clientAuthorizer{
TdlibParameters: make(chan *TdlibParameters, 1), TdlibParameters: make(chan *SetTdlibParametersRequest, 1),
PhoneNumber: make(chan string, 1), PhoneNumber: make(chan string, 1),
Code: make(chan string, 1), Code: make(chan string, 1),
State: make(chan AuthorizationState, 10), State: make(chan AuthorizationState, 10),
@ -68,13 +68,7 @@ func (stateHandler *clientAuthorizer) Handle(client *Client, state Authorization
switch state.AuthorizationStateType() { switch state.AuthorizationStateType() {
case TypeAuthorizationStateWaitTdlibParameters: case TypeAuthorizationStateWaitTdlibParameters:
_, err := client.SetTdlibParameters(&SetTdlibParametersRequest{ _, err := client.SetTdlibParameters(<-stateHandler.TdlibParameters)
Parameters: <-stateHandler.TdlibParameters,
})
return err
case TypeAuthorizationStateWaitEncryptionKey:
_, err := client.CheckDatabaseEncryptionKey(&CheckDatabaseEncryptionKeyRequest{})
return err return err
case TypeAuthorizationStateWaitPhoneNumber: case TypeAuthorizationStateWaitPhoneNumber:
@ -169,14 +163,14 @@ func CliInteractor(clientAuthorizer *clientAuthorizer) {
} }
type botAuthorizer struct { type botAuthorizer struct {
TdlibParameters chan *TdlibParameters TdlibParameters chan *SetTdlibParametersRequest
Token chan string Token chan string
State chan AuthorizationState State chan AuthorizationState
} }
func BotAuthorizer(token string) *botAuthorizer { func BotAuthorizer(token string) *botAuthorizer {
botAuthorizer := &botAuthorizer{ botAuthorizer := &botAuthorizer{
TdlibParameters: make(chan *TdlibParameters, 1), TdlibParameters: make(chan *SetTdlibParametersRequest, 1),
Token: make(chan string, 1), Token: make(chan string, 1),
State: make(chan AuthorizationState, 10), State: make(chan AuthorizationState, 10),
} }
@ -191,13 +185,7 @@ func (stateHandler *botAuthorizer) Handle(client *Client, state AuthorizationSta
switch state.AuthorizationStateType() { switch state.AuthorizationStateType() {
case TypeAuthorizationStateWaitTdlibParameters: case TypeAuthorizationStateWaitTdlibParameters:
_, err := client.SetTdlibParameters(&SetTdlibParametersRequest{ _, err := client.SetTdlibParameters(<-stateHandler.TdlibParameters)
Parameters: <-stateHandler.TdlibParameters,
})
return err
case TypeAuthorizationStateWaitEncryptionKey:
_, err := client.CheckDatabaseEncryptionKey(&CheckDatabaseEncryptionKeyRequest{})
return err return err
case TypeAuthorizationStateWaitPhoneNumber: case TypeAuthorizationStateWaitPhoneNumber:

View file

@ -21,6 +21,7 @@ type Client struct {
successMsgStore *sync.Map successMsgStore *sync.Map
updatesTimeout time.Duration updatesTimeout time.Duration
catchTimeout time.Duration catchTimeout time.Duration
DisablePatch bool
} }
type Option func(*Client) type Option func(*Client)
@ -43,6 +44,12 @@ func WithProxy(req *AddProxyRequest) Option {
} }
} }
func WithoutSendMessagePatch() Option {
return func(client *Client) {
client.DisablePatch = true
}
}
func SetLogLevel(level int32) { func SetLogLevel(level int32) {
_, _ = SetLogVerbosityLevel(&SetLogVerbosityLevelRequest{ _, _ = SetLogVerbosityLevel(&SetLogVerbosityLevelRequest{
NewVerbosityLevel: level, NewVerbosityLevel: level,
@ -79,15 +86,15 @@ func NewClient(authorizationStateHandler AuthorizationStateHandler, options ...O
client.extraGenerator = UuidV4Generator() client.extraGenerator = UuidV4Generator()
client.catchTimeout = 60 * time.Second client.catchTimeout = 60 * time.Second
for _, option := range options {
option(client)
}
tdlibInstance.addClient(client) tdlibInstance.addClient(client)
go client.processPendingResponse() go client.processPendingResponse()
go client.receiver() go client.receiver()
for _, option := range options {
go option(client)
}
err := Authorize(client, authorizationStateHandler) err := Authorize(client, authorizationStateHandler)
if err != nil { if err != nil {
return nil, err return nil, err
@ -109,10 +116,10 @@ func (client *Client) processResponse(response *Response) {
return return
} }
if typ.GetType() == (&UpdateMessageSendSucceeded{}).GetType() { if !client.DisablePatch && typ.GetType() == (&UpdateMessageSendSucceeded{}).GetType() {
value, ok := client.successMsgStore.Load(typ.(*UpdateMessageSendSucceeded).OldMessageId) sendVal, sOk := client.successMsgStore.Load(typ.(*UpdateMessageSendSucceeded).OldMessageId)
if ok { if sOk {
value.(chan *Response) <- response sendVal.(chan *Response) <- response
} }
} }
@ -127,7 +134,18 @@ func (client *Client) processResponse(response *Response) {
needGc := false needGc := false
for _, listener := range client.listenerStore.Listeners() { for _, listener := range client.listenerStore.Listeners() {
if listener.IsActive() && listener.Updates != nil && typ.GetType() == listener.Filter.GetType() { // All updates go to Updates channel if type == filter if listener.IsActive() && listener.Updates != nil && typ.GetType() == listener.Filter.GetType() { // All updates go to Updates channel if type == filter
listener.Updates <- typ // Make some delay to UpdateMessageSendSucceeded listener
// This can make UpdateMessageSendSucceeded response later than sendMessage response.
// This may help a bot developer to map temporary message id to actual message id easily.
// Cause an event listener slower than sendMessage response, so you have enough time to do mapping stuff.
if typ.GetType() == (&UpdateMessageSendSucceeded{}).GetType() {
go func(listener *Listener, typ Type) {
time.Sleep(5 * time.Millisecond)
listener.Updates <- typ
}(listener, typ)
} else {
listener.Updates <- typ
}
} else if listener.IsActive() && listener.RawUpdates != nil { // All updates go to RawUpdates channel if filter is empty } else if listener.IsActive() && listener.RawUpdates != nil { // All updates go to RawUpdates channel if filter is empty
listener.RawUpdates <- typ listener.RawUpdates <- typ
} else if !listener.IsActive() { // GC inactive listener } else if !listener.IsActive() { // GC inactive listener
@ -137,6 +155,10 @@ func (client *Client) processResponse(response *Response) {
if needGc { if needGc {
client.listenerStore.gc() client.listenerStore.gc()
} }
if typ.GetType() == TypeUpdateAuthorizationState && typ.(*UpdateAuthorizationState).AuthorizationState.AuthorizationStateType() == TypeAuthorizationStateClosed {
close(client.responses)
}
} }
func (client *Client) receiver() { func (client *Client) receiver() {
@ -184,7 +206,7 @@ func (client *Client) Send(req Request) (*Response, error) {
select { select {
case response := <-catcher: case response := <-catcher:
if response.Type != "error" && req.Type == "sendMessage" { if !client.DisablePatch && response.Type != "error" && req.Type == "sendMessage" {
m, err := UnmarshalMessage(response.Data) m, err := UnmarshalMessage(response.Data)
if err != nil { if err != nil {
return nil, err return nil, err
@ -205,8 +227,8 @@ func (client *Client) Send(req Request) (*Response, error) {
if err2 != nil { if err2 != nil {
return response, nil return response, nil
} }
response.Data = bytes.Replace(response.Data, []byte("{\"@type\":\"messageSendingStatePending\"}"), []byte("{\"@type\":\"updateMessageSendSucceeded\"}"), 1) response.Data = bytes.Replace(response.Data, []byte("\"@type\":\"messageSendingStatePending\""), []byte("\"@type\":\"updateMessageSendSucceeded\""), 1)
response.Data = bytes.Replace(response.Data, []byte(strconv.FormatInt(m.Id, 10)), []byte(strconv.FormatInt(m2.Message.Id, 10)), 1) response.Data = bytes.Replace(response.Data, []byte("\"id\":"+strconv.FormatInt(m.Id, 10)), []byte("\"id\":"+strconv.FormatInt(m2.Message.Id, 10)), 1)
return response, nil return response, nil
case <-time.After(1 * time.Second): case <-time.After(1 * time.Second):
return response, nil return response, nil
@ -239,7 +261,3 @@ func (client *Client) AddEventReceiver(msgType Type, channelCapacity int) *Liste
return listener return listener
} }
func (client *Client) Stop() {
client.Destroy()
}

View file

@ -1,67 +1,49 @@
package client package client
import ( import (
"fmt"
"math/rand"
"strings" "strings"
"github.com/google/uuid"
) )
type ExtraGenerator func() string type ExtraGenerator func() string
func UuidV4Generator() ExtraGenerator { func UuidV4Generator() ExtraGenerator {
return func() string { return func() string {
var uuid [16]byte return uuid.NewString()
rand.Read(uuid[:])
uuid[6] = (uuid[6] & 0x0f) | 0x40
uuid[8] = (uuid[8] & 0x3f) | 0x80
return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", uuid[:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:])
} }
} }
func IsCommmand(text string) bool { func IsCommand(text string) bool {
if text != "" { if i := strings.Index(text, "/"); i == 0 {
if text[0] == '/' { return true
return true
}
} }
return false return false
} }
func CheckCommand(text string, entities []*TextEntity) string { func CheckCommand(text string, entities []*TextEntity) string {
if IsCommmand(text) { if IsCommand(text) {
// Check text entities and make bot happy! cmd := text
if len(entities) >= 1 {
// Get first command // e.g. ["/hello 123", "/hell o 123"]
if entities[0].Type.TextEntityTypeType() == "textEntityTypeBotCommand" { // Result: "/hello", "/hell"
// e.g.: { "text": "/hello@world_bot", "textEntity": { offset: 0, length: 16 } } if i := strings.Index(cmd, " "); i != -1 {
// Result: "/hello" cmd = cmd[:i]
if i := strings.Index(text[:entities[0].Length], "@"); i != -1 {
return text[:i]
}
return text[:entities[0].Length]
}
} else {
// Since userbot does not have bot command entities in Private Chat, so make userbot happy too!
// e.g.: ["/hello@world_bot", "/hello@", "/hello@123"]
// Result: "/hello"
if i := strings.Index(text, "@"); i != -1 {
return text[:i]
}
// e.g. ["/hello 123", "/hell o 123"]
// Result: "/hello", "/hell"
if i := strings.Index(text, " "); i != -1 {
return text[:i]
}
return text
} }
// e.g.: ["/hello@world_bot", "/hello@", "/hello@123"]
// Result: "/hello"
if i := strings.Index(cmd, "@"); i != -1 {
cmd = cmd[:i]
}
return cmd
} }
return "" return ""
} }
func CommandArgument(text string) string { func CommandArgument(text string) string {
if IsCommmand(text) { if IsCommand(text) {
// e.g. ["/hello 123", "/hell o 123"] // e.g. ["/hello 123", "/hell o 123"]
// Result: "123", "o 123" // Result: "123", "o 123"
if i := strings.Index(text, " "); i != -1 { if i := strings.Index(text, " "); i != -1 {

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,12 @@
package client package client
//#cgo linux CFLAGS: -I/usr/local/include //#cgo linux CFLAGS: -I/usr/local/include
//#cgo freebsd CFLAGS: -I/usr/local/include
//#cgo darwin CFLAGS: -I/usr/local/include //#cgo darwin CFLAGS: -I/usr/local/include
//#cgo windows CFLAGS: -IE:/src/tdlib -IE:/src/tdlib/build //#cgo windows CFLAGS: -IE:/src/tdlib -IE:/src/tdlib/build
//#cgo linux LDFLAGS: -L/usr/local/lib -ltdjson_static -ltdjson_private -ltdclient -ltdcore -ltdapi -ltdactor -ltddb -ltdsqlite -ltdnet -ltdutils -lstdc++ -lssl -lcrypto -ldl -lz -lm //#cgo linux LDFLAGS: -L/usr/local/lib -ltdjson_static -ltdjson_private -ltdclient -ltdcore -ltdapi -ltdactor -ltddb -ltde2e -ltdsqlite -ltdmtproto -ltdnet -ltdutils -lstdc++ -lssl -lcrypto -ldl -lz -lm
//#cgo darwin LDFLAGS: -L/usr/local/lib -L/usr/local/opt/openssl/lib -ltdjson_static -ltdjson_private -ltdclient -ltdcore -ltdapi -ltdactor -ltddb -ltdsqlite -ltdnet -ltdutils -lstdc++ -lssl -lcrypto -ldl -lz -lm //#cgo freebsd LDFLAGS: -L/usr/local/lib -ltdjson_static -ltdjson_private -ltdclient -ltdcore -ltdapi -ltdactor -ltddb -ltde2e -ltdsqlite -ltdmtproto -ltdnet -ltdutils -lstdc++ -lssl -lcrypto -ldl -lz -lm
//#cgo darwin LDFLAGS: -L/usr/local/lib -L/usr/local/opt/openssl/lib -ltdjson_static -ltdjson_private -ltdclient -ltdcore -ltdapi -ltdactor -ltddb -ltde2e -ltdsqlite -ltdmtproto -ltdnet -ltdutils -lstdc++ -lssl -lcrypto -ldl -lz -lm
//#cgo windows LDFLAGS: -LE:/src/tdlib/build/Release -ltdjson //#cgo windows LDFLAGS: -LE:/src/tdlib/build/Release -ltdjson
//#include <stdlib.h> //#include <stdlib.h>
//#include <td/telegram/td_json_client.h> //#include <td/telegram/td_json_client.h>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -9,23 +9,21 @@ import (
tdlib "github.com/c0re100/gotdlib/client" tdlib "github.com/c0re100/gotdlib/client"
) )
func GetTdParameters() *tdlib.TdlibParameters { func GetTdParameters() *tdlib.SetTdlibParametersRequest {
return &tdlib.TdlibParameters{ return &tdlib.SetTdlibParametersRequest{
UseTestDc: false, UseTestDc: false,
DatabaseDirectory: "./tdlib-db", DatabaseDirectory: "./tdlib-db",
FilesDirectory: "./tdlib-files", FilesDirectory: "./tdlib-files",
UseFileDatabase: true, UseFileDatabase: true,
UseChatInfoDatabase: true, UseChatInfoDatabase: true,
UseMessageDatabase: true, UseMessageDatabase: true,
UseSecretChats: false, UseSecretChats: false,
ApiId: 132712, ApiId: 132712,
ApiHash: "e82c07ad653399a37baca8d1e498e472", ApiHash: "e82c07ad653399a37baca8d1e498e472",
SystemLanguageCode: "en", SystemLanguageCode: "en",
DeviceModel: "HuskyNG", DeviceModel: "HuskyNG",
SystemVersion: "3.0", SystemVersion: "3.0",
ApplicationVersion: "3.0", ApplicationVersion: "3.0",
EnableStorageOptimizer: true,
IgnoreFileNames: false,
} }
} }
@ -60,7 +58,7 @@ func main() {
log.Fatalf("GetMe error: %s", err) log.Fatalf("GetMe error: %s", err)
} }
log.Printf("%s connected", me.Username) log.Printf("%v connected", me.Usernames)
listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000) listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000)
@ -86,8 +84,10 @@ func main() {
ParseMode: &tdlib.TextParseModeHTML{}, ParseMode: &tdlib.TextParseModeHTML{},
}) })
m, err := client.SendMessage(&tdlib.SendMessageRequest{ m, err := client.SendMessage(&tdlib.SendMessageRequest{
ChatId: chatId, ChatId: chatId,
ReplyToMessageId: msgId, ReplyTo: &tdlib.InputMessageReplyToMessage{
MessageId: msgId,
},
InputMessageContent: &tdlib.InputMessageText{ InputMessageContent: &tdlib.InputMessageText{
Text: text, Text: text,
}, },

View file

@ -17,23 +17,21 @@ func GetSenderId(sender tdlib.MessageSender) int64 {
} }
} }
func GetTdParameters() *tdlib.TdlibParameters { func GetTdParameters() *tdlib.SetTdlibParametersRequest {
return &tdlib.TdlibParameters{ return &tdlib.SetTdlibParametersRequest{
UseTestDc: false, UseTestDc: false,
DatabaseDirectory: "./tdlib-db", DatabaseDirectory: "./tdlib-db",
FilesDirectory: "./tdlib-files", FilesDirectory: "./tdlib-files",
UseFileDatabase: true, UseFileDatabase: true,
UseChatInfoDatabase: true, UseChatInfoDatabase: true,
UseMessageDatabase: true, UseMessageDatabase: true,
UseSecretChats: false, UseSecretChats: false,
ApiId: 132712, ApiId: 132712,
ApiHash: "e82c07ad653399a37baca8d1e498e472", ApiHash: "e82c07ad653399a37baca8d1e498e472",
SystemLanguageCode: "en", SystemLanguageCode: "en",
DeviceModel: "HuskyNG", DeviceModel: "HuskyNG",
SystemVersion: "3.0", SystemVersion: "3.0",
ApplicationVersion: "3.0", ApplicationVersion: "3.0",
EnableStorageOptimizer: true,
IgnoreFileNames: false,
} }
} }
@ -68,7 +66,7 @@ func main() {
log.Fatalf("GetMe error: %s", err) log.Fatalf("GetMe error: %s", err)
} }
log.Printf("%s connected", me.Username) log.Printf("%v connected", me.Usernames)
listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000) listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000)
@ -97,8 +95,10 @@ func main() {
ParseMode: &tdlib.TextParseModeHTML{}, ParseMode: &tdlib.TextParseModeHTML{},
}) })
m, err := client.SendMessage(&tdlib.SendMessageRequest{ m, err := client.SendMessage(&tdlib.SendMessageRequest{
ChatId: chatId, ChatId: chatId,
ReplyToMessageId: msgId, ReplyTo: &tdlib.InputMessageReplyToMessage{
MessageId: msgId,
},
InputMessageContent: &tdlib.InputMessageText{ InputMessageContent: &tdlib.InputMessageText{
Text: text, Text: text,
}, },
@ -109,8 +109,10 @@ func main() {
log.Printf("Message sent, ID: %d", m.Id) log.Printf("Message sent, ID: %d", m.Id)
case "/repeat": case "/repeat":
m, err := client.SendMessage(&tdlib.SendMessageRequest{ m, err := client.SendMessage(&tdlib.SendMessageRequest{
ChatId: chatId, ChatId: chatId,
ReplyToMessageId: msgId, ReplyTo: &tdlib.InputMessageReplyToMessage{
MessageId: msgId,
},
InputMessageContent: &tdlib.InputMessageText{ InputMessageContent: &tdlib.InputMessageText{
Text: &tdlib.FormattedText{Text: tdlib.CommandArgument(msgText)}, Text: &tdlib.FormattedText{Text: tdlib.CommandArgument(msgText)},
}, },

View file

@ -17,23 +17,21 @@ func GetSenderId(sender tdlib.MessageSender) int64 {
} }
} }
func GetTdParameters() *tdlib.TdlibParameters { func GetTdParameters() *tdlib.SetTdlibParametersRequest {
return &tdlib.TdlibParameters{ return &tdlib.SetTdlibParametersRequest{
UseTestDc: false, UseTestDc: false,
DatabaseDirectory: "./tdlib-db", DatabaseDirectory: "./tdlib-db",
FilesDirectory: "./tdlib-files", FilesDirectory: "./tdlib-files",
UseFileDatabase: true, UseFileDatabase: true,
UseChatInfoDatabase: true, UseChatInfoDatabase: true,
UseMessageDatabase: true, UseMessageDatabase: true,
UseSecretChats: false, UseSecretChats: false,
ApiId: 132712, ApiId: 132712,
ApiHash: "e82c07ad653399a37baca8d1e498e472", ApiHash: "e82c07ad653399a37baca8d1e498e472",
SystemLanguageCode: "en", SystemLanguageCode: "en",
DeviceModel: "HuskyNG", DeviceModel: "HuskyNG",
SystemVersion: "3.0", SystemVersion: "3.0",
ApplicationVersion: "3.0", ApplicationVersion: "3.0",
EnableStorageOptimizer: true,
IgnoreFileNames: false,
} }
} }
@ -68,7 +66,7 @@ func main() {
log.Fatalf("GetMe error: %s", err) log.Fatalf("GetMe error: %s", err)
} }
log.Printf("%s connected", me.Username) log.Printf("%v connected", me.Usernames)
listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000) listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000)

BIN
example/media/Meru_01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 KiB

BIN
example/media/Meru_02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 KiB

View file

@ -17,23 +17,21 @@ func GetSenderId(sender tdlib.MessageSender) int64 {
} }
} }
func GetTdParameters() *tdlib.TdlibParameters { func GetTdParameters() *tdlib.SetTdlibParametersRequest {
return &tdlib.TdlibParameters{ return &tdlib.SetTdlibParametersRequest{
UseTestDc: false, UseTestDc: false,
DatabaseDirectory: "./tdlib-db", DatabaseDirectory: "./tdlib-db",
FilesDirectory: "./tdlib-files", FilesDirectory: "./tdlib-files",
UseFileDatabase: true, UseFileDatabase: true,
UseChatInfoDatabase: true, UseChatInfoDatabase: true,
UseMessageDatabase: true, UseMessageDatabase: true,
UseSecretChats: false, UseSecretChats: false,
ApiId: 132712, ApiId: 132712,
ApiHash: "e82c07ad653399a37baca8d1e498e472", ApiHash: "e82c07ad653399a37baca8d1e498e472",
SystemLanguageCode: "en", SystemLanguageCode: "en",
DeviceModel: "HuskyNG", DeviceModel: "HuskyNG",
SystemVersion: "3.0", SystemVersion: "3.0",
ApplicationVersion: "3.0", ApplicationVersion: "3.0",
EnableStorageOptimizer: true,
IgnoreFileNames: false,
} }
} }
@ -68,7 +66,7 @@ func main() {
log.Fatalf("GetMe error: %s", err) log.Fatalf("GetMe error: %s", err)
} }
log.Printf("%s connected", me.Username) log.Printf("%v connected", me.Usernames)
listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000) listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000)
@ -97,11 +95,13 @@ func main() {
ParseMode: &tdlib.TextParseModeHTML{}, ParseMode: &tdlib.TextParseModeHTML{},
}) })
m, err := client.SendMessage(&tdlib.SendMessageRequest{ m, err := client.SendMessage(&tdlib.SendMessageRequest{
ChatId: chatId, ChatId: chatId,
ReplyToMessageId: msgId, ReplyTo: &tdlib.InputMessageReplyToMessage{
MessageId: msgId,
},
InputMessageContent: &tdlib.InputMessagePhoto{ InputMessageContent: &tdlib.InputMessagePhoto{
Photo: &tdlib.InputFileLocal{ Photo: &tdlib.InputFileLocal{
Path: "./myht9-1486821485193084928.jpg", Path: "./Meru_01.png",
}, },
Caption: text, Caption: text,
}, },
@ -116,18 +116,20 @@ func main() {
ParseMode: &tdlib.TextParseModeHTML{}, ParseMode: &tdlib.TextParseModeHTML{},
}) })
m, err := client.SendMessageAlbum(&tdlib.SendMessageAlbumRequest{ m, err := client.SendMessageAlbum(&tdlib.SendMessageAlbumRequest{
ChatId: chatId, ChatId: chatId,
ReplyToMessageId: msgId, ReplyTo: &tdlib.InputMessageReplyToMessage{
MessageId: msgId,
},
InputMessageContents: []tdlib.InputMessageContent{ InputMessageContents: []tdlib.InputMessageContent{
&tdlib.InputMessagePhoto{ &tdlib.InputMessagePhoto{
Photo: &tdlib.InputFileLocal{ Photo: &tdlib.InputFileLocal{
Path: "./myht9-1486821485193084928.jpg", Path: "./Meru_01.png",
}, },
Caption: text, Caption: text,
}, },
&tdlib.InputMessagePhoto{ &tdlib.InputMessagePhoto{
Photo: &tdlib.InputFileLocal{ Photo: &tdlib.InputFileLocal{
Path: "./hisagi_02-1486983199280738309.jpg", Path: "./Meru_02.png",
}, },
}, },
}, },

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

View file

@ -9,23 +9,21 @@ import (
tdlib "github.com/c0re100/gotdlib/client" tdlib "github.com/c0re100/gotdlib/client"
) )
func GetTdParameters() *tdlib.TdlibParameters { func GetTdParameters() *tdlib.SetTdlibParametersRequest {
return &tdlib.TdlibParameters{ return &tdlib.SetTdlibParametersRequest{
UseTestDc: false, UseTestDc: false,
DatabaseDirectory: "./tdlib-db", DatabaseDirectory: "./tdlib-db",
FilesDirectory: "./tdlib-files", FilesDirectory: "./tdlib-files",
UseFileDatabase: true, UseFileDatabase: true,
UseChatInfoDatabase: true, UseChatInfoDatabase: true,
UseMessageDatabase: true, UseMessageDatabase: true,
UseSecretChats: false, UseSecretChats: false,
ApiId: 132712, ApiId: 132712,
ApiHash: "e82c07ad653399a37baca8d1e498e472", ApiHash: "e82c07ad653399a37baca8d1e498e472",
SystemLanguageCode: "en", SystemLanguageCode: "en",
DeviceModel: "HuskyNG", DeviceModel: "HuskyNG",
SystemVersion: "3.0", SystemVersion: "3.0",
ApplicationVersion: "3.0", ApplicationVersion: "3.0",
EnableStorageOptimizer: true,
IgnoreFileNames: false,
} }
} }
@ -65,7 +63,7 @@ func main() {
log.Fatalf("GetMe error: %s", err) log.Fatalf("GetMe error: %s", err)
} }
log.Printf("%s connected", me.Username) log.Printf("%v connected", me.Usernames)
listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000) listener := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, 1000)
@ -91,8 +89,10 @@ func main() {
ParseMode: &tdlib.TextParseModeHTML{}, ParseMode: &tdlib.TextParseModeHTML{},
}) })
m, err := client.SendMessage(&tdlib.SendMessageRequest{ m, err := client.SendMessage(&tdlib.SendMessageRequest{
ChatId: chatId, ChatId: chatId,
ReplyToMessageId: msgId, ReplyTo: &tdlib.InputMessageReplyToMessage{
MessageId: msgId,
},
InputMessageContent: &tdlib.InputMessageText{ InputMessageContent: &tdlib.InputMessageText{
Text: text, Text: text,
}, },

View file

@ -17,23 +17,21 @@ func GetSenderId(sender tdlib.MessageSender) int64 {
} }
} }
func GetTdParameters() *tdlib.TdlibParameters { func GetTdParameters() *tdlib.SetTdlibParametersRequest {
return &tdlib.TdlibParameters{ return &tdlib.SetTdlibParametersRequest{
UseTestDc: false, UseTestDc: false,
DatabaseDirectory: "./tdlib-db", DatabaseDirectory: "./tdlib-db",
FilesDirectory: "./tdlib-files", FilesDirectory: "./tdlib-files",
UseFileDatabase: true, UseFileDatabase: true,
UseChatInfoDatabase: true, UseChatInfoDatabase: true,
UseMessageDatabase: true, UseMessageDatabase: true,
UseSecretChats: false, UseSecretChats: false,
ApiId: 132712, ApiId: 132712,
ApiHash: "e82c07ad653399a37baca8d1e498e472", ApiHash: "e82c07ad653399a37baca8d1e498e472",
SystemLanguageCode: "en", SystemLanguageCode: "en",
DeviceModel: "HuskyNG", DeviceModel: "HuskyNG",
SystemVersion: "3.0", SystemVersion: "3.0",
ApplicationVersion: "3.0", ApplicationVersion: "3.0",
EnableStorageOptimizer: true,
IgnoreFileNames: false,
} }
} }
@ -68,7 +66,7 @@ func main() {
log.Fatalf("GetMe error: %s", err) log.Fatalf("GetMe error: %s", err)
} }
log.Printf("%s connected", me.Username) log.Printf("%v connected", me.Usernames)
listener := client.GetListener() listener := client.GetListener()

5
go.mod
View file

@ -2,4 +2,7 @@ module github.com/c0re100/gotdlib
go 1.16 go 1.16
require golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed require (
github.com/google/uuid v1.6.0
golang.org/x/crypto v0.31.0
)

72
go.sum
View file

@ -1,11 +1,69 @@
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed h1:YoWVYYAfvQ4ddHv3OKmIvX7NCAhFGTj62VP2l2kfBbA= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=