상대방이 임무를 완수하기 전에 귀신 의식을 지속하는 슬랙 앱을 만들었다.이미아무도 재촉하지 않고 해결할 수 있는 세상을 원한다...

슬랙 앱'penpen'을 만들었어요.


https://penpen.netlify.app/

이런 인상

  • slash 명령을 통해 시작합니다./penpen 이후 알림 내용과 엉덩이를 치고 싶은 대상을 지정
  • image.png
  • 이상
  • 상대방은 이렇게 보여요.


    image.png 終わった를 클릭하면 알림 색인 목록에서 삭제됩니다.겸사겸사 알림을 설정한 상대방에게 "미션 완성!"의 알림
    image.png
    사용법은 이런 느낌이에요.

    시간을 자세히 지정할 수 있습니다.


    지정every 3 hoursevery 2 days 등을 통해 엉덩이를 두드리는 주기를 선택할 수 있다.
    image.png
    가장 짧게는 매시간 상대방에게 펜 한 자루를 줄 수 있다.

    누구나 지정할 수 있습니다.


    한 리마 안에서 여러 사람을 지목할 수도 있다.당분간 영어 대응도 있기 때문에 슬랙의 언어 설정은 일본어 이외라면 영어로 엉덩이를 때린다.

    하고 싶은 배경.


    사례 1: 자신의 지시를 잊어버리다


    엔지니어: 저기, 디자이너님, 이 화면의 디자인을 확인해 주세요.
    디자이너: "알겠습니다."
    엔지니어: "제발 부탁해요."
    (3시간 후)
    엔지니어: 아, 그 설계 확인
    디자이너: 아, 잊어버렸어요. 금방 할게요.
    엔지니어: "제발 부탁해요."
    (1시간 후)
    엔지니어: 그게...
    디자이너: 아

    사례 2: 상대방의 지시를 잊어버리다


    엔지니어: "네, 데려다 주세요."
    기획사 "알겠습니다. 그럼 내일 결과를 알려주세요."
    엔지니어
    (내일)
    기획 "그 일은 어떻게 됐나요?"
    엔지니어

    사례 3: 자신의 지시를 잊어버리다


    엔지니어: 아, 큰일났다. 여기 일지를 조사해야겠어. 트롤로를 쓰는 건 귀찮아. 슬랙의reminder나 스마트폰 알람기도 설정해야 돼."
    (내일)
    로그 조사 중
    엔지니어: "지금 밥 먹고 이따가 해요."
    (3일 후)
    엔지니어
    .
    .
    .
    ...나는 이미 다른 사람에게 재촉을 받지 않아도 되고, 재촉하지 않아도 해결할 수 있는 세상이 되고 싶다...
    그래서 우리는 익숙한 슬랙을 떠나지 않고 상대방이 임무를 완수하기 전까지 땅끝까지 쫓아다니며 엉덩이를 두드리기로 했다.

    프로비저닝

  • 인프라: heroku, Cloud Scheduller, Pub/Sub, Cloud Function
  • 백엔드: node.js, TypeScript, express, bolt
  • 안내데스크:nuxt.js, netlify
  • 뱀발: 최근nuxt접근진정한 SSG
  • 제작 기간

  • 약 3일(16시간)
  • 환경 구축: 1시간
  • API: 13시간
  • 단일 테스트: 5시간
  • 기능 설치: 8시간
  • FE: 1시간
  • 슬랙의 설정: 1시간
  • 구조


  • 부팅bolt
  • 처음에 볼트는'이 슬라쉬 지령과 일반적인 REST 단점이 어떻게 공존하는가'에 푹 빠졌는데, 이런 느낌은expressReceiver를 얻으면 해결할 수 있다.
    import { App, ExpressReceiver } from '@slack/bolt'
    
    const receiver = new ExpressReceiver({ signingSecret: config.SLACK_SIGNING_SECRET })
    const app = new App({
      token: config.SLACK_BOT_TOKEN,
      receiver
    })
    
    receiver.router.get('/task', getTaskAndUpdatedSendAtHandler(app, conn)) // 普通のREST
    app.command(config.SLASH_COMMAND_NEW_TASK, slashPostTaskHandler(app, conn)) // slashコマンド
    app.action(ACTIONS.buttonClick, deleteTaskHandler(app, conn)) // ボタンクリック時などのaction
    
    app.start(config.PORT)
    
    볼트를 사용하면 listen slack의 대화 내용, 예를 들어'이거 부탁해'라는 단어에 반응할 수 있고, 펜펜펜 발언 같은 기능도 간단하게 만들 수 있어 향후 대화성을 위해 볼트를 적용했다.

    작업 게시


  • Slack을 기다리는 Slash Command
    slash Command는 기본적으로 API의/slack/events 단점에서 받아들여지는 형식으로 위boltapp.command('hoge')를 사용하면/hoge에 반응한다.

  • 분석 발언AI 분석 발언...아니요.정규 표현식이 일치합니다.every 12 hours면 12시간마다, every 3 months면 3개월마다 등 조정기의 주기를 결정한다

  • 작업 저장
    TypeORM.
  • oauth 인증


    사용자의 동작(slash 명령과 단추를 누르는 것)만 응답하면 이벤트 발생 시 파라미터에 포함된 say()를 호출하면 충분하지만 자신의 적극적인 발언ウェイ 유형의bot은 oauth 인증이 필요합니다.제가 이걸 준비할게요.
    참고로 슬랙은 현재 두 개의 oauth 인증 절차가 있습니다(매우 번거롭습니다)
    이 분은 전임자입니다. https://api.slack.com/legacy/oauth
    이분은 현역: https://api.slack.com/authentication/oauth-v2
    잘못된 문서를 읽지 않도록 주의해라!
  • SlackApp을 만든 후 관리 화면에'분배 관리'를 누르면 끼워 넣을 수 있는 버튼
  • 을 얻을 수 있다.
    image.png
  • LP 등에 이 버튼을 설정합니다
  • image.png

  • 이 단추를 누르면 사용자는 slack의 oauth 인증 화면으로 이동하여 인증한 후 지정한 목적지로 되돌아갑니다.이 때 URL의 조회는 code, state 로 부여되어 이 항목을 가져옵니다.
  • nuxt는 SSG의 경우 asyncData 등의 이유로 query에 접근할 수 없기 때문에 mounted 등부득이하게 방문하다에 있다.(시간을 아끼며 제대로 조사하지 못했다)
  • code, state 자신이 준비한 API 엔드포인트

  • API 측에는 방금 취득한 https://slack.com/api/oauth.v2.access,code,clientId 등이 포함돼 발송clientSecret.
  • 이때 필요한 정보는 지정application/jsonapplication/x-www-form-urlencoded 중 어느 것에 따라 달라집니다주의.

  • 아까 내가 필요하다고 했잖아state?그것은 거짓말이다
  • 이렇게 말하면 좀 과장되지만 state는 부정행위를 막기 위해 자체적으로 대조한 것이기 때문에 무시해도 문제가 발생하지 않는다.잠시 페페에 대해 대조를 진행하였다.
  • https://slack.com/api/oauth.v2.access로부터 온 응답에는 슬랙teamId, teamName, accessToken가 포함되어 있기 때문에 DB에 저장합니다.accessToken은 앞으로bolt의postMessage를 실행할 때 사용자의 slack 작업 공간에서 교환에 사용
  • 작업 알림


  • Cloud Scheduer->Pub/Sub->Cloud Function 프로세스에서 API를 정기적으로 두드려 작업 전송(알림)

  • 슬랙blockKit로 조립 정보
  • "끝났어!"단추를 눌렀을 때'어떤 작업','누가 끝났는지'를 파악하기 위해 누름단추의value에 각종 id
  • 를 미리 기입합니다
  • image.png

  • 편지를 보내다
  • 이후에 볼트app.client.chat.postMessage()로 보내주세요.위의 Outh 인증을 통해 획득한 액세스 토큰
  • slack 메시지에서 완료된 작업 삭제


  • bolt 사용client.chat.update

  • 여기 주의가 필요할 것 같습니다.과거의 슬랙 메시지를 삭제할 때 다음과 같은 정보가 필요합니다
  • channelId
  • timestamp
  • accessToken
  • タイムスタンプ가 없으면 업데이트는 정보를 식별할 수 없습니다.메시지 ID 같은 거 없나요?내 생각에는 시간 스탬프를 사용한 것 같다.이제 됐지?

  • 버튼을 눌렀을 때 온전한 정보를 보내서 삭제하고 싶은 정보를 찾아내서 업데이트합니다
  • BlockKit 복잡한 정보라면 Type Script로 Parse를 하는 게 어려울 것 같은데 적당히筋肉(any) 사기를 쳤어
  • 자신에게 할당된 작업 목록 가져오기

  • /penpen-list의 사선 명령을 연결시켜 자신의 임무를 일람하고 발송하는 기능이 있는데 이게 맞나요.../penpen는 변화가 거의 없어서 할애
  • 단일 테스트

  • 개인 개발이라 아무도 보지 않았고, 고장이 두려워 테스트는 대략 60% 정도의 커버물을 적었다.
  • 나는 무슨 소용이 있는지 모르겠다.jest mock out을 사용하는 곳에만 참고로 쓴다
  • import { App } from '@slack/bolt'
    jest.mock('@slack/bolt', () => {
      return {
        App: jest.fn().mockImplementation(() => {
          return {
            client: {
              chat: {
                postMessage: jest.fn(),
                update: jest.fn()
              }
            }
          }
        })
      }
    })
    
    const app = new App() // あとはモック化されてるので煮るなり焼くなりご自由に
    
  • 그나저나 제스트의 경우 nodemodules와 같은 등급에 __mocks__/@slack/bolt.js을 세우고 그 중에서 모듈자동 마운트을 미리 정의했다면jest로 명확하게 나타낸다.모크()라고 할 필요도 없고, 매번 테스트 파일의 모듈을 다시 정의할 필요도 없다. 간단하다
  • 이상


    이상은 기본적인 페페의 구성입니다.
  • 퀘스트 유출을 방지하고 싶어
  • 주변을 재촉하느라 힘들었다
  • 그런 분들은 꼭 사용해 보세요.
    (그리고 고장나면 가볍게 알려주세요...)
    https://penpen.netlify.app/

    좋은 웹페이지 즐겨찾기