It's no secret to anyone that knows me: I bloody hate OAuth2. (I specifically say 2 because OAuth was a radically different beast.) I recently had occasion to use the Pocket API. I have very mixed feelings about this service, but I have paid for it before (for quite some time). Now I am trying to use the Kobo integration which syncs articles from Pocket. This seems a much better solution than Send to Kindle which I was previously using. However, to use it in practicality I had to somehow archive 5000+ links which I had imported into it, my ~10 year browser bookmark history.

I tried to use ChatGPT to generate this code, and it got something that looked very close but was in practicality useless. It was faster for me to write the code from scratch than to debug the famous LLM's attempt. So maybe don't retire your keyboard hands just yet, console jockeys.

import requests
from flask import Flask, redirect, session
import pdb

app = Flask(__name__)
app.secret_key = 'nonesuch'

CONSUMER_KEY = 'MYCONSUMERKEY'
REDIRECT_URI = 'http://localhost:5000/callback'
BATCH_SIZE = 1000    # max 5000

@app.route("/test")
def test():
    print("foo")


    resp = requests.post('https://getpocket.com/v3/oauth/request', json={
        'consumer_key': CONSUMER_KEY,
        'redirect_uri': REDIRECT_URI,
        'state': 'nonesuch',
    }, headers={'X-Accept': 'application/json'})
    data = resp.json()
    request_token = data['code']
    session['request_token'] = request_token


    uri = f'https://getpocket.com/auth/authorize?request_token={request_token}&redirect_uri={REDIRECT_URI}'

    return redirect(uri)



@app.route("/callback")
def callback():
    print("using request token", session['request_token'])
    resp = requests.post(
        'https://getpocket.com/v3/oauth/authorize',
        json={
            'consumer_key': CONSUMER_KEY,
            'code': session['request_token']
        },
        headers={'X-Accept': 'application/json'}
    )

    print("Status code for authorize was", resp.status_code)
    print(resp.headers)

    result = resp.json()
    print(result)
    access_token = result['access_token']
    print("Access token is", access_token)

    resp = requests.post(
        'https://getpocket.com/v3/get',
        json={
            'consumer_key': CONSUMER_KEY,
            'access_token': access_token,
            'state': 'unread',
            'sort': 'oldest',
            'detailType': 'simple',
            'count': BATCH_SIZE,
        }
    )
    x = resp.json()
    actions = []
    for y in x['list'].keys():
        actions.append({'action': 'archive', 'item_id': y})

    print("Sending", len(actions), "actions")

    resp = requests.post(
        'https://getpocket.com/v3/send',
        json={
            'actions': actions,
            'access_token': access_token,
            'consumer_key': CONSUMER_KEY
        }
    )
    print(resp.text)


    return f"<p>Access token is {access_token}</p>"

I believe it's mandatory to make this an actual web app, hence the use of Flask. I hate OAuth2. The Pocket implementation of OAuth2 is subtly quirky (what a freakin' surprise). Also, this API is pretty strange, it doesn't even make any attempt at being RESTful, though the operation batching is rather nifty. It's rather pleasant that you can work in batches of 1000 items at a time, though. I expected a lower limit. If I cranked the batch size up to 5000 I effectively KO'd the API and started getting 500s.

This script doesn't actually archive everything because it doesn't loop. That's left as an exercise for the reader for now.