aboutsummaryrefslogtreecommitdiff
path: root/telegram/commands.go
diff options
context:
space:
mode:
Diffstat (limited to 'telegram/commands.go')
-rw-r--r--telegram/commands.go328
1 files changed, 212 insertions, 116 deletions
diff --git a/telegram/commands.go b/telegram/commands.go
index bd9f0f8..87fff72 100644
--- a/telegram/commands.go
+++ b/telegram/commands.go
@@ -15,11 +15,11 @@ import (
)
const notEnoughArguments string = "Not enough arguments"
-const telegramNotInitialized string = "Telegram connection is not initialized yet"
+const TelegramNotInitialized string = "Telegram connection is not initialized yet"
+const TelegramAuthDone string = "Authorization is done already"
const notOnline string = "Not online"
-var permissionsAdmin = client.ChatMemberStatusAdministrator{
- CanBeEdited: true,
+var permissionsAdmin = client.ChatAdministratorRights{
CanChangeInfo: true,
CanPostMessages: true,
CanEditMessages: true,
@@ -30,20 +30,27 @@ var permissionsAdmin = client.ChatMemberStatusAdministrator{
CanPromoteMembers: false,
}
var permissionsMember = client.ChatPermissions{
- CanSendMessages: true,
- CanSendMediaMessages: true,
+ CanSendBasicMessages: true,
+ CanSendAudios: true,
+ CanSendDocuments: true,
+ CanSendPhotos: true,
+ CanSendVideos: true,
+ CanSendVideoNotes: true,
+ CanSendVoiceNotes: true,
CanSendPolls: true,
CanSendOtherMessages: true,
CanAddWebPagePreviews: true,
CanChangeInfo: true,
CanInviteUsers: true,
CanPinMessages: true,
+ CanManageTopics: true,
}
var permissionsReadonly = client.ChatPermissions{}
var transportCommands = map[string]command{
"login": command{"phone", "sign in"},
"logout": command{"", "sign out"},
+ "cancelauth": command{"", "quit the signin wizard"},
"code": command{"", "check one-time code"},
"password": command{"", "check 2fa password"},
"setusername": command{"", "update @username"},
@@ -52,6 +59,10 @@ var transportCommands = map[string]command{
"setpassword": command{"[old] [new]", "set or remove password"},
"config": command{"[param] [value]", "view or update configuration options"},
"report": command{"[chat] [comment]", "report a chat by id or @username"},
+ "add": command{"@username", "add @username to your chat list"},
+ "join": command{"https://t.me/invite_link", "join to chat via invite link or @publicname"},
+ "supergroup": command{"title description", "create new supergroup «title» with «description»"},
+ "channel": command{"title description", "create new channel «title» with «description»"},
}
var chatCommands = map[string]command{
@@ -60,6 +71,7 @@ var chatCommands = map[string]command{
"silent": command{"message", "send a message without sound"},
"schedule": command{"{online | 2006-01-02T15:04:05 | 15:04:05} message", "schedules a message either to timestamp or to whenever the user goes online"},
"forward": command{"message_id target_chat", "forwards a message"},
+ "vcard": command{"", "print vCard as text"},
"add": command{"@username", "add @username to your chat list"},
"join": command{"https://t.me/invite_link", "join to chat via invite link or @publicname"},
"group": command{"title", "create groupchat «title» with current user"},
@@ -168,6 +180,10 @@ func rawCmdArguments(cmdline string, start uint8) string {
return ""
}
+func keyValueString(key, value string) string {
+ return fmt.Sprintf("%s: %s", key, value)
+}
+
func (c *Client) unsubscribe(chatID int64) error {
return gateway.SendPresence(
c.xmpp,
@@ -179,11 +195,17 @@ func (c *Client) unsubscribe(chatID int64) error {
func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message) {
for i := len(messages) - 1; i >= 0; i-- {
+ message := messages[i]
+ reply, _ := c.getMessageReply(message)
+
gateway.SendMessage(
c.jid,
strconv.FormatInt(chatID, 10),
- c.formatMessage(0, 0, false, messages[i]),
+ c.formatMessage(0, 0, false, message),
+ strconv.FormatInt(message.Id, 10),
c.xmpp,
+ reply,
+ false,
)
}
}
@@ -215,7 +237,7 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
switch cmd {
case "login", "code", "password":
if cmd == "login" && c.Session.Login != "" {
- return ""
+ return "Phone number already provided, use /cancelauth to start over"
}
if len(args) < 1 {
@@ -223,36 +245,35 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
}
if cmd == "login" {
- wasSessionLoginEmpty := c.Session.Login == ""
- c.Session.Login = args[0]
-
- if wasSessionLoginEmpty && c.authorizer == nil {
- go func() {
- err := c.Connect(resource)
- if err != nil {
- log.Error(errors.Wrap(err, "TDlib connection failure"))
- }
- }()
- // a quirk for authorizer to become ready. If it's still not,
- // nothing bad: the command just needs to be resent again
- time.Sleep(1e5)
+ err := c.TryLogin(resource, args[0])
+ if err != nil {
+ return err.Error()
}
- }
- if c.authorizer == nil {
- return telegramNotInitialized
- }
+ c.locks.authorizerWriteLock.Lock()
+ defer c.locks.authorizerWriteLock.Unlock()
- switch cmd {
- // sign in
- case "login":
c.authorizer.PhoneNumber <- args[0]
- // check auth code
- case "code":
- c.authorizer.Code <- args[0]
- // check auth password
- case "password":
- c.authorizer.Password <- args[0]
+ } else {
+ c.locks.authorizerWriteLock.Lock()
+ defer c.locks.authorizerWriteLock.Unlock()
+
+ if c.authorizer == nil {
+ return TelegramNotInitialized
+ }
+
+ if c.authorizer.isClosed {
+ return TelegramAuthDone
+ }
+
+ switch cmd {
+ // check auth code
+ case "code":
+ c.authorizer.Code <- args[0]
+ // check auth password
+ case "password":
+ c.authorizer.Password <- args[0]
+ }
}
// sign out
case "logout":
@@ -271,6 +292,13 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
}
c.Session.Login = ""
+ // cancel auth
+ case "cancelauth":
+ if c.Online() {
+ return "Not allowed when online, use /logout instead"
+ }
+ c.cancelAuth()
+ return "Cancelled"
// set @username
case "setusername":
if !c.Online() {
@@ -290,25 +318,36 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
}
// set My Name
case "setname":
- if !c.Online() {
- return notOnline
- }
-
var firstname string
var lastname string
if len(args) > 0 {
firstname = args[0]
}
+ if firstname == "" {
+ return "The name should contain at least one character"
+ }
if len(args) > 1 {
- lastname = args[1]
+ lastname = rawCmdArguments(cmdline, 1)
}
- _, err := c.client.SetName(&client.SetNameRequest{
- FirstName: firstname,
- LastName: lastname,
- })
- if err != nil {
- return errors.Wrap(err, "Couldn't set name").Error()
+ c.locks.authorizerWriteLock.Lock()
+ if c.authorizer != nil && !c.authorizer.isClosed {
+ c.authorizer.FirstName <- firstname
+ c.authorizer.LastName <- lastname
+ c.locks.authorizerWriteLock.Unlock()
+ } else {
+ c.locks.authorizerWriteLock.Unlock()
+ if !c.Online() {
+ return notOnline
+ }
+
+ _, err := c.client.SetName(&client.SetNameRequest{
+ FirstName: firstname,
+ LastName: lastname,
+ })
+ if err != nil {
+ return errors.Wrap(err, "Couldn't set name").Error()
+ }
}
// set About
case "setbio":
@@ -344,6 +383,10 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
}
case "config":
if len(args) > 1 {
+ if gateway.MessageOutgoingPermissionVersion == 0 && args[0] == "carbons" && args[1] == "true" {
+ return "The server did not allow to enable carbons"
+ }
+
value, err := c.Session.Set(args[0], args[1])
if err != nil {
return err.Error()
@@ -387,6 +430,14 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
} else {
return "Reported"
}
+ case "add":
+ return c.cmdAdd(args)
+ case "join":
+ return c.cmdJoin(args)
+ case "supergroup":
+ return c.cmdSupergroup(args, cmdline)
+ case "channel":
+ return c.cmdChannel(args, cmdline)
case "help":
return helpString(helpTypeTransport)
}
@@ -463,14 +514,17 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
return "Last message is empty", true
}
- content := c.ProcessOutgoingMessage(0, rawCmdArguments(cmdline, 0), "")
+ content := c.PrepareOutgoingMessageContent(rawCmdArguments(cmdline, 0))
if content != nil {
- c.client.EditMessageText(&client.EditMessageTextRequest{
+ _, err = c.client.EditMessageText(&client.EditMessageTextRequest{
ChatId: chatID,
MessageId: message.Id,
InputMessageContent: content,
})
+ if err != nil {
+ return "Message editing error", true
+ }
} else {
return "Message processing error", true
}
@@ -480,7 +534,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
return "Not enough arguments", true
}
- content := c.ProcessOutgoingMessage(0, rawCmdArguments(cmdline, 0), "")
+ content := c.PrepareOutgoingMessageContent(rawCmdArguments(cmdline, 0))
if content != nil {
_, err := c.client.SendMessage(&client.SendMessageRequest{
@@ -559,7 +613,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
}
}
- content := c.ProcessOutgoingMessage(0, rawCmdArguments(cmdline, 1), "")
+ content := c.PrepareOutgoingMessageContent(rawCmdArguments(cmdline, 1))
if content != nil {
_, err := c.client.SendMessage(&client.SendMessageRequest{
@@ -606,80 +660,33 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
c.ProcessIncomingMessage(targetChatId, message)
}
}
- // add @contact
- case "add":
- if len(args) < 1 {
- return notEnoughArguments, true
- }
-
- chat, err := c.client.SearchPublicChat(&client.SearchPublicChatRequest{
- Username: args[0],
- })
+ // print vCard
+ case "vcard":
+ info, err := c.GetVcardInfo(chatID)
if err != nil {
return err.Error(), true
}
- if chat == nil {
- return "No error, but chat is nil", true
+ _, link := c.PermastoreFile(info.Photo, true)
+ entries := []string{
+ keyValueString("Chat title", info.Fn),
+ keyValueString("Photo", link),
+ keyValueString("Usernames", c.usernamesToString(info.Nicknames)),
+ keyValueString("Full name", info.Given+" "+info.Family),
+ keyValueString("Phone number", info.Tel),
}
-
- c.subscribeToID(chat.Id, chat)
+ return strings.Join(entries, "\n"), true
+ // add @contact
+ case "add":
+ return c.cmdAdd(args), true
// join https://t.me/publichat or @publicchat
case "join":
- if len(args) < 1 {
- return notEnoughArguments, true
- }
-
- if strings.HasPrefix(args[0], "@") {
- chat, err := c.client.SearchPublicChat(&client.SearchPublicChatRequest{
- Username: args[0],
- })
- if err != nil {
- return err.Error(), true
- }
- if chat == nil {
- return "No error, but chat is nil", true
- }
- _, err = c.client.JoinChat(&client.JoinChatRequest{
- ChatId: chat.Id,
- })
- if err != nil {
- return err.Error(), true
- }
- } else {
- _, err := c.client.JoinChatByInviteLink(&client.JoinChatByInviteLinkRequest{
- InviteLink: args[0],
- })
- if err != nil {
- return err.Error(), true
- }
- }
+ return c.cmdJoin(args), true
// create new supergroup
case "supergroup":
- if len(args) < 1 {
- return notEnoughArguments, true
- }
-
- _, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
- Title: args[0],
- Description: rawCmdArguments(cmdline, 1),
- })
- if err != nil {
- return err.Error(), true
- }
+ return c.cmdSupergroup(args, cmdline), true
// create new channel
case "channel":
- if len(args) < 1 {
- return notEnoughArguments, true
- }
-
- _, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
- Title: args[0],
- Description: rawCmdArguments(cmdline, 1),
- IsChannel: true,
- })
- if err != nil {
- return err.Error(), true
- }
+ return c.cmdChannel(args, cmdline), true
// create new secret chat with current user
case "secret":
_, err := c.client.CreateNewSecretChat(&client.CreateNewSecretChatRequest{
@@ -880,7 +887,10 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
}
// clone the permissions
- status := permissionsAdmin
+ status := client.ChatMemberStatusAdministrator{
+ CanBeEdited: true,
+ Rights: &permissionsAdmin,
+ }
if len(args) > 1 {
status.CustomTitle = args[1]
@@ -930,9 +940,9 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
return "Invalid TTL", true
}
}
- _, err = c.client.SetChatMessageTtl(&client.SetChatMessageTtlRequest{
- ChatId: chatID,
- Ttl: int32(ttl),
+ _, err = c.client.SetChatMessageAutoDeleteTime(&client.SetChatMessageAutoDeleteTimeRequest{
+ ChatId: chatID,
+ MessageAutoDeleteTime: int32(ttl),
})
if err != nil {
@@ -1076,3 +1086,89 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
return "", true
}
+
+func (c *Client) cmdAdd(args []string) string {
+ if len(args) < 1 {
+ return notEnoughArguments
+ }
+
+ chat, err := c.client.SearchPublicChat(&client.SearchPublicChatRequest{
+ Username: args[0],
+ })
+ if err != nil {
+ return err.Error()
+ }
+ if chat == nil {
+ return "No error, but chat is nil"
+ }
+
+ c.subscribeToID(chat.Id, chat)
+
+ return ""
+}
+
+func (c *Client) cmdJoin(args []string) string {
+ if len(args) < 1 {
+ return notEnoughArguments
+ }
+
+ if strings.HasPrefix(args[0], "@") {
+ chat, err := c.client.SearchPublicChat(&client.SearchPublicChatRequest{
+ Username: args[0],
+ })
+ if err != nil {
+ return err.Error()
+ }
+ if chat == nil {
+ return "No error, but chat is nil"
+ }
+ _, err = c.client.JoinChat(&client.JoinChatRequest{
+ ChatId: chat.Id,
+ })
+ if err != nil {
+ return err.Error()
+ }
+ } else {
+ _, err := c.client.JoinChatByInviteLink(&client.JoinChatByInviteLinkRequest{
+ InviteLink: args[0],
+ })
+ if err != nil {
+ return err.Error()
+ }
+ }
+
+ return ""
+}
+
+func (c *Client) cmdSupergroup(args []string, cmdline string) string {
+ if len(args) < 1 {
+ return notEnoughArguments
+ }
+
+ _, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
+ Title: args[0],
+ Description: rawCmdArguments(cmdline, 1),
+ })
+ if err != nil {
+ return err.Error()
+ }
+
+ return ""
+}
+
+func (c *Client) cmdChannel(args []string, cmdline string) string {
+ if len(args) < 1 {
+ return notEnoughArguments
+ }
+
+ _, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
+ Title: args[0],
+ Description: rawCmdArguments(cmdline, 1),
+ IsChannel: true,
+ })
+ if err != nil {
+ return err.Error()
+ }
+
+ return ""
+}