Skip to content

Commit

Permalink
Merge pull request #758 from rubenlagus/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
rubenlagus authored Jun 4, 2020
2 parents 6ecc2af + 72b239e commit 1a2e7c9
Show file tree
Hide file tree
Showing 32 changed files with 439 additions and 2,167 deletions.
7 changes: 3 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,11 @@ hs_err_pid*
.idea/
copyright/
*.iml
*.ipr
*.iws
.classpath
.project
.settings/

#File System specific files
.DS_STORE

# Default ignored files
/Bots.iws
.DS_Store
2,104 changes: 0 additions & 2,104 deletions Bots.ipr

This file was deleted.

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ Just import add the library to your project with one of these options:
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.8.1</version>
<version>4.9</version>
</dependency>
```

```gradle
compile "org.telegram:telegrambots:4.8.1"
compile "org.telegram:telegrambots:4.9"
```

2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/4.8.1)
3. Download the jar(including all dependencies) from [here](https://mvnrepository.com/artifact/org.telegram/telegrambots/4.8.1)
2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/4.9)
3. Download the jar(including all dependencies) from [here](https://mvnrepository.com/artifact/org.telegram/telegrambots/4.9)

In order to use Long Polling mode, just create your own bot extending `org.telegram.telegrambots.bots.TelegramLongPollingBot`.

Expand Down
4 changes: 4 additions & 0 deletions TelegramBots.wiki/Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
### <a id="4.9"></a>4.9 ###
1. Update Api version [4.9](https://core.telegram.org/bots/api-changelog#june-4-2020)
2. Bug fixing: #731, #749, #752 and #753

### <a id="4.8.1"></a>4.8.1 ###
1. Update Api version [4.8](https://core.telegram.org/bots/api-changelog#april-24-2020)
2. Add stats for Abilities
Expand Down
4 changes: 2 additions & 2 deletions TelegramBots.wiki/Getting-Started.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ First you need ot get the library and add it to your project. There are few poss
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.8.1</version>
<version>4.9</version>
</dependency>
```
* With **Gradle**:

```groovy
compile group: 'org.telegram', name: 'telegrambots', version: '4.8.1'
compile group: 'org.telegram', name: 'telegrambots', version: '4.9'
```

2. Don't like **Maven Central Repository**? It can also be taken from [Jitpack](https://jitpack.io/#rubenlagus/TelegramBots).
Expand Down
5 changes: 4 additions & 1 deletion TelegramBots.wiki/abilities/Advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@ As an example, if you want to restrict the updates to photos only, then you may
public boolean checkGlobalFlags(Update update) {
return Flag.PHOTO;
}
```
```

## Statistics
AbilityBot can accrue basic statistics about the usage of your abilities and replies. Simply `enableStats()` on an Ability builder or `enableStats(<name>)` on replies to activate this feature. Once activated, you may call `/stats` and the bot will print a basic list of statistics. At the moment, AbilityBot only tracks hits. In the future, this will be enhanced to track more stats.
4 changes: 2 additions & 2 deletions TelegramBots.wiki/abilities/Simple-Example.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ As with any Java project, you will need to set your dependencies.
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-abilities</artifactId>
<version>4.8.1</version>
<version>4.9</version>
</dependency>
```
* **Gradle**
```groovy
implementation group: 'org.telegram', name: 'telegrambots-abilities', version: '4.8.1'
implementation group: 'org.telegram', name: 'telegrambots-abilities', version: '4.9'
```
* [JitPack](https://jitpack.io/#rubenlagus/TelegramBots)

Expand Down
19 changes: 9 additions & 10 deletions TelegramBots.wiki/abilities/State-Machines.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,30 +70,29 @@ Now, after your naughty bot retaliates, the user can say "go left or else" to fo

## Complete Example
```java
public static class ReplyFlowBot extends AbilityBot {
public class ReplyFlowBot extends AbilityBot {
public class ReplyFlowBot extends AbilityBot {
public ReplyFlowBot(String botToken, String botUsername) {
super(botToken, botUsername);
super(botToken, botUsername);
}

@Override
public int creatorId() {
return <YOUR ID HERE>;
return <YOUR ID HERE>;
}

public ReplyFlow directionFlow() {
Reply saidLeft = Reply.of(upd -> silent.send("Sir, I have gone left.", getChatId(upd)),
Reply saidLeft = Reply.of(upd -> silent.send("Sir, I have gone left.", getChatId(upd)),
hasMessageWith("go left or else"));

ReplyFlow leftflow = ReplyFlow.builder(db)
ReplyFlow leftflow = ReplyFlow.builder(db)
.action(upd -> silent.send("I don't know how to go left.", getChatId(upd)))
.onlyIf(hasMessageWith("left"))
.next(saidLeft).build();

Reply saidRight = Reply.of(upd -> silent.send("Sir, I have gone right.", getChatId(upd)),
Reply saidRight = Reply.of(upd -> silent.send("Sir, I have gone right.", getChatId(upd)),
hasMessageWith("right"));

return ReplyFlow.builder(db)
return ReplyFlow.builder(db)
.action(upd -> silent.send("Command me to go left or right!", getChatId(upd)))
.onlyIf(hasMessageWith("wake up"))
.next(leftflow)
Expand All @@ -103,9 +102,9 @@ public static class ReplyFlowBot extends AbilityBot {

@NotNull
private Predicate<Update> hasMessageWith(String msg) {
return upd -> upd.getMessage().getText().equalsIgnoreCase(msg);
return upd -> upd.getMessage().getText().equalsIgnoreCase(msg);
}
}
}
```
## Inline Declaration
As you can see in the above example, we used a bottom-up approach. We declared the leaf replies before we got to the root reply flow.
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>org.telegram</groupId>
<artifactId>Bots</artifactId>
<packaging>pom</packaging>
<version>4.8.1</version>
<version>4.9</version>

<modules>
<module>telegrambots</module>
Expand Down
8 changes: 4 additions & 4 deletions telegrambots-abilities/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ Usage
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-abilities</artifactId>
<version>4.8.1</version>
<version>4.9</version>
</dependency>
```

**Gradle**

```gradle
compile "org.telegram:telegrambots-abilities:4.8.1"
compile "org.telegram:telegrambots-abilities:4.9"
```

**JitPack** - [JitPack](https://jitpack.io/#rubenlagus/TelegramBots/v4.8.1)
**JitPack** - [JitPack](https://jitpack.io/#rubenlagus/TelegramBots/v4.9)

**Plain imports** - [Here](https://github.com/rubenlagus/TelegramBots/releases/tag/v4.8.1)
**Plain imports** - [Here](https://github.com/rubenlagus/TelegramBots/releases/tag/v4.9)

Motivation
----------
Expand Down
4 changes: 2 additions & 2 deletions telegrambots-abilities/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.telegram</groupId>
<artifactId>Bots</artifactId>
<version>4.8.1</version>
<version>4.9</version>
</parent>

<artifactId>telegrambots-abilities</artifactId>
Expand Down Expand Up @@ -84,7 +84,7 @@
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.8.1</version>
<version>4.9</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.telegram.abilitybots.api.bot;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.*;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -33,15 +33,18 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.google.common.collect.Sets.difference;
import static java.lang.String.format;
import static java.time.ZonedDateTime.now;
import static java.util.Arrays.stream;
import static java.util.Optional.ofNullable;
import static java.util.regex.Pattern.CASE_INSENSITIVE;
import static java.util.regex.Pattern.compile;
import static java.util.stream.Collectors.toSet;
import static org.telegram.abilitybots.api.objects.Locality.*;
import static org.telegram.abilitybots.api.objects.MessageContext.newContext;
import static org.telegram.abilitybots.api.objects.Privacy.*;
import static org.telegram.abilitybots.api.objects.Stats.createStats;
import static org.telegram.abilitybots.api.util.AbilityMessageCodes.*;
import static org.telegram.abilitybots.api.util.AbilityUtils.*;

Expand Down Expand Up @@ -87,6 +90,7 @@ public abstract class BaseAbilityBot extends DefaultAbsSender implements Ability
public static final String USERS = "USERS";
public static final String USER_ID = "USER_ID";
public static final String BLACKLIST = "BLACKLIST";
public static final String STATS = "ABILITYBOT_STATS";

// DB and sender
protected final DBContext db;
Expand All @@ -102,6 +106,7 @@ public abstract class BaseAbilityBot extends DefaultAbsSender implements Ability

// Ability registry
private Map<String, Ability> abilities;
private Map<String, Stats> stats;

// Reply registry
private List<Reply> replies;
Expand All @@ -119,6 +124,7 @@ protected BaseAbilityBot(String botToken, String botUsername, DBContext db, Abil
silent = new SilentSender(sender);

registerAbilities();
initStats();
}

/**
Expand Down Expand Up @@ -149,6 +155,13 @@ protected Set<Integer> admins() {
return db.getSet(ADMINS);
}

/**
* @return a mapping of ability and reply names to their corresponding statistics
*/
protected Map<String, Stats> stats() {
return stats;
}

/**
* @return the immutable map of <String,Ability>
*/
Expand All @@ -163,6 +176,7 @@ public List<Reply> replies() {
return replies;
}


/**
* This method contains the stream of actions that are applied on any update.
* <p>
Expand All @@ -180,6 +194,7 @@ public void onUpdateReceived(Update update) {
.filter(this::checkBlacklist)
.map(this::addUser)
.filter(this::filterReply)
.filter(this::hasUser)
.map(this::getAbility)
.filter(this::validateAbility)
.filter(this::checkPrivacy)
Expand All @@ -188,6 +203,7 @@ public void onUpdateReceived(Update update) {
.filter(this::checkMessageFlags)
.map(this::getContext)
.map(this::consumeUpdate)
.map(this::updateStats)
.forEach(this::postConsumption);

// Commit to DB now after all the actions have been dealt
Expand Down Expand Up @@ -275,6 +291,19 @@ private void registerAbilities() {
}
}

private void initStats() {
Set<String> enabledStats = Stream.concat(
replies.stream().filter(Reply::statsEnabled).map(Reply::name),
abilities.entrySet().stream()
.filter(entry -> entry.getValue().statsEnabled())
.map(Map.Entry::getKey)).collect(toSet());
stats = db.getMap(STATS);
Set<String> toBeRemoved = difference(stats.keySet(), enabledStats);
toBeRemoved.forEach(stats::remove);
enabledStats.forEach(abName -> stats.computeIfAbsent(abName,
name -> createStats(abName, 0)));
}

/**
* @param clazz the type to be tested
* @return a predicate testing the return type of the method corresponding to the class parameter
Expand Down Expand Up @@ -344,6 +373,26 @@ Pair<MessageContext, Ability> consumeUpdate(Pair<MessageContext, Ability> pair)
return pair;
}

Pair<MessageContext, Ability> updateStats(Pair<MessageContext, Ability> pair) {
Ability ab = pair.b();
if (ab.statsEnabled()) {
updateStats(pair.b().name());
}
return pair;
}

private void updateReplyStats(Reply reply) {
if (reply.statsEnabled()) {
updateStats(reply.name());
}
}

void updateStats(String name) {
Stats statsObj = stats.get(name);
statsObj.hit();
stats.put(name, statsObj);
}

Pair<MessageContext, Ability> getContext(Trio<Update, Ability, String[]> trio) {
Update update = trio.a();
User user = AbilityUtils.getUser(update);
Expand Down Expand Up @@ -487,6 +536,12 @@ Update addUser(Update update) {
return update;
}

private boolean hasUser(Update update) {
// Valid updates without users should return an empty user
// Updates that are not recognized by the getUser method will throw an exception
return !AbilityUtils.getUser(update).equals(EMPTY_USER);
}

private void updateUserId(User oldUser, User newUser) {
if (oldUser != null && oldUser.getUserName() != null) {
// Remove old username -> ID
Expand All @@ -504,6 +559,7 @@ boolean filterReply(Update update) {
.filter(reply -> reply.isOkFor(update))
.map(reply -> {
reply.actOn(update);
updateReplyStats(reply);
return false;
})
.reduce(true, Boolean::logicalAnd);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;

import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.MultimapBuilder.hashKeys;
Expand Down Expand Up @@ -76,6 +77,7 @@ public final class DefaultAbilities implements AbilityExtension {
public static final String RECOVER = "recover";
public static final String COMMANDS = "commands";
public static final String REPORT = "report";
public static final String STATS = "stats";
private static final Logger log = LoggerFactory.getLogger(DefaultAbilities.class);
private final BaseAbilityBot bot;

Expand Down Expand Up @@ -179,6 +181,26 @@ public Ability commands() {
.build();
}

/**
* @return the ability to report statistics for abilities and replies.
*/
public Ability reportStats() {
return builder()
.name(STATS)
.locality(ALL)
.privacy(ADMIN)
.input(0)
.action(ctx -> {
String stats = bot.stats().entrySet().stream()
.map(entry -> String.format("%s: %d", entry.getKey(), entry.getValue().hits()))
.reduce(new StringJoiner("\n"), StringJoiner::add, StringJoiner::merge)
.toString();

bot.silent.send(stats, ctx.chatId());
})
.build();
}

/**
* This backup ability returns the object defined by {@link DBContext#backup()} as a message document.
* <p>
Expand Down Expand Up @@ -212,6 +234,7 @@ public Ability backupDB() {
.build();
}


/**
* Recovers the bot database using {@link DBContext#recover(Object)}.
* <p>
Expand Down
Loading

0 comments on commit 1a2e7c9

Please sign in to comment.