aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2023-11-08 03:10:49 +0300
committerGravatar Vitaly Takmazov2023-11-08 03:35:01 +0300
commitfe0ded45efa3930557c4f50b01c81b81e919b38a (patch)
treeced4d83ab229d1270fbfb9773620daf13e0c25a6 /src
parentdfad691d92d55d8b458665ca7b810d4fae2d3089 (diff)
Handle premium users from Patreon
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/juick/config/AppConfig.java9
-rw-r--r--src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java51
2 files changed, 59 insertions, 1 deletions
diff --git a/src/main/java/com/juick/config/AppConfig.java b/src/main/java/com/juick/config/AppConfig.java
index 32926bd1..2963ee27 100644
--- a/src/main/java/com/juick/config/AppConfig.java
+++ b/src/main/java/com/juick/config/AppConfig.java
@@ -28,6 +28,7 @@ import com.mitchellbosecke.pebble.extension.FormatterExtension;
import com.overzealous.remark.Options;
import com.overzealous.remark.Remark;
+import com.patreon.PatreonAPI;
import io.pebbletemplates.pebble.PebbleEngine;
import io.pebbletemplates.pebble.loader.ClasspathLoader;
import io.pebbletemplates.pebble.loader.Loader;
@@ -65,6 +66,8 @@ public class AppConfig {
private Resource keystore;
@Value("${keystore_password:secret}")
private String keystorePassword;
+ @Value("${patreon_creator_access_token:secret}")
+ private String creatorAccessToken;
@Bean
KeystoreManager keystoreManager() {
@@ -169,6 +172,12 @@ public class AppConfig {
}
@Bean
+ PatreonAPI patreonClient() {
+ return new PatreonAPI(creatorAccessToken);
+ }
+
+
+ @Bean
ViewResolver viewResolver() {
PebbleViewResolver viewResolver = new PebbleViewResolver(pebbleEngine());
viewResolver.setPrefix("templates");
diff --git a/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java b/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java
index c961dec9..2bdeb020 100644
--- a/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java
+++ b/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java
@@ -17,7 +17,12 @@
package com.juick.www.api.webhooks;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.jasminb.jsonapi.JSONAPIDocument;
+import com.juick.service.UserService;
import com.juick.util.HttpForbiddenException;
+import com.patreon.PatreonAPI;
+import com.patreon.resources.User;
import org.apache.commons.codec.digest.HmacUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
@@ -29,14 +34,25 @@ import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
+import javax.inject.Inject;
+import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.StreamSupport;
@RestController
public class PatreonWebhook {
private static final Logger logger = LoggerFactory.getLogger("Patreon");
@Value("${patreon_secret:}")
private String secretKey;
+ @Inject
+ private PatreonAPI patreonClient;
+ @Inject
+ private ObjectMapper jsonMapper;
+ @Inject
+ private UserService userService;
@PostMapping(value = "/api/_patreon")
@ResponseStatus(value = HttpStatus.OK)
@@ -50,6 +66,39 @@ public class PatreonWebhook {
if (!actualSignature.equals(signature)) {
throw new HttpForbiddenException();
}
- logger.info("Data: " + data);
+ var json = jsonMapper.readTree(data);
+ var updatedEmails = StreamSupport.stream(json.get("included").spliterator(), false)
+ .filter(node -> node.get("type").textValue().equals("user"))
+ .map(node -> node.get("attributes").get("email").textValue()).toList();
+ JSONAPIDocument<User> userResponse = patreonClient.fetchUser();
+ User creator = userResponse.get();
+ logger.info("Patreon user: {}", jsonMapper.writeValueAsString(creator));
+ var campainsResponse = patreonClient.fetchCampaigns();
+ List<String> activeEmails = new ArrayList<>();
+ campainsResponse.get().forEach(campaign -> {
+ try {
+ var pledgesResponse = patreonClient.fetchAllPledges(campaign.getId());
+ pledgesResponse.forEach(pledge -> {
+ logger.info("Pledge: {}, email: {}", pledge.getPatron().getFullName(), pledge.getPatron().getEmail());
+ activeEmails.add(pledge.getPatron().getEmail());
+ });
+ } catch (IOException e) {
+ logger.warn("Patreon exception: {}", e.getMessage());
+ }
+ });
+ activeEmails.forEach(email -> {
+ var user = userService.getUserByEmail(email);
+ if (!user.isAnonymous()) {
+ userService.setPremium(user.getUid(), true);
+ }
+ });
+ updatedEmails.stream().filter(email -> !activeEmails.contains(email))
+ .forEach(deleted -> {
+ var user = userService.getUserByEmail(deleted);
+ if (!user.isAnonymous()) {
+ logger.info("User is not a patron anymore: {}", deleted);
+ userService.setPremium(user.getUid(), false);
+ }
+ });
}
}