Coder Social home page Coder Social logo

ghostrider-05 / patreon-api.ts Goto Github PK

View Code? Open in Web Editor NEW
4.0 1.0 1.0 618 KB

Typescript library for the Patreon V2 API

Home Page: https://patreon-api.pages.dev

License: MIT License

TypeScript 98.94% JavaScript 1.06%
patreon patreon-api patreon-wrapper oauth patreon-client webhook-server typescript

patreon-api.ts's Introduction

Patreon-api.ts

npm npm GitHub issues GitHub stars

Typescript library for the V2 Patreon API with Typescript types that strongly reflect your request.

// query: attributes[campaign]=title
const payload = await client.fetchCampaign(query)
    // ^? { data: { attributes: { title: string } }, ... }

Installation

npm install patreon-api.ts
pnpm add patreon-api.ts
yarn add patreon-api.ts

Usage

Caution

This package does not include v1 of the Patreon API and starts with API v2

The default API version for this package is 2 and might change in major versions. When the default API version is changed, old versions will still receive updates. You can not import this module by API version since it is unlikely that Patreon will release a new version any time soon.

import { type Campaign } from 'patreon-api.ts';

While some features are highlighted below, you can read more in the documentation. Still doubting if this library has everything you need related to the Patreon API? Compare all libraries yourself.

Compatibility

To check for compatibility with this package, look if your platform:

  • has the globals: AbortController, setTimeout, clearTimeout, fetch, URL and URLSearchParams
  • supports ES2020
  • supports createHmac of the node:crypto module

[!WARNING] This is a server-side API & Oauth package and requires your application tokens. Make sure you do not share or expose your tokens or run this code client-side.

Clients

Creator token

If you don't need to handle Oauth2 requests, but only your own creator profile, the first example will get you started. It is recommended to sync your token to your database or store it somewhere safe, so the token is not lost.

Example
import { PatreonCreatorClient, PatreonStore } from 'patreon-api.ts'

const creatorClient = new PatreonCreatorClient({
    oauth: {
        clientId: process.env.PATREON_CLIENT_ID!,
        clientSecret: process.env.PATREON_CLIENT_SECRET!,
        // Either set the token in the options
        // or configure a store and call <Client>.initialize()
        token: {
            access_token: process.env.PATREON_CREATOR_ACCESS_TOKEN!,
            refresh_token: process.env.PATREON_CREATOR_REFRESH_TOKEN!,
        },
    },
    store: new PatreonStore.Fetch('<url>'),
})

User oauth2

For handling Oauth2 requests, add redirectUri and if specified a state to the options. Then fetch the token for the user with request url. Note that for handling Oauth2 requests the client will not cache or store the tokens anywhere in case you need to refresh it!

Example
import { PatreonUserClient } from 'patreon-api.ts'

// Minimal configuration for handling Oauth2
const userClient = new PatreonUserClient({
    oauth: {
        clientId: process.env.PATREON_CLIENT_ID!,
        clientSecret: process.env.PATREON_CLIENT_SECRET!,
        redirectUri: '<uri>',
    }
})

export default {
    // The Oauth2 callback request with the code parameter
    fetch: async (request) => {
        const instance = await userClient.createInstance(request)
        await instance.fetchIdentity(<query>)
    }
}

Store

There are 3 built-in methods of retreiving and storing tokens:

  1. Manual loading and storing, see the example below
  2. Fetch: use an external server that accepts GET and PUT requests
  3. KV: store the (creator) token in a KV-like storage system (present on a lot of edge-runtimes).
Example
// Use stored tokens in a database
// And directly call the `store.get` method on starting the client
const storeClient = new PatreonCreatorClient({
    oauth: {
        clientId: process.env.PATREON_CLIENT_ID!,
        clientSecret: process.env.PATREON_CLIENT_SECRET!,
    },
    name: '<application>', // The application name in the dashboard
    store: {
        get: async () => {
            // Get your stored token
            return <never>{
                access_token: '<token>',
                //...refresh, expires, etc.
            }
        },
        put: async (token) => {
            console.log(JSON.stringify(token))
        }
    }
})

Webhooks

You can interact with the webhooks API using one of the clients above. This library also exposes functions to create a webhook server.

Example
import { parseWebhookRequest } from 'patreon-api.ts'

export default {
    async fetch (request, env) {
        const { verified, payload, event } = await parseWebhookRequest(request, env.WEBHOOK_SECRET)
        if (!verified) return new Response('Invalid request', { status: 403 })

        // handle your event
    }
}

Examples

Changelog

Detailed changes are listed for each release in the changelog.

For upcoming releases, see the roadmap for planned changes.

Contributing

See the code of conduct and the contributing guide for how to contribute. You can also support the development by writing guides, posts and templates or by funding the maintainers.

License

MIT

patreon-api.ts's People

Contributors

clonex avatar dependabot[bot] avatar ghostrider-05 avatar github-actions[bot] avatar igoodie avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

clonex

patreon-api.ts's Issues

Campaign members is of type never

For the campaign members the included property is of type never[].

const membersQuery = buildQuery.campaignMembers(['user', 'currently_entitled_tiers'])({
    member: ['patron_status'],
})
const members = await client.fetchOauth2(Oauth2Routes.campaignMembers('<id>'), membersQuery)

if (members != undefined) {
    // Filter all but tiers
    const tiers = members.included
        .filter((item): item is AttributeItem<Type.Tier, typeof item['attributes']> => item.type === Type.Tier)

    console.log(tiers[0].attributes)
}

Webhook Types

It is an amazing effort you have done, thanks for taking your time and writing the types out!

It would be amazing to have the types for Webhook Resource and Webhook Endpoints as well.

Thanks a lot for your time once again ๐ŸŽ‰

Add support for testing payloads / sandbox

Feature

Since the official response from Patreon is to test it yourself by paying to your own campaigns, a library method that does not require paying would be preferred.

Solution

  • create payloads (pluggable with popular sample data packages)
  • send payloads to the client / different client
  • add extra property to check if it is a sandbox event; client must opt-in to be able to listen to sandbox events to not make any mistakes
  • add methods to send example webhooks (including webhook posts which is not possible in the portal)

Draft API

const client = new <Client>({
    oauth: {
       // Allow sandboxed Oauth Users
       sandbox: true,
    },
    store: {
       // By default the store will not receive any request related to a sandbox
       // even if all other sandbox options are enabled
       sandbox: true,
    },

    rest: {
       // Enable sandbox for all payloads or only certain routes
        sandbox: boolean | string[] | { route: string, method?: string }[]
    }
})

// Used for sandboxed webhook events
function isSandboxEvent (event: RequestPayload): boolean {}

function getScopesForRoutes (routes: { path: string, query: Query }[]): string[] {}

interface PatreonSandboxOptions {
  client: <Client>
  createRandom<Type>()?: Type // Type can be: User, Campaign, Post, Tier, etc.
  createRandomName()?: string
  // All sandbox ids will have a prefix
  createRandomId()?: string
  
  idPrefix?: string // defaults to `sandbox-api-`
  cachedEvents?: number
}

class PatreonSandbox {
   public constructor (options: PatreonSandboxOptions) {}
   public events: (RequestPayload & library_sandbox: true)[]
   
   public send (event: RequestPayload, client?: <Client>): Promise<void>
   
   public oauth: {
        createToken (code?: string, client?: <Client>): Promise<object>
        refreshToken (updatedToken: object, valid: boolean | Date, client?: <Client>): Promise<void>
   }
   
   public rest: {
      request (route: string, options: { status: number, method?: string }): Promise<void>
      
   }
   
   public createPayload (route: string, method?: string, data?: SandboxDataOptions): RequestPayload
   
   public webhooks: {
        createPayload(trigger: PatreonWebhookTrigger, data?: SandboxDataOptions): RequestPayload
        send (uri: string, trigger: PatreonWebhookTrigger, payload: RequestPayload, headers?: object): Promise<Response>
   }
}

Alternative solutions

No response

Additional context

No response

Create a documentation site

Feature

As this library will have more features the readme of the repo will become quite large

Solution

A (static) documentation http://patreon-api-docs.pages.dev with:

API pages:

  • Oauth: creator & user clients
  • Webhooks: Webhook API and webhook servers

Library pages:

  • Why?
  • Installation
  • Getting started
  • Wrapper: simplified responses
  • Storing keys (using the client.store option)
  • Testing events

Interactive pages:

  • API Requests

App pages (external):

  • Webhooks
  • Discord bot

Official pages:

  • Official Docs (external)
  • Official Dev forum (external)
  • Dev Discord channel (external)

Alternative solutions

No response

Additional context

No response

Simplify payloads

Feature

Add a wrapper to simplify the payloads from Patreon.

Solution

  • A method to 'simplify' payloads, like function simplify<Payload>(payload: Payload): WrappedResponse<Payload>
  • Classes to interact with wrapped payloads exposing methods and getters
  • Implement wrapped variants of all current methods

Alternative solutions

No response

Additional context

No response

Change Oauth2 client

  • remove the client-oauth2 dependency (and the severity vulnerabilities with it)
  • simplify the multiple token interfaces
  • add tests for oauth2

Create apps built using this library

Feature

N/A

Solution

Standalone apps:

  • Discord PatreonRole bot:
    - manage multiple campaigns / guild
    - update member roles on pledges *
    - include option for free members
    - sync posts to a channel / forum:
    - option to update post messages
    - option to choose embed / normal message
    - option to choose embed color, footer
    - add test commands:
    - trigger test post
    - trigger new member (option to choose user to test on)
    - trigger deleting member (same options for new user test)

  • Cloudflare Webhook pages site:

    • login to Cloudflare and view all your campaigns + their webhooks *
    • add new webhooks (for every event)
    • add test events for every event
    • add option to send events in the dashboard
    • view logs for past events
  • Patreon Dashboard template

    • routes for login, logout, user
    • methods for showing data related to the logged in user
    • = currently supported by Patreon

Alternative solutions

No response

Additional context

No response

Update GitHub repository

Add:

  • funding
  • contributing guide
  • code of conduct
  • issue templates
  • pull request template

Look into:

  • changelog automation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.