kokbee-Hive
article thumbnail

 

입사 후, 새로 시작하는 서비스를 만들때 사용하던 앱 푸시를 고도화해야 할 때가 와서 진행하게 되었다.
고도화의 이유에는 여러가지가 있지만, 기존에 사용하던 푸시 방식이 올드하다는 것과 새롭게 개편될 앱에서 사용할 마케팅용 앱푸시의 불편함 때문이었다.

그 과정을 기록 하고자 적고 공유하는 글입니다. 😎

 


* 참고: Apple developer 사이트에서 앱 등록 및 세팅 다 가정되어 있고 그 이후에 내용입니다.

 

1. 개발 진행 전


iOS의 경우 테스터로 푸시 알림 테스트


※개발환경에서 로그로 확인한 deviceToken은 Sandbox APN Server로 발송
※ 동일한 앱이라도 앱스토어에서 다운로드 받은 앱은 deviceToken이 다르고 스토어에서 앱 재설치해도 deviceToken이 달라짐
※ 앱스토어에서 설치한 앱으로 받은 deviceToken만 Production APN Server로 발송 가능
  1.  요구사항 분석 (iOS)
    1.  기존 백오피스에서 사용하던 올드한 방식의 푸시를 간편하게 개선
    2.  기존 푸시의 경우 sandbox 알림을 사용할 수 없음
      1. sandbox란? 애플에서 prodction용으로 알림을 보내는 게 아닌 개발환경에서 테스트를 할 수 있도록 해주는 알림 테스트 (https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/se)nding_notification_requests_to_apns
    3.  기존 모듈의 최신화 또는 새로운 모듈로 변경 (node-apn-http2) 의경우 5년 전에 Deprecated 
    4.  타이틀 추가 및 bold 기능 (subtitle or title로 가능), 줄바꿈
 

Sending Notification Requests to APNs | Apple Developer Documentation

Transmit your remote notification payload and device token information to Apple Push Notification service (APNs).

developer.apple.com

 

2. 모듈 교체를 위한 리서치 및 개발 사항 분석


1. node-apn-http2 https://www.npmjs.com/package/node-apn-http2

 

node-apn-http2

Communicate with Apple Push Notification Service via native Node.js v8.8.1+ HTTP2 module (node-apn drop-in). Latest version: 1.2.0, last published: 5 years ago. Start using node-apn-http2 in your project by running `npm i node-apn-http2`. There are 2 other

www.npmjs.com


회사에서 쓰던 모듈은 5년전에 이미 종료되었고, 사실상 node-apn의 forked 버전임..

다른사람들도 따로 포크를따서 수정중인 상황, 그나마 최신은 1년전 포크를따서 수정한사람의 것이다. 


https://www.npmjs.com/package/@parse/node-apn

 

@parse/node-apn

An interface to the Apple Push Notification service for Node.js. Latest version: 5.1.3, last published: a year ago. Start using @parse/node-apn in your project by running `npm i @parse/node-apn`. There are 21 other projects in the npm registry using @parse

www.npmjs.com

 

그럼 어떻게 해야할까?

  1.  우리도 포크를 따서 수정한다. (결정)
  2.  aws-sdk를 사용한다. 

aws-sdk는 돈이 들기에... 일단 포크를 따서 쓰기로 하였다. 

개발하면서 들은 얘기로는 왜 수정이 없는지는 앱팀 팀장님이 말씀주셧는데..

apple 측에서 url주소를 바꾸지 않는이상 수정 할 일이 없다는것!

또한, firebase를 사용해서 하는 회사가 많기때문.. (하지만 우리회사는 ㅜㅜ 당장사용하지 못하는 글로벌환경)

 

 

 

 

 

3. 모듈 교체 및 테스트


포크를 따서 수정을 진행

다른 레포지터리와 회사의 컨벤션에 맞춰서 수정하였다. (npm publish는 하지않음 - public 레포)

 

현재 푸시를 보내는 Flow

PushService에서 어디로갈지 받게 되면 인증을 통해 푸시를 전송

따라서 PushService에 코드를 고쳐야함

 

 

3-1. 고치기전 진행할사항

  • sandbox 엔드포인트 추가

기존 엔드포인트를 api.sandbox.push.apple.com로 변경
  • 보안 취약점 수정 (jsowebtoken) -> 9.0.0으로 수정
  • 회사의 컨벤션 적용 (standardjs) 및 uuid 적용

 

3-2. 모듈 교체 및 테스트(푸셔)

물론 성.공.함

성공해서 자랑햇다가 앱팀 팀장님한테 자랑했는데, 공유상황에 같이 박제됨..;ㅁ;

 

 

 

4.  코드 작성


임시로 블로그에 올리려고 짠 코드입니다.
대충 이런 느낌이라고 보시면 될것 같습니다. 

const apn = require('node-apn')

const MAX_BYTES = 4096
const apnProvider = new apn.Provider({
    token: {
      key: 'apns.p8',
      keyId: 'mykeyId',
      teamId: 'mytemeId'
    },
    production: false,
    sandbox: true,
    topic: 'myAppTopic'
})

function sendNoti (options, callback) {
  const note = new apn.Notification()
  note.expiry = options.ttl ?? Math.floor(Date.now() / 1000)
  note.badge = options.badge || 3

  const alert = {}
  let body = options.body ?? 'Notification Test'
  // title 이 없는 경우 기본적인 앱 이름으로 표기 한다.
  if (options.title) alert.title = options.title
  if (options.subtitle) alert.subtitle = options.subtitle
  // max를 넘는 경우 ..으로 표시
  if (Buffer.byteLength(body) > MAX_BYTES - 2) body = body.substring(0, MAX_BYTES - 2) + '..'
  alert.body = body
  note.alert = alert

  const deviceList = options.device_list.map(d => d.device_token)

  apnProvider.send(note, deviceList)
    .then((result) => {})
}

설명

- body: 메세지 본문, 쓸 수 있는 값이 4KB가 MAX가 있기에 MAX값을 넘는경우 ..으로 표기한다. (그렇게 까지 많이 쓸일은 없지만..)

- subtitle: 볼드 체 및 앱 이름 밑에 표기될 타이틀 기본값은 없으면, 있는 경우 출력

- title: 푸시에 표기될 앱이름 변경할 수 있고 없으면 기본값인 앱이름

 

 

 

이상으로 push 관련하여 part.1을 마치고 part.2로 이어집니당 

profile

kokbee-Hive

@콕비

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!