instapush라는 서비스가 있어서 예전에 그냥 시험삼아 끄적거려 봤는데, 너무 대충이라 간단히 레시피 식으로 어떻게 푸시를 보내는지 알아보는 시간을 가져보자. instapush는 홈페이지에서 계정을 생성한 후 자신의 애플리케이션을 등록하고 필요한 필드들을 설정한 다음, 요구되는 조건에 맞게 REST API를 호출해주면, instapush 앱이 설치된 스마트폰으로 푸시 메시지를 보내주는 서비스이다. 실제로 엄청나게 간단하기 때문에 쉽게 푸시 전송을 보낼 수 있다.
회원 가입 및 앱 생성
먼저 instapush 홈페이지에 가서 회원가입을 한다. 그런다음 Dashboard의 Apps 탭으로 가면 애플리케이션을 만들라는 버튼이 있다.
[+ Add Application] 버튼을 클릭해서 새로운 앱을 등록한다. 이건 뭐 따로 만들어둔 앱을 선택한다기 보다는 일종의 푸시를 구분해서 받을 채널을 만드는 거라 생각하면 된다. 앱을 생성할 때는 이름만 주면 된다.
여기서는 간단하게 TestApp이라고 이름을 정했다. 사실 앱이름은 지금은 하나도 안 중요하니까 아무렇게나 줘도 상관없다.
이벤트 세팅
각각의 앱에 대해서 다시 이벤트를 설정한다. 이벤트는 푸시 메시지의 템플릿이라 생각하면 된다. 이벤트를 만들기 위해서는 이벤트 이름, 트래커 (메시지 파라미터) 그리고 트래커를 이용해서 실제 조합되는 문구의 포맷 템플릿을 정의해야 한다.
간단한 인사말을 전송하는 이벤트를 정의하자. 이벤트 이름은 Greetings
라 하고 트래커로는 name
과 message
를 정의했다. 그리고 푸시메시지의 포맷은 Greet from {name} : "{message}"
라고 정했다. 이를테면 Greet from sooop: "Hello, world"`
와 같은 식으로 푸시 메시지가 전송될 것이다.
앱 아이디와 비밀코드
각각의 앱을 통해서 푸시를 발송하기 위해서는 앱아이디와 앱비밀코드(app secret)가 필요하다. 이는 앱을 처음 생성하면 자동으로 만들어진다. 대시보드에서 앱을 선택하고, 다시 [Basic Info] 탭으로 가면 이를 확인할 수 있다.
스마트폰 앱 설치
실제로 푸시를 수신할 스마트폰용 앱을 설치한다. 웹에서 회원 가입한 동일 계정으로 로그인해 두자.
푸시 전송하기
실제로 푸시를 전송해볼 차례이다. 사실 필요한 모든 정보는 API 페이지의 맨 위에 다 나와있다. 이 내용은 터미널 상에서 curl 이라는 툴을 사용해서 명령줄에서 직접 API 서버로 요청을 날리는 예를 설명한 것이다. (참고로 curl은 거의 모든 OS 용으로 배포되고 있으니, 관심 있는 사람이라면 이곳을 통해서 설치해볼 수도 있다.)
일단 위 내용의 파라미터를 설명하면 다음과 같다.
- curl 은 기본적으로 HTTP나 FTP 등의 인터넷 프로토콜을 이용해서 통신하는 프로그램이다.
-X POST
는 HTTP 요청을 POST method를 이용해서 보낸다는 뜻이다.-H
로 시작하는 값들은 모두 HTTP 요청의 헤더들이다. 헤더는 여러 개의 키:값 쌍으로 구분되며,:
을 통해서 구분된다.-d
로 시작된 이후 내용은 요청의 본체로 서버로 전송될 데이터, 즉 페이로드이다. JSON 포맷을 그대로 사용한다. (이 문자열은 curl 프로그램 내부에서 적절하게 인코딩되어 날아갈 것이다.)
사실, curl 이 시스템에 설치되어 있다면, 저 내용 그대로를 subprocess.check_call()
을 사용해서 호출해도 된다. (물론 실제 그대로는 아니고 데이터 부분과 각 id, secret 정보는 자기 것으로 바꿔야지…) 결국 이 구현은 단순히 HTTP POST 요청하나에 JSON 데이터를 실어서 보내는 것 이상도 이하도 아니다.
urllib.request.Request
흔히 HTTP 요청을 통해서 웹페이지나 웹상의 리소스를 내려받을 때에는 urlopen()
함수를 사용한다. 이 함수만을 사용하는 것은 암시적으로 HTTP GET 요청을 보내는 것으로 일상적인 웹브라우저의 주소창을 이용한 웹페이지 접근과 동일하다고 볼 수 있다. HTTP POST는 폼을 통한 파일업로드나 로그인 등에 사용되는 통신 방식이다. 통신 방식이나 헤더 정보를 커스터마이징하여 통신하기 위해서는 별도의 HTTP 요청 객체를 생성해서, 이를 URL 대신에 urlopen() 함수에 전달해야 한다.
이 클래스의 인스턴스를 생성할 때, 앞서 언급한 대부분의 HTTP 요청의 구성 요소들을 넘겨줄 수 있다.
- 맨 첫 인자는 URL이다.
headers=
인자는 헤더값을 정의한 dict 객체를 넘겨준다.data=
인자는 요청의 페이로드에 대응하는 바이트배열이다.method=
인자는 요청의 방식을 결정한다.
이제 실제 코드를 작성해보자. 위 인자를 사용해서 요청을 만들고 이걸 urlopen
에 넘기면 끝.
from urllib.request import Request, urlopen
import json
def send_greet(name, message):
url = 'https://api.instapush.im/v1/post'
headers = {
'x-instapush-appid' : '5###################',
'x-instapuhs-appsecret' : '3####################',
'Content-Type' : 'application/json'
}
payload = { 'event' : 'Test_Event',
'trackers' : { 'name' : name, 'message' : message }
}
## 페이로드는 json.dumps 를 사용해서 JSON 문자열로 바꾼다음, 다시 인코딩해서 바이트배열로 만든다.
req = Request(url, headers=headers, data=json.dumps(payload).encode(), method='POST')
res = urloepn(req)
print(res.read().decode())
이제 실제로 위 함수를 호출해서 스마트폰으로 푸시 메시지가 전송되는지 확인하면 된다.
curl을 사용하는 방법
curl이 설치된 시스템이라면, 파이썬에서 subprocess 모듈을 사용해서 간단하게 외부 프로세스로 curl을 기동하여 요청을 전송할 수 있다. API 페이지 상단의 예제의 포맷을 그대로 사용하면 된다.
from subprocess import check_call
import json
## check_call 은 명령 실행 후 출력된 내용을 문자열로 리턴해준다.
def send_push_curl(name, message):
payload = { 'event' : 'Test_Event',
'trackers': { 'name' : name, 'message':message }}
data = json.dumps(payload, ensure_ascii=False) ## ensure_ascii=False는 비라틴문자를 위한 옵션
cmds = ['curl',
'-X', 'POST',
'-H', 'x-instapush-appid : 3###########',
'-H', 'x-instapush-appsecret : 5################',
'-H', 'Content-Type: application/json',
'-d', data, ## 인코딩하지 않은 문자열을 사용해야한다.
'https://api.instapush.im/v1/post']
result = check_call(cmds, shell=True, universal_newline=True)
print(result)
instapush 패키지를 사용하는 방법
어떻게 보면 가장 쉬운 방법이다. 앞에서 소개한 직접 HTTP 요청을 만들어서 보내는 과정을 간단히 래핑한 패키지가 이미 제공된다. pip install instapush
로 설치해서 다음과 같이 사용할 수 있다.
from instapush import App
app = App(appid='3##########', secret='5##############')
app.notify(event_name='Test_Event', trackers={'name' : 'sooop', 'message': 'hello, world'})