외부 API/etc

스트라바 Strava Webhook 이벤트 API

재테크하는 개발자 2022. 2. 28. 23:01

 

 

 


 

 

 

 

Strava API 사용 시 Webhook 이 없다면 사용자의 데이터를 언제 동기화할지 모르기 때문에 클라이언트에서 주기적으로 서버에 데이터를 얻어와서 변경 여부를 체크해야 합니다. 
Webhook을 사용하는 경우 서버에 데이터가 업데이트되는 시점을 Webhook으로 등록한 URL로 알려주기 때문에 필요한 시점에서만  Strava API 호출하여 데이터를 동기화할 수 있습니다.  

Strava Webhook Event Data

Strava API에서 Webhook 가이드는 링크에서 확인이 가능합니다.  Strava Webhook API에서는 athlete와 activitiy object의  Title, Type과 같은 데이터 생성, 삭제, 갱신된 경우 클라이언트로 이벤트를 전달합니다.  API scope 중 activity:read_all에 대한 Permission을 가지고 있어야 사용 가능합니다.

 

참고 URL : https://developers.strava.com/docs/webhooks/

Strava Webhook  API 등록하기

Strava에서 Webhook URL 등록은 하나의 앱에서는 1개만 허용됩니다. 
Webhook의 callbac url로 등록하는 URL 은 외부 인터넷에서 접속 가능해야 하고, URL 처리를 위해서는 Web server가 설치되어 있어야 합니다.
ngrok을 통해 테스트를 하였으며, web server는 nodejs를 사용하였습니다.

 

 

 

Create a subscrtiption

Webhook Event를 받을 URL을 등록하는 과정입니다. Client ID와 Client Secrete은 App 등록 시 할당받은 값으로 적용하면 되고, callback_url은 Webhook 이벤트를 받을 서버 URL로 적용해야 합니다.
Strava 서버에서 callback_url로 변경된 데이터를 JSON으로 POST method로 호출하고, Webhook 서버에서는 callback_url에 대한 적절한 응답을 해야 합니다.
Webhook 서버에서 응답이 없거나 잘못된 경우 에러가 발생할 수 있습니다. 
마지막 인자인 verify token은 임의 string 값으로 넣을 수 있고, webhook validation 시 활용할 수 있는 값입니다.  

 

 

"use strict";

// Imports dependencies and sets up http server
const express = require("express"),
  bodyParser = require("body-parser"),
  // creates express http server
  app = express().use(bodyParser.json());

// Sets server port and logs message on success
app.listen(process.env.PORT || 3000, () => console.log("webhook is listening"));

// Creates the endpoint for our webhook
app.post("/webhook", (req, res) => {
  console.log("webhook event received!", req.query, req.body);
  res.status(200).send("EVENT_RECEIVED");
});

// Adds support for GET requests to our webhook
app.get("/webhook", (req, res) => {
  // Your verify token. Should be a random string.
  const VERIFY_TOKEN = "STRAVA";
  // Parses the query params
  let mode = req.query["hub.mode"];
  let token = req.query["hub.verify_token"];
  let challenge = req.query["hub.challenge"];
  // Checks if a token and mode is in the query string of the request
  if (mode && token) {
    // Verifies that the mode and token sent are valid
    if (mode === "subscribe" && token === VERIFY_TOKEN) {
      // Responds with the challenge token from the request
      console.log("WEBHOOK_VERIFIED");
      res.json({ "hub.challenge": challenge });
    } else {
      // Responds with '403 Forbidden' if verify tokens do not match
      res.sendStatus(403);
    }
  }
});

 

Strava 서버에서는 Webhook 서버의 callback_url으로 {hub.mod, hub.chanllege, hub.verify_token}을  GET로 JSON 데이터를 전달하고 Webhook 서버에서 callback_url에 대한 응답(response)으로 {hub.chanllge} 값을 전달해야 합니다.
터미널에서 node index.js로 실행해주고 ngrok http 3000 로 외부 url을 발급받습니다.

 

$ curl -X POST https://www.strava.com/api/v3/push_subscriptions
-d client_id=11111
-d client_secret=f142a327164ecf843c45ffa
-d 'callback_url= https://6b9e-129-247.ngrok.io/webhook'
-d 'verify_token=STRAVA'

 

Subscription에 대한 Validation이 정상적으로 진행되었다면 그 결과로 Strava 서버에서는 Subscription ID를  최종적으로 응답을 해줍니다.

{
    "id": 9123314
}

 

 

 

 

 

 

여기까지 구독 생성과 세팅이 완료되었습니다.

 

이제 정상적으로 구독되는지 테스트 해보겠습니다.

 

위와 같이 구독용 활동을 생성했습니다.

 

 

서버에 위와 같이 새로 생성된 정보가 실시간으로 webhook으로 정상적으로 들어옵니다.
(단, 사용자의 정보 수정은 구독되지 않습니다.)

 

 

View a subscrption (생성된 구독 보기)

Strava 서버에 등록된 subscription을 https://www.strava.com/api/v3/push_subscriptions을 사용해서 확인할 수 있습니다.

 

curl -G https://www.strava.com/api/v3/push_subscriptions
-d client_id=11111
-d client_secret=f4asfdsafds

 

response

[
  {
    "id": ,
    "resource_state": 2,
    "application_id": ,
    "callback_url": " https://6b9e-125-132--.ngrok.io/webhook",
    "created_at": "2022-02-16T02:33:55+00:00",
    "updated_at": "2022-02-16T02:33:55+00:00"
  }
]

 

Delete a subscrption (생성된 구독 삭제)

 

curl -X DELETE https://www.strava.com/api/v3/push_subscriptions/212214
-d client_id=11111
-d client_secret=f4asfdsafds

 

구독하던것을 삭제를 해줍니다.

다시 확인했을때 응답값이 비어서 출력되므로 정상적으로 삭제되었습니다.