비 프로그래머의 친구와 놀 수있는 Discord Bot을 Go로 만들어 보았다.

최근 화제의 Discord Bot을 만들어 보았으므로, 논프로그래머의 친구와 놀 수 있는 Discord Bot라는 명목으로 공개했습니다.
기주 b. 코 m / 아이모 f / ぢ s 또는 t 에 소스를 MIT 라이센스로 게시 중입니다.

데모





하루의 시작은 인사부터!

그래서 문서에 미리 정해 놓은 랜덤 응답을 돌려줍니다.

기능


  • 인구 무능하게 정해진 단어를 트리거에 정해진 대답을 돌려주는 기능.
  • 발언수에 따라 레벨이 올라가는 기능(아래)



  • 레벨이 올라가거나 내려가는 이유는 docker 스토리지 지속성에 실패하기 때문입니다.

    어느 쪽이 비 프로그래머와 함께 즐길 수 있습니까?



    무려 이 봇, 대사를 Google SpreadSheet에서 편집할 수 있도록 했습니다. (자동 배포가 아직 없으므로 수동으로 CSV를 이식해야합니다)

    설정 파일은 이런 느낌



    도서관



    라이브러리로도 이용할 수 있어 간단하게 위의 기능만 돌려주게 되어 있습니다.

    기술적인 다양한



    기술면에서 생각한 것을 써 갑니다. 별로 어려운 일은 하지 않기 때문에 쓰는 일이 많지 않을지도 모릅니다.

    라이브러리 메인



    discat.go
    package discat
    
    type Discat struct {
        speaker speaker
        level   level
    }
    
    func Init(dict [][]string, expMap map[string]int) Discat {
        return Discat{
            speaker: newSpeaker(dict),
            level:   level{exp: expMap},
        }
    }
    
    func (d Discat) Speak(input string) string {
        return d.speaker.speak(input)
    }
    
    func (d Discat) GainExp(name string, exp int) {
        d.level.gainExp(name, exp)
    }
    
    func (d Discat) ShowLevel(name string) (exp, level, rest int) {
        return d.level.showLevel(name)
    }
    
    func (d Discat) Output() map[string]int { return d.level.output() }
    

    Go처럼 쓰는 것을 의식하면 이렇게 되었습니다만, 이것으로 좋은 것일까… 라이브러리는 단순히 문자열을 받고 문자열과 숫자를 반환하는 단순한 것으로 만들었습니다. 그 이상의 기능은 명령 측에서 구현

    인터럽트를 받는 일반적인 알레



    main.go
    ch := make(chan os.Signal, 1)
    signal.Notify(ch, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
    _ = <-ch
    err = session.Close()
    if err != nil {
        log.Fatalln(err)
    }
    // 正常終了処理
    

    인터럽트 시그널로부터 세션을 정상적으로 종료시키는 녀석입니다.

    말하는 부분은 어리석게 구현



    speaker.go
    func (s speaker) speak(sentenceIn string) string {
        for key, value := range s.table {
            if strings.Contains(sentenceIn, key) {
                return value[rand.Intn(len(value))]
            }
        }
        return ""
    }
    

    들어온 문장에 대해, 가지고 있는 단어와 쓰고 있는 개소가 있으면, 대응하는 리스폰스를 리턴합니다.
    같은 문언에서도 대사가 바뀌어 즐길 수 있습니다.

    table이라는 필드명의 map이 있는 것은 기분 나쁘네요… (지금 알아차렸다)

    docker-compose에서 볼륨을 마운트할 수 없는 문제


    FROM golang:1.10.3-alpine
    
    LABEL maintainer "aimof <[email protected]>"
    
    RUN apk update --no-cache && \
        apk add --no-cache git && \
        go get -u github.com/golang/dep/cmd/dep
    
    COPY . /go/src/github.com/aimof/discat/
    WORKDIR /go/src/github.com/aimof/discat/cmd/discat/
    
    RUN dep ensure && \
        go build
    
    CMD ./discat
    

    docker-compose.yml
    version: "3"
    services:
      discat:
        build: .
        volumes:
          - /home/ubuntu/discat/cmd/discat/data:/go/src/github.com/aimof/discat/cmd/discat/data
        logging:
          options:
            max-size: "10m"
            max-file: "5"
    volumes:
      data:
    

    리포지토리를 ubuntu 사용자 홈 바로 아래에 두는 가정으로, 이런 docker-compose.yml 를 썼습니다만, 왠지 볼륨의 마운트에 실패. 로컬에서는 성공했지만…

    요약



    Discord 봇 개발 재미 있습니다. 프로그램 걸지 않는 친구도 대사를 생각하는 곳이라면 참가해 주실 수 있으므로, 만약 흥미 있으면 이용해 보세요.
    덧붙여 아직 프로토 단계이므로, 아직 사용하기 어렵습니다. 조금씩 개선하겠습니다.

    좋은 웹페이지 즐겨찾기