import * as rpc from "discord-rpc" ; import fetch from "node-fetch" ; import { URLSearchParams } from "url" ; export interface DiscordRpcConfig { clientId : string ; clientSecret : string ; accessToken ? : string ; refreshToken ? : string ; redirectUrl ? : string ; expireTime ? : number ; } export async function createLoginData ( client , config , scopes ) { await client . connect ( config . clientId ) ; const redirectUrl = config . redirectUrl === undefined ? "http://127.0.0.1" : config . redirectUrl ; if ( config . accessToken === undefined || config . refreshToken === undefined || config . expireTime === undefined ) { const authorizeResult = await client . request ( "AUTHORIZE" , { client_id : config . clientId , scopes : scopes } ) ; const response = await fetch ( "https://discord.com/api/oauth2/token" , { method : "POST" , headers : { "Content-Type" : "application/x-www-form-urlencoded" } , body : encodeQuery ( { client_id : config . clientId , client_secret : config . clientSecret , grant_type : "authorization_code" , code : authorizeResult . code , redirect_uri : redirectUrl , scope : scopes . join ( " " ) } ) } ) ; const data = await response . json ( ) ; if ( "error" in data ) throw new Error ( "error_description" in data ? data . error_description : "Unknown discord rpc login error" ) ; config . accessToken = data . access_token ; config . refreshToken = data . refresh_token ; config . expireTime = data . expires_in + Date . now ( ) / 1000 - 1000 ; } else if ( config . expireTime < Date . now ( ) / 1000 ) { const response = await fetch ( "https://discord.com/api/oauth2/token" , { method : "POST" , headers : { "Content-Type" : "application/x-www-form-urlencoded" } , body : encodeQuery ( { client_id : config . clientId , client_secret : config . clientSecret , grant_type : "refresh_token" , refresh_token : config . refreshToken , redirect_uri : redirectUrl , scope : scopes . join ( " " ) } ) } ) ; const data = await response . json ( ) ; if ( "error" in data ) throw new Error ( "error_description" in data ? data . error_description : "Unknown discord rpc refresh error" ) ; config . accessToken = data . access_token ; config . refreshToken = data . refresh_token ; config . expireTime = data . expires_in + Date . now ( ) / 1000 - 1000 ; } return { clientId : config . clientId , clientSecret : config . clientSecret , redirectUri : redirectUrl , scopes : scopes , accessToken : config . accessToken } ; } function encodeQuery ( query ) { const params = new URLSearchParams ( ) ; for ( const key in query ) { params . append ( key , String ( query [ key ] ) ) ; } return params ; }