UNPKG

meetup-token

Version:

An Ethereum ERC20 compatible token for members of a meetup.com group

201 lines (168 loc) 7.09 kB
// there is no type definition file for the meetup-api module so the following will error import * as MeetupApi from 'meetup-api'; import * as VError from 'verror'; import {extractEthAddress} from './ethUtils'; import * as logger from 'config-logger'; export interface MemberAddress {id: number, name: string, address: string} declare type MeetupProfile = { id: number, name: string, group_profile: { intro?: string} }; declare type MeetupApi = { getMemberProfiles: (options: object, callback: (err: Error, members: MeetupProfile[]) => void) => void, getGroup: (options: object, callback: (err: Error, rsvps: {members: number}) => void) => void, getEventRSVPs: (options: object, callback: (err: Error, rsvps: {rsvps: object[]}) => void) => void }; export default class Meetup { readonly meetup: MeetupApi; pageSize: number = 200; apiLimit: number = 5; memberNumber: number; extractAddressFromText: (text: string)=> string | void = extractEthAddress; constructor(readonly apiKey: string, readonly urlname: string) { this.meetup = new MeetupApi({key: apiKey}); logger.debug(`Instantiated MeetupApi`); } getMemberNumbers(): Promise<number> { const self = this; return new Promise<number>( (resolve: (memberNumer: number) => void, reject: any) => { self.meetup.getGroup({ 'urlname': this.urlname }, function(err: Error, response: {members: number}) { if (err) { const error = new VError(`Get member numbers for meetup ${self.urlname} returned error: ${err}`); logger.error(error.stack); return reject(error); } else { logger.info(`${response.members} members in the ${self.urlname} group`); self.memberNumber = response.members; resolve(response.members); } }); } ); } async extractMemberAddresses(): Promise<MemberAddress[]> { const self = this; let memberAddresses: MemberAddress[] = []; try { const members = await this.getMemberNumbers(); const pages = Math.round(members / this.pageSize); for(let page = 0; page <= pages; page++) { const newMemberAddresses = await self.extractMemberAddressesFromPage(page); memberAddresses = memberAddresses.concat(newMemberAddresses); } return memberAddresses; } catch(err) { const error = new VError(err, `could not extract member addresses`); logger.error(error.stack); throw error; } } private extractMemberAddressesFromPage(offset: number): Promise<MemberAddress[]> { const self = this; return new Promise<MemberAddress[]>((resolve: (result?: MemberAddress[]) => void, reject: (error: Error) => void) => { this.meetup.getMemberProfiles({ 'urlname': this.urlname, "page": this.pageSize, "offset": offset }, function(err: Error, memberProfiles: MeetupProfile[]) { if (err) { const error = new VError(`Get member profiles for meetup ${self.urlname}, page ${this.page} and offset ${offset} returned error: ${err}`); logger.error(error.stack); return reject(error); } else { logger.trace(memberProfiles); logger.info(`${memberProfiles.length} members returned for page offset ${offset} and page size ${self.pageSize}`); let memberAddresses: MemberAddress[] = []; memberProfiles.forEach((memberProfile) => { const memberAddress = self.getMemberAddressFromProfile(memberProfile); if (memberAddress) { logger.debug(`Address ${memberAddress.address} belongs to member with id ${memberAddress.id} and name ${memberAddress.name} `); memberAddresses.push(memberAddress); } else { logger.debug(`no address for member with id ${memberProfile.id}, name ${memberProfile.name} and intro ${memberProfile.group_profile.intro}`); } }); resolve(memberAddresses); } }); }); } private getMemberAddressFromProfile(memberProfile: MeetupProfile): void | MemberAddress { if (memberProfile && memberProfile.group_profile && memberProfile.group_profile.intro) { const address = this.extractAddressFromText(memberProfile.group_profile.intro); if (address) { return { id: memberProfile.id, name: memberProfile.name, address: address }; } } } getMembersAtEvent(event_id: number): Promise<string[]> { const self = this; const description = `event RSVPs for ${self.urlname} Meetup event with id ${event_id}`; return new Promise<string[]>((resolve: (result?: string[]) => void, reject: (err: Error) => void) => { self.meetup.getEventRSVPs({ 'urlname': self.urlname, "event_id": event_id }, function(err: Error, rsvps: object[]) { if (err) { const error = new VError(`Get ${description} returned error: ${err}`); logger.error(error.stack); return reject(error); } else if (!rsvps || !Array.isArray(rsvps)) { const error = new VError(`Get ${description} did not return a response that was an Array`); logger.error(error.stack); return reject(error); } else { logger.trace(rsvps); logger.debug(`Returned ${rsvps.length} ${description}`); const rsvpMembers: string[] = []; rsvps.forEach(rsvp => { if (rsvp.response == 'yes' && rsvp.member && rsvp.member.id ) { rsvpMembers.push(rsvp.member.id.toString()); } }); logger.debug(`${rsvpMembers.length} ${description}`); resolve(rsvpMembers); } }); }); } }