피라미드

30896 단어 discordnodetypescript

A discord bot for making pyramids!



이봐! Node.js, TypeScript 및 Discord의 JS API를 사용하여 다음과 같은 피라미드 봇을 만들 것입니다.



Discord 및 JavaScript의 기본 사항에 이미 익숙하다고 가정합니다. 시작하자!

1단계: 상용구



가장 먼저 할 일은 프로젝트를 위한 새 디렉토리를 만드는 것입니다. 실행하려는 몇 가지 명령은 다음과 같습니다.

# Clone a boilerplate for Node.JS
git clone https://github.com/safinsingh/node-ts.git pyramid

# Reset source control
rm -rf .git
git init

# Install dependencies
{pnpm/[yarn]/npm} install

이 상용구의 디렉토리 구조를 자세히 살펴보겠습니다.

.
├── .eslintignore     (linting ignores)
├── .eslintrc         (linting config)
├── .github           (continuous integration)
│  └── workflows
│     ├── format.yml
│     └── lint.yml
├── .gitignore        (source control ignores)
├── .prettierignore   (formatting ignores)
├── .prettierrc       (formatting config)
├── package.json      (package metadata)
├── src               (code)
│  └── index.ts
├── tsconfig.json     (typescript config)
└── yarn.lock         (package lockfile)

완벽한! 이제 모든 파일과 디렉토리가 필요하다는 것을 알았으므로 필요한 종속성 중 일부를 설치해 보겠습니다.

{pnpm/[yarn]/npm} install discord.js dotenv
discord.js에는 JavaScript용 Discord API 모듈과 TypeScript용 유형이 포함되어 있으며 dotenv는 소스 제어에 게시하지 않고 Discord API 키를 로드하기 위한 것입니다.

2단계: Discord 봇 설정



먼저 discord.com에 Discord 계정이 없으면 생성합니다. 그런 다음 Discord developer portal으로 이동하여 새 앱을 만듭니다.



거기에서 Bot 탭을 누르고 봇 토큰을 복사합니다.



그런 다음 다음과 같이 Pyramid 디렉토리 내의 .env 파일에 복사하여 붙여넣기만 하면 됩니다.

TOKEN=YOUR-SUPER-SECURE-TOKEN-HERE

그러나 상용구에서 .env 파일은 기본적으로 무시되지 않습니다. .gitignore 파일을 편집하고 다음과 같이 .env를 추가하여 이 문제를 해결할 수 있습니다.

echo ".env" >> .gitignore

또는 텍스트 편집기로 열고 이를 통해 변경합니다.

마지막으로 OAuth2 탭으로 이동하여 scopesbot이고 허가 비트가 67584인 URL을 생성하여 서버에 추가합니다.



이것을 브라우저에 복사하기만 하면 서버에 봇을 추가할 수 있습니다! 지금은 오프라인 상태이므로 먼저 설정하지 않습니다.

3단계: Hello World!



봇을 시작하고 실행하려면 다음을 index.ts 파일에 추가해 보겠습니다.

// Imports dotenv and discord modules
import dotenv from 'dotenv'
import Discord from 'discord.js'

// Read config from .env and login to the Discord API
dotenv.config()
const client = new Discord.Client()
client.login(process.env.TOKEN)

// Listen for a 'ready' event and execute a callback when it's fired
client.on('ready', () => {
  console.log('Ready!')
})

// Listen for a 'message' event and execute a callback when it's fired
client.on('message', (msg) => {
  const channel = msg.channel as Discord.TextChannel
  channel.send('Hi there!')
})

완벽한! 이제 {pnpm/[yarn]/npm} dev를 실행하여 서버를 시작할 수 있습니다. 우리의 봇은 활성화되어 있고 우리가 메시지를 보낼 때마다 답장을 보내야 합니다!

4단계: 오류 처리



이제 봇을 실행할 수 있으므로 피라미드를 만들기 시작해야 합니다!

그 전에 사용자가 입력한 명령을 읽고 유효성을 검사해 보겠습니다.

// Useful constants
const content = msg.content.split(' ')
const channel = msg.channel as Discord.TextChannel

// If the message starts with /pyramid
if (content[0] === '/pyramid') {
  // Get the size of the pyramid and the repeatable text
  const size = parseInt(content[1])
  const toRepeat = content.slice(2).join(' ')

  // Validate our message
  const valid = isValid(msg)
  if (!valid.isValid) {
    // If not valid, tell them!
    msg.reply(valid.error)
    msg.react(valid.reaction as Discord.EmojiResolvable)
    return
  }

  // Generate a pyramid from the text and size
  const toSend = genPyramid(toRepeat, size)

  // Send the message and catch an error
  channel.send(toSend).catch((err) => msg.reply(err))
}

isValid에서 봇 남용을 방지하기 위해 몇 가지 기능(isValid 기능)을 추가할 예정입니다.

// Create an interface for what a validCheck should look like
// Errors and reactions should be optional and only present if isValid is false
interface validCheck {
  isValid: boolean
  error?: string
  reaction?: Discord.EmojiResolvable
}

// Determine whether the message will overflow the 2000 character limit imposed by Discord
const willOverflow = (msgArr: Array<string>): boolean => {
  // Get the height of the pyramid
  const iter = parseInt(msgArr[1]) + 1

  // iter * (iter - 1) is the same thing as 2 * (n + (n - 1) + ... 1)
  if (iter * (iter - 1) * msgArr.slice(2).join(' ').length > 1000) {
    return true
  }
  return false
}

// Determine is a message is valid, and return a validCheck object
export const isValid = (msg: Discord.Message): validCheck => {
  const msgArr = msg.content.split(' ')

  // Make sure all the required arguments are present
  if (msgArr.length < 3) {
    console.log('1')
    return {
      isValid: false,
      error: 'Invalid command, must have at least 3 arguments!',
      reaction: '🗑️',
    }
    // Ensure that the height of the pyramid is actually a number
  } else if (isNaN(parseInt(msgArr[1]))) {
    return {
      isValid: false,
      error: 'Invalid number, must be an integer!',
      reaction: '🗑️',
    }
  } else {
    // Create a temporary storage variable
    let toReturn: validCheck = {
      isValid: true,
    }

    // Loop through words to be pyramidified
    msg.content
      .split(' ')
      .slice(1)
      .forEach((e) => {
        // Prevent disallowed keywords
        if (e === '/pyramid') {
          toReturn = {
            isValid: false,
            error: 'Recursiveness is not allowed!',
            reaction: '😡',
          }
        } else if (e === '͔') {
          toReturn = {
            isValid: false,
            error: "Sorry, but that character doesn't work :(",
            reaction: '😔',
          }
        }
      })

    // If the message is invalid, return the temporary variable containing the most recent error
    if (!toReturn.isValid) {
      return toReturn
    }

    // Prevent character overflow
    if (willOverflow(msgArr)) {
      return {
        isValid: false,
        error: 'Whoops! Looks like that exceeds the maximum characters!',
        reaction: '😔',
      }
    } else {
      // Return correct message!
      return {
        isValid: true,
      }
    }
  }
}

5단계: 피라미드 만들기



드디어 피라미드를 만들 준비가 되었습니다! 이것은 봇의 가장 간단한 부분입니다. 다음 알고리즘을 살펴보겠습니다.

// Define a pyramid generator with arguments for the repeater and the pyramid size
export const genPyramid = (toRepeat: string, size: number): string => {
  let toSend = ''

  for (let i = 0; i <= size; i++) {
    // For line in pyramid
    for (let z = 0; z < i; z++) {
      // For entry in line
      toSend += `${toRepeat} ` // Append to sending variable
    }
    toSend += '\n' // Create newline between pyramid rows
  }
  return toSend
}

그러면 다음과 같은 패턴이 생성됩니다.

1
1 1
1 1 1
1 1 1 1
1 1 1 1 1

자세히 살펴보면 각 행의 1 의 수가 행 번호와 같다는 것을 알 수 있습니다.

Row 1: 1          (1 column)
Row 2: 1 1        (2 columns)
Row 3: 1 1 1      (3 columns)
Row 4: 1 1 1 1    (4 columns)
Row 5: 1 1 1 1 1  (5 columns)

파트 6: 모두 합치기



마지막으로 모든 유틸리티 기능을 완료했으므로 실제 기능을 봇 자체에 통합해 보겠습니다. 다음은 index.ts 파일에 추가한 몇 가지 개선된 변경 사항입니다.

import dotenv from 'dotenv'
import Discord from 'discord.js'

// Abstract utility functions
import { isValid, genPyramid } from './util'

dotenv.config()
const client = new Discord.Client()
client.login(process.env.TOKEN)

// Set bot activity
client.on('ready', () => {
  console.log('Ready!')
  client?.user?.setActivity('making sideways pyramids')
})

client.on('message', (msg) => {
  const content = msg.content.split(' ')
  const channel = msg.channel as Discord.TextChannel

  // Root checker
  if (content[0] === '/pyramid') {
    const size = parseInt(content[1])
    const toRepeat = content.slice(2).join(' ')

    const valid = isValid(msg)
    if (!valid.isValid) {
      msg.reply(valid.error)
      msg.react(valid.reaction as Discord.EmojiResolvable)
      return
    }

    // Create toSend
    const toSend = genPyramid(toRepeat, size)

    // Send the final message and catch an error
    channel
      .send(toSend)
      .catch((err) =>
        msg.reply(
          `Nice! It looks like you've successfully hacked the Pyramid! Feel free to pen a pull request :). BTW, the error was: ${err}`
        )
      )
  }
})

우후 🎉! 드디어 피라미드 봇을 완성했습니다! 이제 마음에 들면 마무리 작업을 더 추가하고 개인화할 수 있습니다!



제안 사항이 있거나 피라미드 버전을 공유하고 싶다면 이슈를 열거나 github.com/safinsingh/pyramid에 요청을 가져오십시오.

다음 단계


  • 중앙, 거꾸로 또는 오른쪽을 향한 피라미드 만들기
  • 다른 명령 추가(예: help/info 명령)
  • 가능성은 무한합니다! 재미있게 보내세요 :)
  • 좋은 웹페이지 즐겨찾기