Overview

지난엔 대략적인 구조와 설정적인 부분을 봤다면 이번엔 해당 SDK를 호출 및 기능에 대해 구체적으로 기록하고자 한다. 뭔가 SNS를 검색하면, SQS도 연관검색어로 나오지만 이번엔 SNS -> FCM -> AOS, iOS 케이스에 대한 API 코드를 기록할 것이다.
간략한 주요 개념, GUI 방식, 프로그래밍적 방식을 정리해본다.

Contents

  1. 주요 개념
    • Topic
      • 메시지를 게시하고 구독할 수 있는 논리적 액세스 포인트
      • 다양한 옵션으로 구독 가능
    • Push Notification
      • 모바일 디바이스에 메시지를 직접 전송하는 기능
  2. Topic 기능
    • Topic 생성
      • 메시지를 게시할 수 있는 주제 생성
    • Topic 구독
      • 다양한 옵션으로 Topic 구독 가능
      • 구독 옵션에 따라 메시지 수신 방식 결정
      • (수행해본적없음) PlatformApplication 내 Endpoint Arn을 통해 구독 가능
    • Topic 게시(Publish)
      • 특정 Topic에 메시지 게시
      • 구독 옵션과 형태에 따라 지정된 액션 수행
  3. Push Notification 기능
    • PlatformApplication 생성
      • 푸시 알림을 보낼 플랫폼 애플리케이션 생성
    • Endpoint 생성
      • PlatformApplication에 Endpoint 생성
      • Device Token 필수 (대상 식별용, 보통 FCM의 token을 사용)
      • UserData 옵션 제공 (추가 정보 입력 가능)
  4. 추가 정보
    • GUI 지원: AWS 콘솔을 통한 시각적 관리 가능
    • SDK 호출: 프로그래밍 방식으로 기능 구현 가능

GUI 예시

Dashboard

생성한 Topic에 subscrible
여러가지 프로토콜로 subscrible 할 수 있다.

email은 등록된 email에서 confirm을 해야된다.

생성한 Platform Application에 Endpoint enroll


SDK 사용예시

AWS에서 아래와 같은 SDK를 지원한다.(나는Java로 작성해보았다.)

  • Topic
    • Create
      private CreateTopicResponse createTopicResponse(String topicName){
          return awsConfig.getSnsClient().createTopic(req->req.name(topicName));
      }
      

      Topic을 생성한다.

    • delete
      private DeleteTopicResponse deleteTopicResponse(String topicArn){
          return awsConfig.getSnsClient().deleteTopic(req->req.topicArn(topicArn));
      }
      

      Topic을 삭제한다.

    • subscrible
      private SubscribeResponse subscribeResponse(String protocol, String topicArn, String endpoint){
      //        -- protocol
      //        http – delivery of JSON-encoded message via HTTP POST
      //        https – delivery of JSON-encoded message via HTTPS POST
      //        email – delivery of message via SMTP
      //        email-json – delivery of JSON-encoded message via SMTP
      //        sms – delivery of message via SMS
      //        sqs – delivery of JSON-encoded message to an Amazon SQS queue
      //        application – delivery of JSON-encoded message to an EndpointArn for a mobile app and device.
      //        lambda – delivery of JSON-encoded message to an Amazon Lambda function.
              return awsConfig.getSnsClient().subscribe(req->
               req.protocol(protocol.toUpperCase())
                  .topicArn(topicArn)
                  .endpoint(endpoint));
      }
      

      subscribe한다.

    • unsubscrible
      private UnsubscribeResponse unsubscribeResponse(String unSubArn){
          return awsConfig.getSnsClient().unsubscribe(req->req.subscriptionArn(unSubArn));
      }
      

      unsubscribe한다.

    • subscrible select
      private ListSubscriptionsResponse listSubscriptionsResponse(){
          return awsConfig.getSnsClient().listSubscriptions();
      }
      

      subscrible list 정보를 select 한다.

    • publish
      private PublishResponse topicPublishResponse(String topicArn){
          return awsConfig.getSnsClient().publish(req->req.topicArn(topicArn)
                  .subject("제목")
                  .message("본문"));
      }
      

      Topic을 subscirble한 대상에게 publish 한다.

  • PlatformApplication
    • PlatformApplication create
      private CreatePlatformApplicationResponse createPlatformApplicationResponse(String applicationName){
          Map<String,String> attribute = new HashMap<>();
      //        attribue.put("PlatformCredential", "Google API KEY");
          return awsConfig.getSnsClient().createPlatformApplication(req->
               req.name(applicationName)
                  .platform("GCM")
                  .attributes(attribute));
      }  
      

      FCM(GCM)을 등록하기 위해 .json을 attribute(map)에 추가하여 API를 전송해준다.

      참고 URL - SetPlatformApplicationAttributes

    • PlatformApplication delete
      private DeletePlatformApplicationResponse deletePlatformApplicationResponse(String applicationArn){
          return awsConfig.getSnsClient().deletePlatformApplication(req->req.platformApplicationArn(applicationArn));
      }
      

      PlatformAppilcation을 delete한다.

    • Endpoint create
      private CreatePlatformEndpointResponse createPlatformEndpointResponse(String applicationArn,
                                                                            String token,
                                                                            String customUserData){
          return awsConfig.getSnsClient().createPlatformEndpoint(req->
               req.platformApplicationArn(applicationArn)
                  .token(token)
                  .customUserData(customUserData));
      }
      

      특정 platformapplication에 endpoint을 등록한다.

    • Endpoint delete
      private DeleteEndpointResponse deleteEndpointResponse(String endPointArn){
          return awsConfig.getSnsClient().deleteEndpoint(req->req.endpointArn(endPointArn));
      }
      

      endpoint를 삭제한다.

    • Endpoint select
      private ListEndpointsByPlatformApplicationResponse listEndpointsByPlatformApplicationResponse(String applicationArn){
          return awsConfig.getSnsClient().listEndpointsByPlatformApplication(req->req.platformApplicationArn(applicationArn));
      }
      

      platformApplication에 등록된 endpoint를 select한다.

    • Endpoint status
      private GetEndpointAttributesResponse getEndpointStatusResponse(String endPointArn){
          return awsConfig.getSnsClient().getEndpointAttributes(req->req.endpointArn(endPointArn));
      }
      

      platformApplication에 등록된 endpoint의 status를 조회한다.

    • Endpoint publish
      private PublishResponse notificationPublishResponse(String endPointArn, String subject, String msg){
          return awsConfig.getSnsClient().publish(req->
               req.targetArn(endPointArn)
                  .messageStructure("json")
                  .subject(subject)
                  .message(makeMessage(subject,msg)));
      }
      
      private String makeMessage(String title, String bodyMessage){
          Map<String,Object> messageBodyMap = new HashMap<String, Object>();
          messageBodyMap.put("title",title);
          messageBodyMap.put("body",bodyMessage);
      
          Map<String,Object> messageResMap = new HashMap<String, Object>();
          messageResMap.put("notification", messageBodyMap);
      
          Map<String,Object> messageMap = new HashMap<String, Object>();
          messageMap.put("GCM", Utility.jsonify(messageResMap));
      
          log.debug("MSG ::: {}", Utility.jsonify(messageMap));
      
          return Utility.jsonify(messageMap);
      }
      

      PlatformApplication에 등록된 Endpoint들이 publish 한다.

GUI로 메시지 publish

Message Publish

json 포맷을 맞춰서 메시지 조립하여 publish해야된다.
AWS SNS → FCM → AOS Client App
AWS SNS → FCM → APNS - iOS Client App
FCM : “json String”으로 보내는데, notification, data,, 등이 있다.
Android Background에서 실행하기 위해서는 Notification이아닌 data로 데이터를 세팅하여 보낸다.
APNS : aps 하위 alert 밑에 body,title 등이 있다.

참고 url : Firebase Message , APNS Message

마치면서

AWS SNS를 쓰면서 Push Notification 기능을 구현하였고, SpringBatch를 이용해서 publish를 하도록 구현하였다. 애먹엇던부분이 publish였는데 message payload를 각 native os별로 맞추는게 어려웠던거 같다. 각 Native OS 별 메시지 구조에 대한 이해도가 낮아서 Sample 앱을 만들어서 푸쉬가 각 네이티브 클라이언트에서 잘왔는지, 메시지 포맷이 안맞아서 안왔는지 확인하는 그런 부분이 힘들었던거같다. 아! 그리고, EndPoint를 등록하면 status가 일단 정상인데, 최초 유효하지 않은 token으로 등록되고 초회 publish을 하기 전까지는 status상태가 무조건 정상이라는점, 또한 SNS를 쓰면서 ARN(Amazon Resource Name)이라는 값으로 모든 topic이든 subscrible든 endpoint든 컨트롤하는지 알게 되었다는점 신기하였다 ㅎ 작년 10월~11월에 개발했던부분인데 이제서야 기록을 남겨서 다행이라고 생각한다.