dblock / slack-strava

(Re)Post Strava activities to Slack
https://slava.playplay.io
MIT License
37 stars 6 forks source link

Suggestion: segment records #113

Open Eothred opened 3 years ago

Eothred commented 3 years ago

I wrote my own little python script to report to our slack running channel every time someone got on the top list in one of the segments close to our office. I think this could be a good idea for this app as well if possible, to select a segment to track which would report something like "{name} just ran {segment} in {time}, reaching {placement} place on leaderboard".

dblock commented 3 years ago

Sounds cool. How does your script work? Maybe share the code under a permissive license? We can talk about how to integrate that workflow here.

Eothred commented 3 years ago

Sure. My script is quite simple with hardcoded segment list and only reporting to one specific channel. I also don't think it works after they changed the API so I've stopped my integration. I give it LGPL 3 so you can use it (let me know if you need more formal hand-over, but it is just a small script in the end):

import requests
import json
import os
import datetime
from time import strftime
from time import gmtime

STRAVA_CLIENT_ID = os.environ['STRAVA_CLIENT_ID']
STRAVA_CLIENT_SECRET = os.environ['STRAVA_CLIENT_SECRET']
STRAVA_REFRESH_TOKEN = os.environ['STRAVA_REFRESH_TOKEN']

SLACK_API_KEY = os.environ['SLACK_API_KEY']
SLACK_URL = os.environ['SLACK_WEBHOOK_URL']

STRAVA_API_URL = 'https://www.strava.com/api/v3'
STRAVA_HEADER = {'Authorization': 'Bearer null'}

TXT_RANK = {1: "first", 2: "second", 3: "third", 4: "fourth", 5: "fifth", 6: "sixth"}
entries = {}
if os.path.exists('leaderboards.json'):
    entries = json.load(open('leaderboards.json', 'r'))

athletes = {}
if os.path.exists('athletes.json'):
    athletes = json.load(open('athletes.json', 'r'))

def get_segment(segment):
    url = f'{STRAVA_API_URL}/segments/{segment}/leaderboard'
    res = requests.get(url=url, headers=STRAVA_HEADER)
    data = res.json()
    url2 = f'{STRAVA_API_URL}/segments/{segment}'
    res2 = requests.get(url=url2, headers=STRAVA_HEADER)
    data2 = res2.json()
    data["name"] = data2["name"]

    return data

def get_athlete(athlete):
    url = '{}/athletes/{}'.format(STRAVA_API_URL, athlete)
    res = requests.get(url=url, headers=STRAVA_HEADER)
    data = res.json()

    return data

def refresh_strava_token():
    global STRAVA_HEADER
    data = {"client_id": STRAVA_CLIENT_ID,
            "client_secret": STRAVA_CLIENT_SECRET,
            "grant_type": "refresh_token",
            "refresh_token": STRAVA_REFRESH_TOKEN}
    res = requests.post('https://www.strava.com/api/v3/oauth/token', json=data)
    STRAVA_API_KEY = res.json()['access_token']
    STRAVA_HEADER = {'Authorization': f'Bearer {STRAVA_API_KEY}'}

if __name__ == "__main__":

    refresh_strava_token()

    for SEGMENT in [<list of segment ID's>]:
        data = get_segment(SEGMENT)

        previous = []
        if str(SEGMENT) in entries:
            previous = entries[str(SEGMENT)]
        print(data)
        for i in range(len(data['entries'])):
            rank = i+1
            entry = data['entries'][i]
            del entry['rank']

            if entry not in previous:
                previous.append(entry)
                if entry['elapsed_time'] < 3600:
                    t = strftime('%Mm%Ss', gmtime(entry['elapsed_time']))
                else:
                    t = strftime('%Hh%Mm%Ss', gmtime(entry['elapsed_time']))

                if rank < 6:
                    msg = "{} just ran <https://www.strava.com/segments/{}|{}> in {}, reaching {} place on the leaderboard".format(entry['athlete_name'], SEGMENT, data['name'], t, TXT_RANK[rank])
                    print(msg)
                    blocks = {"blocks": [{"text": {"type": "mrkdwn", "text": msg}, "type": "section"}]}
                    headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}

                    requests.post(url=SLACK_URL, json=blocks, headers=headers)

        entries[str(SEGMENT)] = previous

    open('leaderboards.json', 'w').write(json.dumps(entries, indent=2, sort_keys=True))