From fe0ded45efa3930557c4f50b01c81b81e919b38a Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 8 Nov 2023 03:10:49 +0300 Subject: Handle premium users from Patreon --- src/main/java/com/juick/config/AppConfig.java | 9 ++++ .../com/juick/www/api/webhooks/PatreonWebhook.java | 51 +++++++++++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) (limited to 'src') 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() { @@ -168,6 +171,12 @@ public class AppConfig { return new TopManager(); } + @Bean + PatreonAPI patreonClient() { + return new PatreonAPI(creatorAccessToken); + } + + @Bean ViewResolver viewResolver() { PebbleViewResolver viewResolver = new PebbleViewResolver(pebbleEngine()); 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 userResponse = patreonClient.fetchUser(); + User creator = userResponse.get(); + logger.info("Patreon user: {}", jsonMapper.writeValueAsString(creator)); + var campainsResponse = patreonClient.fetchCampaigns(); + List 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); + } + }); } } -- cgit v1.2.3