package fr.ippon.tatami.service; import com.notnoop.apns.APNS; import com.notnoop.apns.ApnsService; import com.notnoop.exceptions.NetworkIOException; import fr.ippon.tatami.domain.status.Status; import fr.ippon.tatami.repository.AppleDeviceRepository; import fr.ippon.tatami.repository.AppleDeviceUserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Profile; import org.springframework.core.env.Environment; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.inject.Inject; import java.util.Collection; import java.util.Date; import java.util.Map; /** * Notifies users with iOS push notifications. */ @Service @Profile("apple-push") public class ApplePushService { private static final Logger log = LoggerFactory.getLogger(ApplePushService.class); private ApnsService apnsService; @Inject private Environment env; @Inject private AppleDeviceRepository appleDeviceRepository; @Inject private AppleDeviceUserRepository appleDeviceUserRepository; @PostConstruct public void init() { log.info("Creating Apple Push Service"); String certificate = env.getRequiredProperty("apple.push.certificate"); String password = env.getRequiredProperty("apple.push.password"); apnsService = APNS.newService() .withCert(certificate, password) .withSandboxDestination() .build(); try { apnsService.testConnection(); log.info("Apple Push Service is OK"); } catch (NetworkIOException nioe) { log.warn("Apple Push Service is NOT OK"); } } /** * Notifies the user with APNS. */ public void notifyUser(String login, Status status) { log.debug("Notifying user with Apple Push: {}", login); try { String message = "@" + status.getUsername() + "\n" + status.getContent(); if (message.length() > 256) { message = message.substring(0, 252) + "..."; } String payload = APNS.newPayload() .alertBody(message).build(); Collection<String> deviceIds = appleDeviceRepository.findAppleDevices(login); for (String deviceId : deviceIds) { log.debug("Notifying user : {} - device : {}", login, deviceId); apnsService.push(deviceId, payload); } } catch (Exception e) { log.warn("Apple Push error: " + e.getMessage()); } } /** * Check Apple feedback service for inactive devices. */ @Scheduled(cron = "0 0 23 * * ?") public void feedbackService() { log.info("Checking the Apple Feedback Service for inactive devices"); try { Map<String, Date> inactiveDevices = apnsService.getInactiveDevices(); for (String deviceId : inactiveDevices.keySet()) { log.debug("Device {} is inactive", deviceId); String login = appleDeviceUserRepository.findLoginForDeviceId(deviceId); log.debug("Removing device for user {}" + login); appleDeviceRepository.removeAppleDevice(login, deviceId); appleDeviceUserRepository.removeAppleDeviceForUser(deviceId); } } catch (Exception e) { log.warn("Apple Feedback Service error: " + e.getMessage()); } } }