|
@@ -0,0 +1,135 @@
|
|
|
+package com.lemon.lifecenter.scheduler.common;
|
|
|
+
|
|
|
+import java.io.FileNotFoundException;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.HashMap;
|
|
|
+
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.core.io.ClassPathResource;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import com.google.auth.oauth2.GoogleCredentials;
|
|
|
+import com.google.firebase.FirebaseApp;
|
|
|
+import com.google.firebase.FirebaseOptions;
|
|
|
+import com.google.firebase.messaging.AndroidConfig;
|
|
|
+import com.google.firebase.messaging.AndroidNotification;
|
|
|
+import com.google.firebase.messaging.ApnsConfig;
|
|
|
+import com.google.firebase.messaging.Aps;
|
|
|
+import com.google.firebase.messaging.ApsAlert;
|
|
|
+import com.google.firebase.messaging.AndroidNotification.Priority;
|
|
|
+import com.google.firebase.messaging.FirebaseMessaging;
|
|
|
+import com.google.firebase.messaging.FirebaseMessagingException;
|
|
|
+import com.google.firebase.messaging.Message;
|
|
|
+import com.notnoop.apns.APNS;
|
|
|
+import com.notnoop.apns.ApnsService;
|
|
|
+
|
|
|
+@Component
|
|
|
+public class PushUtils {
|
|
|
+
|
|
|
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
|
+
|
|
|
+ public void sendFcm(String deviceKey, String title, String content) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ ClassPathResource cpr = new ClassPathResource("firebase/firebase_service_key.json");
|
|
|
+ FirebaseOptions options = new FirebaseOptions.Builder()
|
|
|
+ .setCredentials(GoogleCredentials.fromStream(cpr.getInputStream()))
|
|
|
+ .setDatabaseUrl("https://fcmtest-ddc32.firebaseio.com/")
|
|
|
+ .build();
|
|
|
+
|
|
|
+ if (FirebaseApp.getApps().isEmpty()) {
|
|
|
+ FirebaseApp.initializeApp(options);
|
|
|
+ }
|
|
|
+
|
|
|
+ String registrationToken = deviceKey;
|
|
|
+
|
|
|
+ AndroidNotification notification = AndroidNotification.builder().setTitle(title).setBody(content).setPriority(Priority.MAX).build();
|
|
|
+ AndroidConfig androidConfig = AndroidConfig.builder().setPriority(AndroidConfig.Priority.HIGH).setNotification(notification).setTtl(7200).build();
|
|
|
+
|
|
|
+ ApsAlert apsAlert = ApsAlert.builder().setTitle(title).setBody(content).build();
|
|
|
+ Aps aps = Aps.builder().setSound("default").setAlert(apsAlert).build();
|
|
|
+ ApnsConfig apnsConfig = ApnsConfig.builder().setAps(aps).build();
|
|
|
+// Message message = Message.builder().setApnsConfig(apnsConfig).setToken(registrationToken).build();
|
|
|
+
|
|
|
+ Message message = Message.builder()
|
|
|
+ .setAndroidConfig(androidConfig)
|
|
|
+ .setApnsConfig(apnsConfig)
|
|
|
+ .setToken(registrationToken).build();
|
|
|
+
|
|
|
+ String response = FirebaseMessaging.getInstance().send(message);
|
|
|
+ logger.error("response -- > " + response);
|
|
|
+
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ logger.error("fileNotFound -- > " + e);
|
|
|
+ errorMsg("FileNotFound");
|
|
|
+ } catch (IOException e) {
|
|
|
+ logger.error("IOException -- > " + e);
|
|
|
+ errorMsg("IOException");
|
|
|
+ } catch (FirebaseMessagingException e) {
|
|
|
+ logger.error("FirebaseMessagingException -- > " + e);
|
|
|
+ errorMsg(e.getErrorCode().toString().trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void errorMsg(String e) {
|
|
|
+ String msg = "";
|
|
|
+ if (fcmErrorCode().get(e) != null) {
|
|
|
+ msg = fcmErrorCode().get(e);
|
|
|
+ } else {
|
|
|
+ msg = fcmErrorCode().get("FATAL");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private HashMap<String, String> fcmErrorCode() {
|
|
|
+ HashMap<String, String> code = new HashMap<String, String>();
|
|
|
+ code.put("UNSPECIFIED_ERROR", "이 오류에 대한 추가 정보가 없습니다.");
|
|
|
+ code.put("INVALID_ARGUMENT", "(HTTP 오류 코드 = 400) 요청 매개 변수가 유효하지 않습니다. google.rpc.BadRequest 유형의 확장자가 리턴되어 유효하지 않은 필드를 지정합니다.");
|
|
|
+ code.put("UNREGISTERED", " (HTTP 오류 코드 = 404) FCM에서 앱 인스턴스가 등록 해제되었습니다. 이것은 일반적으로 사용 된 토큰이 더 이상 유효하지 않으며 새로운 토큰을 사용해야 함을 의미합니다.");
|
|
|
+ code.put("SENDER_ID_MISMATCH", "(HTTP 오류 코드 = 403) 인증 된 발신자 ID가 등록 토큰의 발신자 ID와 다릅니다.");
|
|
|
+ code.put("QUOTA_EXCEEDED", "(HTTP 오류 코드 = 429) 메시지 대상에 대한 전송 제한이 초과되었습니다. 초과 한 할당량을 지정하기 위해 google.rpc.QuotaFailure 유형의 확장이 반환됩니다..");
|
|
|
+ code.put("UNAVAILABLE", " (HTTP 오류 코드 = 503) 서버가 과부하되었습니다.");
|
|
|
+ code.put("INTERNAL", "(HTTP 오류 코드 = 500) 알 수없는 내부 오류가 발생했습니다.");
|
|
|
+ code.put("THIRD_PARTY_AUTH_ERROR", "(HTTP 오류 코드 = 401) APN 인증서 또는 웹 푸시 인증 키가 잘못되었거나 없습니다.");
|
|
|
+ code.put("FATAL", "알수없는 오류");
|
|
|
+ code.put("FileNotFound", "FileNotFound");
|
|
|
+ code.put("IOException", "IOException");
|
|
|
+ return code;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void apnsSend() {
|
|
|
+ ClassPathResource cpr = new ClassPathResource("apns/dev/certify.p12");
|
|
|
+ logger.error("name -- > " + cpr.getFilename());
|
|
|
+ logger.error("path -- > " + cpr.getPath());
|
|
|
+ try {
|
|
|
+ logger.error("file -- > " + cpr.getFile().getAbsolutePath());
|
|
|
+
|
|
|
+ ApnsService service =
|
|
|
+ APNS.newService()
|
|
|
+ .withCert(cpr.getFile().getAbsolutePath(), "jksong092") // 指定p12文件及密钥
|
|
|
+ .withSandboxDestination() // 使用苹果推送测试服务器
|
|
|
+ //.withProductionDestination() // 使用苹果推送生产服务器
|
|
|
+ .build();
|
|
|
+
|
|
|
+ String payload = APNS.newPayload()
|
|
|
+// .alertTitle("推送标题") // 标题
|
|
|
+ .alertBody("푸시발송 테스트") // 内容
|
|
|
+ .customField("sourceCode", "01") // 自定义字段
|
|
|
+ .customField("url", "https://www.qq.com") // 自定义字段
|
|
|
+ .sound("default") // 提示声音
|
|
|
+ //.sound("msgsound.caf") // 提示声音(自定义)
|
|
|
+ .badge(1) // 应用角标
|
|
|
+ .build();
|
|
|
+
|
|
|
+ String token = "1EDAE24F474C7CB5497AD92BB92C506033218BF37E7C808C8CD3B28154D41B07";
|
|
|
+
|
|
|
+ service.push(token, payload);
|
|
|
+
|
|
|
+ } catch (IOException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|