co.fingerprintsoft.notification.apns.APNSSender Maven / Gradle / Ivy
The newest version!
package co.fingerprintsoft.notification.apns;
import co.fingerprintsoft.notification.NotificationResult;
import co.fingerprintsoft.notification.PushNotificationSender;
import com.relayrides.pushy.apns.ApnsClient;
import com.relayrides.pushy.apns.ClientNotConnectedException;
import com.relayrides.pushy.apns.PushNotificationResponse;
import com.relayrides.pushy.apns.util.ApnsPayloadBuilder;
import com.relayrides.pushy.apns.util.SimpleApnsPushNotification;
import com.relayrides.pushy.apns.util.TokenUtil;
import io.netty.util.concurrent.Future;
import lombok.Data;
import lombok.ToString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutionException;
/**
* Parent class of ProductionAPNSService and SandboxAPNSService.
* Setups the push manager for push notifications for apple devices.
* The environment to which to connect to apples servers is determined by the sub class
* PushManager comes from the pushy plugin which can be found at
* RelayRides Pushy
*/
public class APNSSender implements PushNotificationSender {
private static final Logger LOG = LoggerFactory.getLogger(APNSSender.class);
private APNSSettings apnsSettings;
private ApnsClient apnsClient;
public APNSSender(APNSSettings apnsSettings, ApnsClient apnsClient) {
this.apnsSettings = apnsSettings;
this.apnsClient = apnsClient;
}
@Override
public NotificationResult sendNotification(String alertBody, String deviceToken) {
return new APNSNotificationResult(send(alertBody, deviceToken));
}
private String send(String alertBody, String deviceToken) {
Future connectFuture;
synchronized (apnsClient) {
if (!apnsClient.isConnected()) {
if (apnsSettings.isSandboxed()) {
connectFuture = apnsClient.connect(ApnsClient.DEVELOPMENT_APNS_HOST);
} else {
connectFuture = apnsClient.connect(ApnsClient.PRODUCTION_APNS_HOST);
}
try {
connectFuture.await();
} catch (InterruptedException e) {
LOG.error("Could not connect", e);
return "Could not connect";
}
}
}
final SimpleApnsPushNotification pushNotification;
{
final ApnsPayloadBuilder payloadBuilder = new ApnsPayloadBuilder();
payloadBuilder.setAlertBody(alertBody);
payloadBuilder.setAlertTitle("Forex Notification"); // this is only used for the Apple Smart Watch
payloadBuilder.setAlertBody(alertBody);
payloadBuilder.setBadgeNumber(1);
payloadBuilder.setSoundFileName("ring-ring.aiff"); // notification sound to play
final String payload = payloadBuilder.buildWithDefaultMaximumLength();
final String token = TokenUtil.sanitizeTokenString(deviceToken);
pushNotification = new SimpleApnsPushNotification(token, "co.za.albaraka.forex.abb-fx-requestor", payload);
}
try {
String result = getResponse(pushNotification);
if (result != null) return result;
} catch (final ExecutionException e) {
LOG.error("Failed to send push notification.", e);
if (e.getCause() instanceof ClientNotConnectedException) {
LOG.debug("Waiting for client to reconnect…");
try {
apnsClient.getReconnectionFuture().await();
LOG.debug("Reconnected.");
} catch (InterruptedException e1) {
LOG.error("Could not reconnect", e1);
}
try {
String result = getResponse(pushNotification);
if (result != null) return result;
} catch (ExecutionException | InterruptedException re) {
LOG.error("Failed retrying to send push notification.", re);
}
}
} catch (InterruptedException e) {
LOG.error("Could not send", e);
}
return "Error Occurred please check the logs";
}
private String getResponse(SimpleApnsPushNotification pushNotification) throws InterruptedException, ExecutionException {
final PushNotificationResponse pushNotificationResponse =
apnsClient.sendNotification(pushNotification).get();
if (pushNotificationResponse.isAccepted()) {
LOG.debug("Push notification accepted by APNs gateway.");
return "Push notification accepted by APNs gateway.";
}
LOG.error("Notification rejected by the APNs gateway: {}", pushNotificationResponse.getRejectionReason());
String result = String.format("Notification rejected by the APNs gateway: %s", pushNotificationResponse.getRejectionReason());
if (pushNotificationResponse.getTokenInvalidationTimestamp() != null) {
LOG.error("\t…and the token is invalid as of {}", pushNotificationResponse.getTokenInvalidationTimestamp());
result += String.format("\t…and the token is invalid as of {}", pushNotificationResponse.getTokenInvalidationTimestamp());
}
return result;
}
@Data
@ToString(callSuper = true)
class APNSNotificationResult implements NotificationResult {
private String result;
public APNSNotificationResult(String result) {
this.result = result;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy