본문 바로가기
Java

java,spring]twilio를 이용해서 전화솔루션 구축하기 (비상연락망)

by 완기 2021. 6. 21.
728x90
반응형

현재 내가 다니는 회사는 24시간 라이브 서비스를 하는 곳이라

서버가 다운되거나 시스템에 장애가 생기면 이는 곧바로 매출로 직결된다.

 

그래서 이를 최소화하기 위한 솔루션 개발을 회사에서 요청받았다.

 

일단 우리의 목적은 이렇다.

 

기존에 서비스에 문제가 있음을 알려주는 API가 존재한다.

 

이는 알림,경고,위험 단계로 구분되며, 위험 단계에서

이 솔루션을 이용하여 항시 빠른 조치를 할 수 있도록 하기 위함이다.

 


메일 같은 알림 시스템은 Java Mail Sender로 쉽게 구현이 가능하지만, 전화만큼 피드백이 확실한 알림이 없다.

 

다른 솔루션도 많은 것 같기는 한데, 가장 유명한 twilio라는 서비스를 이용해서 구축할 것이다.

 

개발환경:

JAVA 11

gradle 7.0.2

twilio 8.14.0

 

나의 API 설계는 다음과 같다.

API가 호출되면 팀원 전체에게 전화를 한 번씩 돌리고

전화를 받은 사람은 콜백을 통해 다음 전화 대상에서 제외된다.

안 받은 사람은 2분 간격으로 2시간 동안 전화가 가며,

최소 전화 받은 인원이 2명이 안되면 전화를 안 받은 사람에게는 무조건 전화가 계속 간다.


 

    implementation 'org.springframework.boot:spring-boot-starter-web' //API 호출을 위해 선언
    compileOnly 'org.projectlombok:lombok' // Entity 간소화를 위해 선언
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    implementation group: "com.twilio.sdk", name: "twilio", version: "8.14.0" //twilio 사용을 위한 SDK
    

build.gradle에는 다음과 같이 라이브러리들을 명시해주었다.

twilio SDK 이외에는 크게 중요하지 않은 라이브러리들이다.

 

프로젝트 기본적인 구조는 일반적인 spring boot 구조와 동일하다.

 

 

 

Twilio - Communication APIs for SMS, Voice, Video and Authentication

 

www.twilio.com

위 사이트를 가서 회원가입을 해주자.

 

회원 가입은 기본적인 사항을 입력하고 메일 인증을 받으면 완료된다.

간단하니까 이 포스팅에선 생략한다.

기본적으로 로그인을 하게 되면 위 페이지와 같이 콘솔창으로 이동한다.

 

가입을 하게되면 기본적으로 20$가량의 크레딧을 준다.

이 크레딧만으로도 충분한 테스트가 가능할 정도로 많은 크레딧이다.

 

기본적으로 가려진 부분에 AccountID와 아래에 Token으로 프로그램에서 SDK를 통해 인증을 받는 방식이다.

외부로 유출되지 않게 주의하자.

 

기본적으로 이 상태라면 프리티어인데,

프리티어는 콘솔에서 인증한 전화번호만 전화가 가능하고,

전화받을 시, 안내 메시지를 커스텀할 수 없다. 이 점을 알아두고 진행하자.

 

 

 

The Twilio Java Helper Library

 

www.twilio.com

그리고 이 페이지에 접속하면 다양하게 SDK를 다운로드할 수 있는데, 각자 환경에 맞게 적용해주자.

 


전화번호 구입 및 전화번호 인증.

Twilio에서는 전화를 걸기 전에 발신자의 주체가 될 번호를 구입해야 한다.

이 번호는 매달 1달러의 요금을 부과하며, 인터넷 여기저기 찾아본 결과 미국 번호가 음질도 좋고

다른 국가 번호에 비해 안정적이라고 한다.

 

콘솔 창 좌측에 #아이콘을 클릭해서 Buy a Number를 클릭해주자.

 

국가는 미국으로 설정하고, 사용할 서비스에 따라 Capabilities를 선택해주자.

이 포스팅에선 전화 예제이기 때문에 Voice를 체크해줬다.

 

이후 Search를 누르면 많은 번호가 뜬다.

마음에 드는 거 아무거나 고르고 우측에 Buy를 누르면 된다.

항목에도 나와있듯이 매월 요금은 1달러이고,

한국이랑 가까운 일본에 하면 더 싸지 않을까 하다가 14달러인 거 보고 바로 꺼버렸다.

미국이 짱이다.

 

여하튼, 번호를 구입했으면 전화를 받을 전화번호를 인증해야 한다.

 

 

Buy a Number위에 Verified Caller IDs를 클릭하자.

좌측에 빨간 + 버튼을 누르면 팝업창이 뜨는데,

인증을 받기 위한 번호를 적어주자.

국가 번호 포함이기 때문에 만약에 번호가 010-1234-5678이면

1012345678을 적어야 한다.

010에서 0 빼고 101234~처럼 적으면 된다.

 

기본 값은 전화를 받아 인증하는 방식이고 아래 하이퍼 링크를 클릭하면 문자로 인증이 가능하다.

 

인증을 했다면 이제 해당 번호로 전화를 걸 수 있다.

잘 적용된 모습이다.

 

그렇다면 위에 링크에서 코드를 복사 붙여 넣기 해서 기본적인 전화를 해볼 수 있다.

 

레퍼런스는 상당히 잘 되어있는 편이라, 레퍼런스만 보고 해도 문제가 없다.

 

 

 

Quickstart: Use Java to Send and Receive Phone Calls using the Twilio REST API

Learn how to make and receive phone calls in five minutes using the Twilio REST API for Java.

www.twilio.com

 

 

 

300x250

이제부터는 내가 작성한 코드를 기준으로 포스팅을 이어나간다.

컨트롤러 코드는 상당히 간단하다.

Bean 등록을 위해 Controller 어노테이션을 클래스에 지정해주고,

 

전화와 관련된 로직을 수행할 TwilioService를 AutoWired로 주입해줬다.

/check 메서드는 전화를 받은 사람을 체크하기 위한 API다.

 

wakeUpMembers는 일어난 사람의 리스트를 담기 위한 String형 List다.

전역으로 선언되어있기 때문에, 일어난 사람을 실시간으로 체크한다.

 


Service 

아까 콘솔에서 확인한 SID, TOKEN을 상수로 선언해줬다.

 

그리고 @Service 어노테이션을 지정해서 실행 시 모든 Bean들이 등록되기 때문에, 생성자에 SDK를 init 했다.

SID, TOKEN순으로 인자를 넣어주면 인증이 완료된다.

 

WakeUpMembers는 전화를 받은 사람을 체크하기 위해 초기화해두었으며,

dialRange는 얼마나 전화를 지속시킬 건가에 대해 체크하기 위해 선언해뒀다.

 

FROM은 아까 콘솔에서 구입한 번호를 넣어주면 된다.

혹은 콘솔 홈에서 Trial Number을 넣어도 된다.

 

일단 전화를 걸기 위한 로직은 다음과 같다.

전화를 걸기 위한 리스트를 Map에 담아줬다.

Map에 담은 이유는 Key는 받은 사람의 이름이고 value는 그 사람의 번호기 때문에 식별이 쉬워서 Map을 사용했다.

저 Map에 담긴 리스트들이 프로그램을 통해 전화를 걸어야 할 대상들이다.

 

     while (wakeUpMembers.size() <= 2 && dialRange <= 60) {
         for (String to : numbers.keySet()) { //Map 순회
            if (wakeUpMembers.size() != 0) { //일어난 사람에게는 전화를 걸지않기 위해
               if (!isWakeUp(to)) { //안일어 났다면
                  sendCall(res, numbers.get(to), to);//전화를 건다.
               }
            } else if (wakeUpMembers.size() == 0) {//아무도 안일어났다면 모두에게 전화를 돌림
               firstTimeCall(res, numbers);
            }
         }
         Thread.sleep(1000 * 60 * 2);//전화가 한 번씩 가고 2분 대기.
         if (dialRange <= 60) { //전화가 얼마나 갔는지 알기위해 카운팅.
            dialRange++;
         }
         if (wakeUpMembers.size() >= 2 && dialRange >= 60) {
            break; //2시간 이상,일어난 사람이 2명이상이면 더 이상, 전화를 걸지않음.
         }
      }//end of while

 

전화받은 사람 체크하기.

전화받은 리스트에 있으면 true 없으면 false를 리턴한다.

 


전화 걸기.

url은 Arrays.asList("answered") 부분과 관계가 있는데,

인자로 받은 receiver가 전화를 받았다면(answered) 해당 url을 호출한다.

 

위 컨트롤러 코드와 일치하는 메서드이다.

 

이 URL 부분은 Twilio에서 쏴주는 부분이기 때문에, 로컬에선 테스트가 불가능하여 ngrok나 ec2에 따로 서버를 띄워서 확인해야 한다.

제일 우측에 3번째 인자에 gather은 전화를 받았을 때, 안내 메시지를 위해 사용했다.

 

이런 식으로 코드를 작성하게 되면 전화를 받은 사람을 인자로 넘겨,

전화받은 사람의 이름을 부르면서 비상 전화다. 메신저 확인해라와 같은 메시지를 안내해준다.

 

코드는 이게 전부고 실제 API를 통해 확인해보면 국제 전화가 내 핸드폰에 온다.

 


아까 앞서 언급한 ngrok 사용법은 

 

 

ngrok - secure introspectable tunnels to localhost

@Botto ngrok, probably the best tool I have started to use for my webwork since firebug also great support

ngrok.com

이 사이트에서 프로그램을 다운로드하고,

 

터미널을 통해서 다운로드한 경로까지 이동한 후, 다음 명령어를 입력하자.

./ngrok http 8080

그럼 이미지처럼 주소가 할당되고, https://~ 에 시작하는 주소를 내 API와 매핑시키면

외부에서도 접속이 가능하기 때문에, 받은 사람에 대해 체크할 수 있다.

 

 

728x90
728x90

댓글