Passed
Push — master ( 030734...e07ad4 )
by Roannel Fernández
03:03
created

reservedCommands(String,Update)   A

Complexity

Conditions 3

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 12
dl 0
loc 18
rs 9.8
c 1
b 0
f 0
cc 3
1
package com.github.netkorp.telegram.framework.bots;
2
3
import com.github.netkorp.telegram.framework.commands.interfaces.Command;
4
import com.github.netkorp.telegram.framework.commands.interfaces.MultistageCommand;
5
import com.github.netkorp.telegram.framework.exceptions.CommandNotActive;
6
import com.github.netkorp.telegram.framework.exceptions.CommandNotFound;
7
import com.github.netkorp.telegram.framework.managers.CommandManager;
8
import com.github.netkorp.telegram.framework.managers.SecurityManager;
9
import org.slf4j.Logger;
10
import org.slf4j.LoggerFactory;
11
import org.springframework.beans.factory.annotation.Autowired;
12
import org.springframework.beans.factory.annotation.Value;
13
import org.springframework.stereotype.Component;
14
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
15
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
16
import org.telegram.telegrambots.meta.api.objects.Update;
17
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
18
19
import java.lang.invoke.MethodHandles;
20
import java.util.Optional;
21
22
@Component
23
public class PollingTelegramBot extends TelegramLongPollingBot {
24
25
    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
26
27
    private String botUsername;
28
    private String botToken;
29
30
    private final SecurityManager securityManager;
31
    private CommandManager commandManager;
32
33
    @Autowired
34
    public PollingTelegramBot(@Value("${telegram.bots.username}") String botUsername,
35
                              @Value("${telegram.bots.token}") String botToken,
36
                              SecurityManager securityManager) {
37
        this.botUsername = botUsername;
38
        this.botToken = botToken;
39
        this.securityManager = securityManager;
40
    }
41
42
    @Autowired
43
    public void setCommandManager(CommandManager commandManager) {
44
        this.commandManager = commandManager;
45
    }
46
47
    /**
48
     * This method is called when receiving updates via GetUpdates method
49
     *
50
     * @param update Update received
51
     */
52
    @Override
53
    public void onUpdateReceived(Update update) {
54
        // We check if the update has a message and the message has text
55
        if (update.hasMessage()) {
56
            Long idChat = update.getMessage().getChatId();
57
58
            try {
59
                // Checking if this is a commands
60
                if (update.getMessage().hasText()) {
61
                    String command = update.getMessage().getText().toLowerCase();
62
63
                    // Checking if it's a free command
64
                    try {
65
                        commandManager.getFreeCommand(command).execute(update);
66
                        return;
67
                    } catch (CommandNotFound commandNotFound) {
68
                        // Do nothing
69
                    }
70
                }
71
72
                // Checking if the chat is authorized
73
                if (securityManager.isAuthorized(idChat)) {
74
                    processMessage(update);
75
                }
76
            } catch (CommandNotFound commandNotFound) {
77
                sendMessage(commandNotFound.getMessage(), idChat);
78
                commandManager.getHelpCommand().ifPresent(command -> command.execute(update));
79
            }
80
        }
81
    }
82
83
    /**
84
     * Return bot username of this bot
85
     */
86
    @Override
87
    public String getBotUsername() {
88
        return botUsername;
89
    }
90
91
    /**
92
     * Returns the token of the bot to be able to perform Telegram Api Requests
93
     *
94
     * @return Token of the bot
95
     */
96
    @Override
97
    public String getBotToken() {
98
        return botToken;
99
    }
100
101
    /**
102
     * Process a given message.
103
     *
104
     * @param update The message sent by the user.
105
     */
106
    private void processMessage(Update update) throws CommandNotFound {
107
        final Long idChat = update.getMessage().getChatId();
108
109
        // Perhaps is a commands
110
        if (update.getMessage().hasText()) {
111
            String commandText = update.getMessage().getText().toLowerCase();
112
113
            if (reservedCommands(commandText, update)) {
114
                return;
115
            }
116
117
            // Trying to get commands
118
            try {
119
                Command command = commandManager.getCommand(commandText);
120
121
                // If there is no active commands defined, we understand this is an attempt to define/execute one
122
                if (!commandManager.hasActiveCommand(idChat)) {
123
124
                    if (command instanceof MultistageCommand) {
125
                        if (((MultistageCommand) command).init(update)) {
126
                            commandManager.setActiveCommand(idChat, ((MultistageCommand) command));
127
                        }
128
                    } else {
129
                        command.execute(update);
130
                    }
131
132
                    return;
133
                }
134
            } catch (CommandNotFound commandNotFound) {
135
                // Perhaps we're talking about data here. If there is an active commands, we leave it to it.
136
                if (!commandManager.hasActiveCommand(idChat)) {
137
                    throw commandNotFound;
138
                }
139
            }
140
        }
141
142
        // If there is a commands active, we handle the messages as data
143
        try {
144
            commandManager.getActiveCommand(idChat).execute(update);
145
        } catch (CommandNotActive commandNotActive) {
146
            sendMessage(commandNotActive.getMessage(), idChat);
147
        }
148
    }
149
150
    /**
151
     * Checks if the entered text matches with some reserved command.
152
     *
153
     * @param commandText Text entered by the user.
154
     * @param update      The message sent by the user.
155
     * @return If some reserved command was executed or not.
156
     */
157
    private boolean reservedCommands(String commandText, Update update) {
158
        Optional<Command> closeCommand = commandManager.getCloseCommand()
159
                .filter(command -> command.command().equals(commandText));
160
161
        if (closeCommand.isPresent()) {
162
            closeCommand.get().execute(update);
163
            return true;
164
        }
165
166
        Optional<Command> doneCommand = commandManager.getDoneCommand()
167
                .filter(command -> command.command().equals(commandText));
168
169
        if (doneCommand.isPresent()) {
170
            doneCommand.get().execute(update);
171
            return true;
172
        }
173
174
        return false;
175
    }
176
177
    /**
178
     * @param content Message content.
179
     * @param idChat  Chat's ID.
180
     */
181
    public void sendMessage(String content, Long idChat) {
182
        sendMessage(content, idChat, false);
183
    }
184
185
    /**
186
     * @param content Message content.
187
     * @param idChat  Chat's ID.
188
     * @param html    If HTML format is enabled or not.
189
     */
190
    public void sendMessage(String content, Long idChat, boolean html) {
191
        SendMessage message = new SendMessage() // Create a SendMessage object with mandatory fields
192
                .setChatId(idChat).setText(content).enableHtml(html);
193
194
        try {
195
            this.execute(message); // Call method to send the message
196
        } catch (TelegramApiException e) {
197
            LOG.error(e.getMessage(), e);
198
        }
199
    }
200
}
201