diff --git a/src/Classes/ArtIndexerBot.ts b/src/Classes/ArtIndexerBot.ts index bef590c..42523fb 100644 --- a/src/Classes/ArtIndexerBot.ts +++ b/src/Classes/ArtIndexerBot.ts @@ -677,4 +677,19 @@ export class ArtIndexerBot { }) return projects } + + checkMintedOut(projectId: string, invocation: string) { + const projectBot = this.projectsById[projectId] + const invocationNumber = parseInt(invocation) + if ( + !projectBot || + !projectBot.editionSize || + projectBot.editionSize - 1 !== invocationNumber + ) { + return + } + console.log('SEND MINTED OUT MESSAGE') + + projectBot.sendMintedOutMessage() + } } diff --git a/src/Classes/MintBot.ts b/src/Classes/MintBot.ts index c8567bb..c4560ba 100644 --- a/src/Classes/MintBot.ts +++ b/src/Classes/MintBot.ts @@ -1,5 +1,5 @@ import { Client, EmbedBuilder, TextChannel } from 'discord.js' -import { mintBot, projectConfig } from '../index' +import { artIndexerBot, mintBot, projectConfig } from '../index' import axios, { AxiosError } from 'axios' import { MINT_UTM, @@ -56,23 +56,6 @@ export class MintBot { listener: true, }) } - if (process.env.HODLERS_TWITTER_API_KEY) { - const hodlerBot = new TwitterBot({ - appKey: process.env.HODLERS_TWITTER_API_KEY ?? '', - appSecret: process.env.HODLERS_TWITTER_API_SECRET ?? '', - accessToken: process.env.HODLERS_TWITTER_OAUTH_TOKEN ?? '', - accessSecret: process.env.HODLERS_TWITTER_OAUTH_SECRET ?? '', - }) - const holderContracts: string[] = [] - holderContracts.push( - PARTNER_CONTRACTS['HODLERS'], - PARTNER_CONTRACTS['HODLERS-PASS'] - ) - - holderContracts.forEach((contract: string) => { - this.contractToTwitterBot[contract] = hodlerBot - }) - } } } @@ -203,7 +186,13 @@ export class MintBot { } // Function to add a new mint to the queue! - addMint(contractAddress: string, tokenID: string, owner: string) { + addMint( + contractAddress: string, + tokenID: string, + owner: string, + invocation: string, + projectId: string + ) { console.log('NEW MINT', contractAddress, tokenID, owner) const id = `${contractAddress}-${tokenID}` @@ -217,6 +206,8 @@ export class MintBot { return } + artIndexerBot.checkMintedOut(projectId, invocation) + this.mintsToPost[id] = new Mint(this.bot, contractAddress, tokenID, owner) } diff --git a/src/Classes/ProjectBot.ts b/src/Classes/ProjectBot.ts index bac280c..aad0583 100644 --- a/src/Classes/ProjectBot.ts +++ b/src/Classes/ProjectBot.ts @@ -23,7 +23,7 @@ import { getRandomOobForProject, getToken, } from '../Data/queryGraphQL' -import { triviaBot } from '..' +import { CHANNEL_BLOCK_TALK, discordClient, triviaBot } from '..' import { ProjectConfig } from '../ProjectConfig/projectConfig' import { ProjectHandlerHelper } from './ProjectHandlerHelper' import { UpcomingProjectDetailFragment } from '../../generated/graphql' @@ -437,9 +437,7 @@ export class ProjectBot { }) // Send all birthdays to #block-talk - let channel = channels.get( - projectConfig.chIdByName['block-talk'] - ) as TextChannel + let channel = channels.get(CHANNEL_BLOCK_TALK) as TextChannel channel?.send({ embeds: [embedContent] }) if ( @@ -463,6 +461,33 @@ export class ProjectBot { return } + async sendMintedOutMessage() { + const blockTalk = discordClient.channels.cache.get( + CHANNEL_BLOCK_TALK + ) as TextChannel + + const artBlocksResponse = await axios.get( + getTokenApiUrl(this.coreContract, `${this.projectNumber * ONE_MILLION}`) + ) + const artBlocksData = await artBlocksResponse.data + const assetUrl = artBlocksData?.preview_asset_url + + // Send congratulations message + const title = `:tada: ${this.projectName} has minted out! Congratulations ${this.artistName}! :tada:` + const description = `Check out the whole collection [here](${ + getProjectUrl(this.coreContract, this.projectNumber.toString()) + + PROJECTBOT_UTM + })` + const embedContent = new EmbedBuilder() + .setColor('#9370DB') + .setTitle(title) + .setImage(assetUrl) + .setDescription(description) + if (blockTalk) { + blockTalk.send({ embeds: [embedContent] }) + } + } + async handleUpcomingMessage( msg: Message, upcomingDetails: UpcomingProjectDetailFragment diff --git a/src/index.ts b/src/index.ts index a154710..c027cb6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -65,7 +65,7 @@ const abXbmIndexerBot = new ArtIndexerBot(getArtBlocksXBMProjects) const CHANNEL_FACTORY = projectConfig.chIdByName['factory-projects'] // Block Talk -const CHANNEL_BLOCK_TALK = projectConfig.chIdByName['block-talk'] +export const CHANNEL_BLOCK_TALK = projectConfig.chIdByName['block-talk'] // PBAB Chat const CHANNEL_ENGINE_CHAT = projectConfig.chIdByName['engine-chat'] @@ -127,6 +127,8 @@ type MintEvent = { project_name: string token_id: string minted_at: string + invocation: string + project_id: string } } } @@ -145,7 +147,9 @@ app.post('/new-mint', function (req: any, res: any) { mintBot.addMint( mintData.contract_address, mintData.token_id, - mintData.owner_address + mintData.owner_address, + mintData.invocation, + mintData.project_id ) res.setHeader('Content-Type', 'application/json') res.json({ @@ -163,7 +167,7 @@ app.get('/callback', (req: any, res: any) => { }) // Bot setup. -const bot = new Client({ +export const discordClient = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, @@ -171,15 +175,15 @@ const bot = new Client({ ], }) if (PRODUCTION_MODE) { - bot.login(DISCORD_TOKEN) + discordClient.login(DISCORD_TOKEN) } -export const triviaBot = new TriviaBot(bot) -new ScheduleBot(bot.channels.cache, projectConfig) -bot.on('ready', () => { - console.info(`Logged in as ${bot.user?.tag}!`) +export const triviaBot = new TriviaBot(discordClient) +new ScheduleBot(discordClient.channels.cache, projectConfig) +discordClient.on('ready', () => { + console.info(`Logged in as ${discordClient.user?.tag}!`) }) -bot.on(Events.MessageCreate, async (msg) => { +discordClient.on(Events.MessageCreate, async (msg) => { const msgAuthor = msg.author.username const msgContent = msg.content const msgContentLowercase = msgContent.toLowerCase() @@ -222,7 +226,7 @@ bot.on(Events.MessageCreate, async (msg) => { console.error('Error handling number message: ', e) } // Handle special info questions that ArtBot knows how to answer. - const artBotID = bot.user?.id + const artBotID = discordClient.user?.id // TODO: refactor smartbotresponse to be less irritating / have fewer args smartBotResponse( msgContentLowercase, @@ -271,7 +275,7 @@ const initReservoirBots = async () => { new ReservoirListBot( `https://api.reservoir.tools/orders/asks/v5?contractsSetId=${contractSetID}&sortBy=createdAt&limit=${reservoirListLimit}&normalizeRoyalties=true`, API_POLL_TIME_MS, - bot, + discordClient, { Accept: 'application/json', 'x-api-key': process.env.RESERVOIR_API_KEY, @@ -292,7 +296,7 @@ const initReservoirBots = async () => { new ReservoirSaleBot( `https://api.reservoir.tools/sales/v4?${saleParams}&limit=${reservoirSaleLimit}`, API_POLL_TIME_MS + i * 3000, - bot, + discordClient, { Accept: 'application/json', 'x-api-key': process.env.RESERVOIR_API_KEY, @@ -301,7 +305,7 @@ const initReservoirBots = async () => { } } -export const mintBot = new MintBot(bot) +export const mintBot = new MintBot(discordClient) // Instantiate API Pollers (if not in test mode) if (PRODUCTION_MODE) {