2020-11-08 22:24:49 -05:00
/* eslint-disable no-continue */
2020-10-31 02:27:41 -04:00
import type { AxiosError , AxiosStatic } from 'axios' ;
2020-10-30 22:33:21 -04:00
import axios from 'axios' ;
import { Member , Message } from 'eris' ;
import { Client , Command , RichEmbed } from '../class' ;
export default class Apply extends Command {
2020-10-31 02:27:41 -04:00
public services : Map < string , { description : string , type : ' HARD ' | ' SOFT ' , url : string , validation : ( ...cond : any ) = > Promise < boolean > | boolean , func? : Function } > ;
2020-10-30 22:33:21 -04:00
constructor ( client : Client ) {
super ( client ) ;
this . name = 'apply' ;
this . description = 'apply' ;
2020-11-08 22:24:49 -05:00
this . usage = ` ${ this . client . config . prefix } apply [serviceName] \ n ${ this . client . config . prefix } apply full ` ;
2020-10-30 22:33:21 -04:00
this . permissions = 0 ;
this . guildOnly = true ;
this . enabled = true ;
this . setServices ( ) ;
}
protected setServices() {
this . services = new Map ( ) ;
this . services . set ( 'role::constants' , {
description : 'Constants role assignment.' ,
2020-10-31 02:27:41 -04:00
type : 'HARD' ,
2020-10-30 22:33:21 -04:00
url : 'https://eds.libraryofcode.org/roles/constants' ,
validation : ( member : Member ) = > ! member . roles . includes ( '511771731891847168' ) ,
func : async ( client : Client , . . . data : any [ ] ) = > {
2020-10-31 02:27:41 -04:00
const member = await client . guilds . get ( client . config . guildID ) . getRESTMember ( data [ 0 ] ) ;
await member . addRole ( '511771731891847168' , 'Constants Approval from EDS' ) ;
2020-10-30 22:33:21 -04:00
} ,
} ) ;
2020-10-31 02:27:41 -04:00
this . services . set ( 'cs::t2' , {
description : 'Tier 2 upgrade for Cloud Services account.' ,
type : 'HARD' ,
url : 'https://eds.libraryofcode.org/cs/t2' ,
2020-10-31 02:36:36 -04:00
validation : ( member : Member ) = > member . roles . includes ( '546457886440685578' ) ,
2020-10-31 02:27:41 -04:00
func : async ( client : Client , . . . data : any [ ] ) = > {
const member = await client . guilds . get ( client . config . guildID ) . getRESTMember ( data [ 0 ] ) ;
const ax = < AxiosStatic > require ( 'axios' ) ;
await ax ( {
method : 'get' ,
2020-11-10 13:15:06 -05:00
url : ` https://api.cloud.libraryofcode.org/wh/t2?userID= ${ member . id } &auth= ${ client . config . internalKey } ` ,
2020-10-31 02:27:41 -04:00
} ) ;
} ,
} ) ;
2020-11-08 07:21:34 -05:00
this . services . set ( 'cs::promot3' , {
description : 'Receive 25% off your first purchase of Tier 3.' ,
type : 'SOFT' ,
url : 'https://eds.libraryofcode.org/cs/t3-promo' ,
validation : async ( member : Member ) = > {
if ( ! member . roles . includes ( '546457886440685578' ) ) return false ;
const customer = await this . client . db . Customer . findOne ( { userID : member.user.id } ) . lean ( ) . exec ( ) ;
if ( ! customer ) return false ;
return true ;
} ,
func : async ( client : Client , . . . data : any [ ] ) = > {
const member = await client . guilds . get ( client . config . guildID ) . getRESTMember ( data [ 0 ] ) ;
const customer = await client . db . Customer . findOne ( { userID : member.user.id } ) . lean ( ) . exec ( ) ;
const coupon = await client . stripe . coupons . create ( {
percent_off : 25 ,
duration : 'once' ,
max_redemptions : 1 ,
name : 'Tier 3 - EDS Discount' ,
2020-11-08 07:30:10 -05:00
metadata : {
userID : member.user.id ,
} ,
2020-11-08 07:21:34 -05:00
} ) ;
const promo = await client . stripe . promotionCodes . create ( {
coupon : coupon.id ,
customer : customer.cusID ,
max_redemptions : 1 ,
restrictions : {
first_time_transaction : true ,
} ,
} ) ;
2020-11-09 23:55:10 -05:00
const doc = new client . db . Promo ( {
code : promo.code ,
pID : promo.id ,
} ) ;
await doc . save ( ) ;
2020-11-08 07:21:34 -05:00
const chan = await client . getDMChannel ( customer . userID ) ;
chan . createMessage ( ` __**Tier 3 Coupon Code**__ \ n \` ${ promo . code } \` \ n \ n*Do not share this promotional code with anyone else. This promo code is good for your first purchase of Tier 2, 25% off applied. Will apply to your first invoice only, for more questions contact support.* ` ) ;
} ,
} ) ;
2020-11-01 07:11:16 -05:00
this . services . set ( 'p::role::constants' , {
description : 'Pre-approval for Constants role assignment.' ,
type : 'SOFT' ,
url : 'https://eds.libraryofcode.org/roles/preconstants' ,
validation : ( member : Member ) = > ! member . roles . includes ( '511771731891847168' ) ,
} ) ;
2020-10-31 23:46:49 -04:00
this . services . set ( 'p::cs::t2' , {
2020-10-31 02:27:41 -04:00
description : 'Pre-approval for Tier 2.' ,
type : 'SOFT' ,
2020-10-31 23:46:49 -04:00
url : 'https://eds.libraryofcode.org/cs/t2pre' ,
validation : ( member : Member ) = > member . roles . includes ( '546457886440685578' ) ,
2020-10-31 02:27:41 -04:00
} ) ;
2020-10-30 22:33:21 -04:00
}
public async run ( message : Message , args : string [ ] ) {
try {
2020-11-08 22:24:49 -05:00
if ( ! args [ 0 ] || args [ 0 ] === 'full' ) {
2020-10-30 22:33:21 -04:00
const embed = new RichEmbed ( ) ;
2020-11-08 22:24:49 -05:00
embed . setTitle ( 'Instant Application Service [IAS]' ) ;
embed . setColor ( '#556cd6' ) ;
if ( args [ 0 ] !== 'full' ) {
2020-11-12 20:37:24 -05:00
embed . setDescription ( ` *These applications are specifically targeted to you based on validation conditions. Run \` ${ this . client . config . prefix } apply full \` for a full list of all applications.* ` ) ;
2020-11-08 22:24:49 -05:00
embed . setThumbnail ( message . member . avatarURL ) ;
embed . setAuthor ( message . member . username , message . member . avatarURL ) ;
}
2020-10-30 22:33:21 -04:00
for ( const service of this . services ) {
2020-11-08 22:24:49 -05:00
// eslint-disable-next-line no-await-in-loop
const test = await service [ 1 ] . validation ( message . member ) ;
if ( ! test && args [ 0 ] !== 'full' ) continue ;
2020-10-31 23:46:49 -04:00
embed . addField ( service [ 0 ] , ` **Description**: ${ service [ 1 ] . description } \ n**Inquiry Type:** ${ service [ 1 ] . type } \ n \ n*Run \` ${ this . client . config . prefix } apply ${ service [ 0 ] } \` to apply.* ` ) ;
2020-10-30 22:33:21 -04:00
}
2020-11-09 23:55:10 -05:00
if ( embed . fields ? . length <= 0 ) embed . setDescription ( ` *We have no offers for you at this time. To see a full list of offers, please run \` ${ this . client . config . prefix } apply full \` .* ` ) ;
2020-10-30 22:33:21 -04:00
embed . setFooter ( this . client . user . username , this . client . user . avatarURL ) ;
embed . setTimestamp ( ) ;
return message . channel . createMessage ( { embed } ) ;
}
if ( ! this . services . has ( args [ 0 ] ) ) return this . error ( message . channel , 'Invalid service/product name.' ) ;
const service = this . services . get ( args [ 0 ] ) ;
const test = await this . services . get ( args [ 0 ] ) . validation ( message . member ) ;
if ( ! test ) return this . error ( message . channel , 'A condition exists which prevents you from applying, please try again later.' ) ;
const msg = await this . loading ( message . channel , 'Thank you for submitting an application. We are currently processing it, you will be pinged here shortly with the decision.' ) ;
2020-10-31 23:46:49 -04:00
return await this . client . queue . processApplication ( { channelID : message.channel.id , guildID : this.mainGuild.id , messageID : msg.id } , service . url , message . author . id , service . func ? service . func . toString ( ) : undefined ) ;
2020-10-30 22:33:21 -04:00
} catch ( err ) {
return this . client . util . handleError ( err , message , this ) ;
}
}
public static async apply ( client : Client , url : string , userID : string ) {
try {
const { data } = await axios ( {
method : 'get' ,
url : ` ${ url } ?userID= ${ userID } &auth= ${ client . config . internalKey } ` ,
} ) ;
return {
status : 'SUCCESS' ,
decision : data.decision ,
2020-10-31 23:46:49 -04:00
id : data.id ,
processedBy : data.processedBy ,
2021-01-12 02:14:22 -05:00
token : data.token ,
2020-10-30 22:33:21 -04:00
} ;
} catch ( err ) {
const error = < AxiosError > err ;
2020-10-31 23:46:49 -04:00
if ( error . response ? . status === 404 || error . response . status === 400 || error . response . status === 401 ) return { id : 'N/A' , processedBy : 'N/A' , status : 'CLIENT_ERROR' , decision : 'PRE-DECLINED' } ;
return { id : 'N/A' , processedBy : 'N/A' , status : 'SERVER_ERROR' , decision : 'PRE-DECLINED' } ;
2020-10-30 22:33:21 -04:00
}
}
}