package com.juick.server; import com.github.messenger4j.Messenger; import com.github.messenger4j.exception.MessengerApiException; import com.github.messenger4j.exception.MessengerIOException; import com.github.messenger4j.exception.MessengerVerificationException; import com.github.messenger4j.send.MessagePayload; import com.github.messenger4j.send.MessageTag; import com.github.messenger4j.send.MessagingType; import com.github.messenger4j.send.NotificationType; import com.github.messenger4j.send.message.TemplateMessage; import com.github.messenger4j.send.message.TextMessage; import com.github.messenger4j.send.message.template.ButtonTemplate; import com.github.messenger4j.send.message.template.button.UrlButton; import com.github.messenger4j.send.recipient.IdRecipient; import com.github.messenger4j.userprofile.UserProfile; import com.github.messenger4j.webhook.event.TextMessageEvent; import com.juick.Message; import com.juick.User; import com.juick.model.AnonymousUser; import com.juick.service.MessagesService; import com.juick.service.MessengerService; import com.juick.service.UserService; import com.juick.service.component.*; 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.stereotype.Component; import javax.annotation.Nonnull; import javax.annotation.PostConstruct; import javax.inject.Inject; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.time.Instant; import java.util.Collections; import java.util.List; import java.util.Optional; import static com.juick.formatters.PlainTextFormatter.formatPost; import static com.juick.formatters.PlainTextFormatter.formatUrl; @Component public class MessengerManager implements NotificationListener { private static final Logger logger = LoggerFactory.getLogger(MessengerManager.class); @Inject private MessagesService messagesService; @Inject private UserService userService; @Inject private MessengerService messengerService; @Inject private CommandsManager commandsManager; @Value("${fb_page_access_token:12345678}") private String facebookPageAccessToken; @Value("${fb_verify_token:12345678}") private String facebookVerifyToken; @Value("${fb_secret:12345678}") private String facebookSecret; private Messenger messenger; @PostConstruct public void init() { messenger = Messenger.create(facebookPageAccessToken, facebookSecret, facebookVerifyToken); } public String getFacebookVerifyToken() { return facebookVerifyToken; } public void processUpdate(String signature , String data) throws MessengerVerificationException { messenger.onReceiveEvents(data, Optional.of(signature), event -> { final String senderId = event.senderId(); final Instant timestamp = event.timestamp(); User user_from = userService.getUserByUID(messengerService.getUserId(senderId)).orElse(AnonymousUser.INSTANCE); logger.info("Found juick user {}", user_from.getUid()); if (user_from.isAnonymous()) { try { UserProfile profile = messenger.queryUserProfile(senderId); signupNotify(senderId, messengerService.getSignUpHash(senderId, profile.firstName())); } catch (MessengerApiException | MessengerIOException | MalformedURLException e) { logger.warn("messenger profile error", e); try { signupNotify(senderId, messengerService.getSignUpHash(senderId, "anonymous")); } catch (MalformedURLException | MessengerApiException | MessengerIOException e1) { logger.warn("signup error", e1); } } } else { if (event.isTextMessageEvent()) { final TextMessageEvent textMessageEvent = event.asTextMessageEvent(); final String messageId = textMessageEvent.messageId(); final String text = textMessageEvent.text(); logger.info("Received text message from '{}' at '{}' with content: {} (mid: {})", senderId, timestamp, text, messageId); try { commandsManager.processCommand(user_from, text, URI.create(StringUtils.EMPTY)); } catch (Exception e) { logger.warn("messenger error", e); } messengerNotify(senderId, "Message sent", null); } } }); } @Override public void processMessageEvent(@Nonnull MessageEvent event) { Message msg = event.getMessage(); List subscribedUsers = event.getUsers(); if (msg.isService()) { return; } if (!MessageUtils.isPM(msg)) { String subject = formatPost(msg); subscribedUsers .forEach(user -> messengerService.getSenderId(user) .ifPresent(t -> messengerNotify(t, subject, formatUrl(msg)))); } } @Override public void processSubscribeEvent(SubscribeEvent subscribeEvent) { } @Override public void processLikeEvent(LikeEvent likeEvent) { } @Override public void processPingEvent(PingEvent pingEvent) { } @Override public void processMessageReadEvent(MessageReadEvent messageReadEvent) { } private void messengerNotify(String messengerUser, String text, String url) { try { if (!StringUtils.isEmpty(url)) { final UrlButton showMessage = UrlButton.create("VIEW MESSAGE", new URL(url)); ButtonTemplate template = ButtonTemplate.create(text, Collections.singletonList(showMessage)); messenger.send(MessagePayload.create(IdRecipient.create(messengerUser), MessagingType.MESSAGE_TAG, TemplateMessage.create(template), Optional.of(NotificationType.REGULAR), Optional.of(MessageTag.NON_PROMOTIONAL_SUBSCRIPTION))); } else { messenger.send(MessagePayload.create(IdRecipient.create(messengerUser), MessagingType.MESSAGE_TAG, TextMessage.create(text), Optional.of(NotificationType.REGULAR), Optional.of(MessageTag.NON_PROMOTIONAL_SUBSCRIPTION))); } } catch (MessengerApiException | MessengerIOException | MalformedURLException e) { logger.warn("messenger error", e); } } private void signupNotify(String messengerUser, String hash) throws MalformedURLException, MessengerApiException, MessengerIOException { final UrlButton urlButton = UrlButton.create("LOGIN", new URL("https://juick.com/signup?type=messenger&hash=" + hash)); ButtonTemplate template = ButtonTemplate.create("Login to receive notifications", Collections.singletonList(urlButton)); messenger.send(MessagePayload.create(messengerUser, MessagingType.RESPONSE, TemplateMessage.create(template))); } }