aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2018-10-05 01:38:04 +0300
committerGravatar Vitaly Takmazov2018-10-05 01:38:04 +0300
commitfe761771ce3cb65b00dc3a826c51b9f20ff6c72d (patch)
tree7671e1bd31dfc10f10d1110048efc313762c6dfe
parenta6824b011325df07caf284352f09c2b9f76155c7 (diff)
TopEvent: Announce in Fediverse, like in XMPP/Telegram
-rw-r--r--juick-common/src/main/java/com/juick/service/component/NotificationListener.java3
-rw-r--r--juick-common/src/main/java/com/juick/service/component/TopEvent.java21
-rw-r--r--juick-notifications/src/main/java/com/juick/components/APNSManager.java24
-rw-r--r--juick-notifications/src/main/java/com/juick/components/FirebaseManager.java5
-rw-r--r--juick-notifications/src/main/java/com/juick/components/MPNSManager.java5
-rw-r--r--juick-server/src/main/java/com/juick/server/ActivityPubManager.java38
-rw-r--r--juick-server/src/main/java/com/juick/server/EmailManager.java5
-rw-r--r--juick-server/src/main/java/com/juick/server/MessengerManager.java18
-rw-r--r--juick-server/src/main/java/com/juick/server/ServerManager.java5
-rw-r--r--juick-server/src/main/java/com/juick/server/TelegramBotManager.java12
-rw-r--r--juick-server/src/main/java/com/juick/server/TopManager.java28
-rw-r--r--juick-server/src/main/java/com/juick/server/TwitterManager.java22
-rw-r--r--juick-server/src/main/java/com/juick/server/XMPPConnection.java15
-rw-r--r--juick-server/src/main/java/com/juick/server/api/activity/model/Context.java1
-rw-r--r--juick-server/src/main/java/com/juick/server/api/activity/model/activities/Announce.java6
15 files changed, 180 insertions, 28 deletions
diff --git a/juick-common/src/main/java/com/juick/service/component/NotificationListener.java b/juick-common/src/main/java/com/juick/service/component/NotificationListener.java
index 8092e258..38d0490a 100644
--- a/juick-common/src/main/java/com/juick/service/component/NotificationListener.java
+++ b/juick-common/src/main/java/com/juick/service/component/NotificationListener.java
@@ -19,4 +19,7 @@ public interface NotificationListener {
@Async
@EventListener
void processMessageReadEvent(MessageReadEvent messageReadEvent);
+ @Async
+ @EventListener
+ void processTopEvent(TopEvent topEvent);
}
diff --git a/juick-common/src/main/java/com/juick/service/component/TopEvent.java b/juick-common/src/main/java/com/juick/service/component/TopEvent.java
new file mode 100644
index 00000000..b7e24957
--- /dev/null
+++ b/juick-common/src/main/java/com/juick/service/component/TopEvent.java
@@ -0,0 +1,21 @@
+package com.juick.service.component;
+
+import com.juick.Message;
+import org.springframework.context.ApplicationEvent;
+
+public class TopEvent extends ApplicationEvent {
+ private Message message;
+ /**
+ * Create a new ApplicationEvent.
+ *
+ * @param source the object on which the event initially occurred (never {@code null})
+ */
+ public TopEvent(Object source, Message message) {
+ super(source);
+ this.message = message;
+ }
+
+ public Message getMessage() {
+ return message;
+ }
+}
diff --git a/juick-notifications/src/main/java/com/juick/components/APNSManager.java b/juick-notifications/src/main/java/com/juick/components/APNSManager.java
index c0380847..3eaf3c93 100644
--- a/juick-notifications/src/main/java/com/juick/components/APNSManager.java
+++ b/juick-notifications/src/main/java/com/juick/components/APNSManager.java
@@ -1,6 +1,7 @@
package com.juick.components;
import com.juick.ExternalToken;
+import com.juick.Message;
import com.juick.User;
import com.juick.formatters.PlainTextFormatter;
import com.juick.service.component.*;
@@ -113,6 +114,29 @@ public class APNSManager implements NotificationListener {
});
});
}
+
+ @Override
+ public void processTopEvent(TopEvent topEvent) {
+ Message message = topEvent.getMessage();
+ ApnsPayloadBuilder apnsPayloadBuilder = new ApnsPayloadBuilder();
+ message.getUser().getTokens().stream().filter(t -> t.getType().equals("apns"))
+ .map(ExternalToken::getToken).forEach( token -> {
+ String payload = apnsPayloadBuilder.setAlertTitle("Top").setAlertBody("Your message became popular!")
+ .addCustomProperty("mid", message.getMid())
+ .addCustomProperty("uname", message.getUser().getName())
+ .buildWithDefaultMaximumLength();
+ Future<PushNotificationResponse<SimpleApnsPushNotification>> notification = apns.sendNotification(
+ new SimpleApnsPushNotification(token, topic, payload));
+ notification.addListener((PushNotificationResponseListener<SimpleApnsPushNotification>) future -> {
+ if (future.isSuccess()) {
+ processAPNSResponse(token, future.getNow());
+ } else {
+ logger.warn("APNS error ", future.cause());
+ }
+ });
+ });
+ }
+
@PreDestroy
public void close() {
apns.close();
diff --git a/juick-notifications/src/main/java/com/juick/components/FirebaseManager.java b/juick-notifications/src/main/java/com/juick/components/FirebaseManager.java
index 54e7c97a..24bb43d1 100644
--- a/juick-notifications/src/main/java/com/juick/components/FirebaseManager.java
+++ b/juick-notifications/src/main/java/com/juick/components/FirebaseManager.java
@@ -87,4 +87,9 @@ public class FirebaseManager implements NotificationListener {
public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
}
+
+ @Override
+ public void processTopEvent(TopEvent topEvent) {
+
+ }
}
diff --git a/juick-notifications/src/main/java/com/juick/components/MPNSManager.java b/juick-notifications/src/main/java/com/juick/components/MPNSManager.java
index 56c2df8d..d6c99b0b 100644
--- a/juick-notifications/src/main/java/com/juick/components/MPNSManager.java
+++ b/juick-notifications/src/main/java/com/juick/components/MPNSManager.java
@@ -160,4 +160,9 @@ public class MPNSManager implements NotificationListener {
public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
}
+
+ @Override
+ public void processTopEvent(TopEvent topEvent) {
+
+ }
}
diff --git a/juick-server/src/main/java/com/juick/server/ActivityPubManager.java b/juick-server/src/main/java/com/juick/server/ActivityPubManager.java
index 2e511738..f08754c6 100644
--- a/juick-server/src/main/java/com/juick/server/ActivityPubManager.java
+++ b/juick-server/src/main/java/com/juick/server/ActivityPubManager.java
@@ -6,9 +6,11 @@ import com.juick.server.api.activity.model.Link;
import com.juick.server.api.activity.model.Note;
import com.juick.server.api.activity.model.Person;
import com.juick.server.api.activity.model.activities.Accept;
+import com.juick.server.api.activity.model.activities.Announce;
import com.juick.server.api.activity.model.activities.Create;
import com.juick.server.api.activity.model.activities.Delete;
import com.juick.service.SocialService;
+import com.juick.service.UserService;
import com.juick.service.activities.*;
import com.juick.service.component.*;
import com.juick.util.MessageUtils;
@@ -20,6 +22,7 @@ import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import javax.annotation.Nonnull;
+import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.io.IOException;
import java.net.URI;
@@ -29,11 +32,22 @@ import java.util.Collections;
public class ActivityPubManager implements ActivityListener, NotificationListener {
private static final Logger logger = LoggerFactory.getLogger(ActivityPubManager.class);
@Inject
- SignatureManager signatureManager;
+ private SignatureManager signatureManager;
@Inject
- SocialService socialService;
+ private SocialService socialService;
+ @Inject
+ private UserService userService;
@Value("${ap_base_uri:http://localhost:8080/}")
private String baseUri;
+ @Value("${service_user:juick}")
+ private String serviceUsername;
+
+ private User serviceUser;
+
+ @PostConstruct
+ public void init() {
+ serviceUser = userService.getUserByName(serviceUsername);
+ }
@Override
public void processFollowEvent(@Nonnull FollowEvent followEvent) {
@@ -204,4 +218,24 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
}
+
+ @Override
+ public void processTopEvent(TopEvent topEvent) {
+ Message message = topEvent.getMessage();
+ Note note = makeNote(message);
+ Announce announce = new Announce();
+ announce.setId(note.getId() + "#top");
+ announce.setActor(personUri(serviceUser));
+ announce.setObject(note);
+ Person me = (Person) signatureManager.getContext(URI.create(announce.getActor())).get();
+ socialService.getFollowers(serviceUser).forEach(acct -> {
+ Person follower = (Person) signatureManager.getContext(URI.create(acct)).get();
+ try {
+ logger.info("Announcing top: {}", message.getMid());
+ signatureManager.post(me, follower, announce);
+ } catch (IOException e) {
+ logger.warn("activitypub exception", e);
+ }
+ });
+ }
}
diff --git a/juick-server/src/main/java/com/juick/server/EmailManager.java b/juick-server/src/main/java/com/juick/server/EmailManager.java
index 534de35b..726da4b9 100644
--- a/juick-server/src/main/java/com/juick/server/EmailManager.java
+++ b/juick-server/src/main/java/com/juick/server/EmailManager.java
@@ -88,6 +88,11 @@ public class EmailManager implements NotificationListener {
}
+ @Override
+ public void processTopEvent(TopEvent topEvent) {
+
+ }
+
private void emailNotify(String email, String subject, Message msg) {
Map<String, String> headers = new HashMap<>();
if (!MessageUtils.isPM(msg)) {
diff --git a/juick-server/src/main/java/com/juick/server/MessengerManager.java b/juick-server/src/main/java/com/juick/server/MessengerManager.java
index 90c58f03..96320b3b 100644
--- a/juick-server/src/main/java/com/juick/server/MessengerManager.java
+++ b/juick-server/src/main/java/com/juick/server/MessengerManager.java
@@ -27,7 +27,9 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpClientErrorException;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
@@ -54,6 +56,8 @@ public class MessengerManager implements NotificationListener {
private MessengerService messengerService;
@Inject
private CommandsManager commandsManager;
+ @Inject
+ private FacebookPageManager facebookPageManager;
@Value("${fb_page_access_token:12345678}")
private String facebookPageAccessToken;
@@ -145,6 +149,20 @@ public class MessengerManager implements NotificationListener {
}
+ @Override
+ public void processTopEvent(TopEvent topEvent) {
+ Message jmsg = topEvent.getMessage();
+ String status = MessageUtils.getMessageHashTags(jmsg) + StringUtils.defaultString(jmsg.getText());
+ String link = "https://juick.com/m/" + jmsg.getMid();
+ try {
+ facebookPageManager.post(status, link);
+ } catch (HttpClientErrorException ex) {
+ HttpStatus statusCode = ex.getStatusCode();
+ String responseString = ex.getResponseBodyAsString();
+ logger.warn("facebook error {}: {}", statusCode.value(), responseString);
+ }
+ }
+
private void messengerNotify(String messengerUser, String text, String url) {
try {
if (!StringUtils.isEmpty(url)) {
diff --git a/juick-server/src/main/java/com/juick/server/ServerManager.java b/juick-server/src/main/java/com/juick/server/ServerManager.java
index 8a9d224b..81703492 100644
--- a/juick-server/src/main/java/com/juick/server/ServerManager.java
+++ b/juick-server/src/main/java/com/juick/server/ServerManager.java
@@ -207,4 +207,9 @@ public class ServerManager implements NotificationListener {
});
});
}
+
+ @Override
+ public void processTopEvent(TopEvent topEvent) {
+
+ }
}
diff --git a/juick-server/src/main/java/com/juick/server/TelegramBotManager.java b/juick-server/src/main/java/com/juick/server/TelegramBotManager.java
index ab1675f5..12f195aa 100644
--- a/juick-server/src/main/java/com/juick/server/TelegramBotManager.java
+++ b/juick-server/src/main/java/com/juick/server/TelegramBotManager.java
@@ -253,7 +253,7 @@ public class TelegramBotManager implements NotificationListener {
telegramMessage.replyToMessageId(replyTo);
}
telegramMessage.parseMode(ParseMode.Markdown).disableWebPagePreview(true);
- bot.execute(telegramMessage, new Callback<SendMessage, SendResponse>() {
+ bot.execute(telegramMessage, new Callback<>() {
@Override
public void onResponse(SendMessage request, SendResponse response) {
processTelegramResponse(chatId, response, source);
@@ -272,7 +272,7 @@ public class TelegramBotManager implements NotificationListener {
telegramPhoto.replyToMessageId(replyTo);
}
telegramPhoto.parseMode(ParseMode.Markdown);
- bot.execute(telegramPhoto, new Callback<SendPhoto, SendResponse>() {
+ bot.execute(telegramPhoto, new Callback<>() {
@Override
public void onResponse(SendPhoto request, SendResponse response) {
processTelegramResponse(chatId, response, source);
@@ -393,6 +393,14 @@ public class TelegramBotManager implements NotificationListener {
}
@Override
+ public void processTopEvent(TopEvent topEvent) {
+ com.juick.Message message = topEvent.getMessage();
+ telegramService.getTelegramIdentifiers(Collections.singletonList(message.getUser()))
+ .forEach(c -> telegramNotify(c, String.format("Your [post](%s) became popular!",
+ formatUrl(message)), new com.juick.Message()));
+ }
+
+ @Override
public void processSubscribeEvent(SubscribeEvent subscribeEvent) {
User subscriber = subscribeEvent.getUser();
User target = subscribeEvent.getToUser();
diff --git a/juick-server/src/main/java/com/juick/server/TopManager.java b/juick-server/src/main/java/com/juick/server/TopManager.java
index e6c22533..a9157841 100644
--- a/juick-server/src/main/java/com/juick/server/TopManager.java
+++ b/juick-server/src/main/java/com/juick/server/TopManager.java
@@ -22,11 +22,13 @@ import com.juick.Tag;
import com.juick.User;
import com.juick.service.MessagesService;
import com.juick.service.UserService;
+import com.juick.service.component.TopEvent;
import com.juick.util.MessageUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -43,21 +45,9 @@ public class TopManager {
@Inject
private MessagesService messagesService;
@Inject
- private FacebookPageManager facebookPageManager;
+ private ApplicationEventPublisher applicationEventPublisher;
@Inject
private TwitterManager twitterManager;
- @Inject
- private UserService userService;
-
- @Value("${service_user:juick}")
- private String serviceUsername;
-
- private User serviceUser;
-
- @PostConstruct
- public void init() {
- serviceUser = userService.getUserByName(serviceUsername);
- }
@Scheduled(fixedRate = 3600000)
public void updateTop() {
@@ -67,17 +57,7 @@ public class TopManager {
messagesService.setMessagePopular(m, 1);
List<String> tags = jmsg.getTags().stream().map(Tag::getName).map(String::toLowerCase).collect(Collectors.toList());
if (!tags.contains("juick")) {
- String status = MessageUtils.getMessageHashTags(jmsg) + StringUtils.defaultString(jmsg.getText());
- String link = "https://juick.com/m/" + jmsg.getMid();
- try {
- facebookPageManager.post(status, link);
- } catch (HttpClientErrorException ex) {
- HttpStatus statusCode = ex.getStatusCode();
- String responseString = ex.getResponseBodyAsString();
- logger.warn("facebook error {}: {}", statusCode.value(), responseString);
- }
- jmsg.setUser(serviceUser);
- twitterManager.twitterPost(jmsg);
+ applicationEventPublisher.publishEvent(new TopEvent(this, jmsg));
}
});
}
diff --git a/juick-server/src/main/java/com/juick/server/TwitterManager.java b/juick-server/src/main/java/com/juick/server/TwitterManager.java
index eeef2b91..613594e6 100644
--- a/juick-server/src/main/java/com/juick/server/TwitterManager.java
+++ b/juick-server/src/main/java/com/juick/server/TwitterManager.java
@@ -17,6 +17,8 @@
package com.juick.server;
import com.juick.Message;
+import com.juick.User;
+import com.juick.service.UserService;
import com.juick.service.component.*;
import com.juick.service.CrosspostService;
import com.juick.util.MessageUtils;
@@ -28,6 +30,7 @@ import org.springframework.stereotype.Component;
import twitter4j.TwitterFactory;
import twitter4j.conf.ConfigurationBuilder;
+import javax.annotation.PostConstruct;
import javax.inject.Inject;
/**
@@ -45,6 +48,18 @@ public class TwitterManager implements NotificationListener {
private String twitter_consumer_key;
@Value("${twitter_consumer_secret:secret}")
private String twitter_consumer_secret;
+ @Inject
+ private UserService userService;
+
+ @Value("${service_user:juick}")
+ private String serviceUsername;
+
+ private User serviceUser;
+
+ @PostConstruct
+ public void init() {
+ serviceUser = userService.getUserByName(serviceUsername);
+ }
void twitterPost(final com.juick.Message jmsg) {
crosspostService.getTwitterToken(jmsg.getUser().getUid()).ifPresent(t -> {
@@ -100,4 +115,11 @@ public class TwitterManager implements NotificationListener {
public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
}
+
+ @Override
+ public void processTopEvent(TopEvent topEvent) {
+ Message jmsg = topEvent.getMessage();
+ jmsg.setUser(serviceUser);
+ twitterPost(jmsg);
+ }
}
diff --git a/juick-server/src/main/java/com/juick/server/XMPPConnection.java b/juick-server/src/main/java/com/juick/server/XMPPConnection.java
index fdbb5fe6..f405e384 100644
--- a/juick-server/src/main/java/com/juick/server/XMPPConnection.java
+++ b/juick-server/src/main/java/com/juick/server/XMPPConnection.java
@@ -119,6 +119,10 @@ public class XMPPConnection implements StanzaListener, NotificationListener {
private ExecutorService service;
@Inject
private ApplicationEventPublisher applicationEventPublisher;
+ @Value("${service_user:juick}")
+ private String serviceUsername;
+
+ private User serviceUser;
@PostConstruct
public void init() {
@@ -267,6 +271,7 @@ public class XMPPConnection implements StanzaListener, NotificationListener {
logger.warn("xmpp exception", e);
}
});
+ serviceUser = userService.getUserByName(serviceUsername);
}
private String stanzaToString(Stanza stanza) throws XMLStreamException, JAXBException {
@@ -474,6 +479,16 @@ public class XMPPConnection implements StanzaListener, NotificationListener {
}
+ @Override
+ public void processTopEvent(TopEvent topEvent) {
+ com.juick.Message message = topEvent.getMessage();
+ try {
+ commandsManager.processCommand(serviceUser, String.format("! #%d", message.getMid()), URI.create(StringUtils.EMPTY));
+ } catch (Exception e) {
+ logger.warn("XMPP error", e);
+ }
+ }
+
private void incomingPresence(Presence p) {
final String username = p.getTo().getLocal();
final boolean toJuick = username.equals(jid.getLocal());
diff --git a/juick-server/src/main/java/com/juick/server/api/activity/model/Context.java b/juick-server/src/main/java/com/juick/server/api/activity/model/Context.java
index a645d746..9eb03c6f 100644
--- a/juick-server/src/main/java/com/juick/server/api/activity/model/Context.java
+++ b/juick-server/src/main/java/com/juick/server/api/activity/model/Context.java
@@ -19,6 +19,7 @@ import java.util.List;
@JsonSubTypes.Type(value = Accept.class, name = "Accept"),
@JsonSubTypes.Type(value = Undo.class, name = "Undo"),
@JsonSubTypes.Type(value = Like.class, name = "Like"),
+ @JsonSubTypes.Type(value = Activity.class, name = "Activity"),
@JsonSubTypes.Type(value = Image.class, name = "Image"),
@JsonSubTypes.Type(value = Key.class, name = "Key"),
@JsonSubTypes.Type(value = Link.class, name = "Link"),
diff --git a/juick-server/src/main/java/com/juick/server/api/activity/model/activities/Announce.java b/juick-server/src/main/java/com/juick/server/api/activity/model/activities/Announce.java
new file mode 100644
index 00000000..f2859404
--- /dev/null
+++ b/juick-server/src/main/java/com/juick/server/api/activity/model/activities/Announce.java
@@ -0,0 +1,6 @@
+package com.juick.server.api.activity.model.activities;
+
+import com.juick.server.api.activity.model.Activity;
+
+public class Announce extends Activity {
+}