<html>

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Twitch-Bot Authorization</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/combine/npm/bootstrap@4/dist/css/bootstrap.min.css,npm/bootstrap-vue@2/dist/bootstrap-vue.min.css,npm/bootswatch@4/dist/darkly/bootstrap.min.css">

  <div id="app">
    <b-container>
      <b-row>
        <b-col>

          <b-jumbotron
            class="mt-4"
            header="Twitch-Bot Authorization"
            lead="Get a Twitch Auth-Token for your bot easily"
          >

            <template v-if="token">
              <label for="token">Your <code>--twitch-token</code>:</label>
              <b-form-input id="token" v-model="token" type="text" readonly />
            </template>

            <template v-else>
              <p>In case you haven't done this yet you need to create an Application for your bot:</p>
              <ol class="mb-3">
                <li>Go to <a href="https://dev.twitch.tv/console/apps">https://dev.twitch.tv/console/apps</a></li>
                <li>
                  Register a new Application with these properties:
                  <ul>
                    <li><strong>Name:</strong> Choose any you like</li>
                    <li><strong>OAuth Redirect URLs:</strong> <code>{{ redirURL }}</code></li>
                    <li><strong>Category:</strong> Chat Bot</li>
                  </ul>
                </li>
              </ol>
              <p>After you've completed the steps above, copy your <strong>Client ID</strong> (do <strong>NOT</strong> copy your Client Secret) below and click the button:</p>
              <b-input-group class="mb-3">
                <b-form-input v-model="clientId" placeholder="Application Client Id"></b-form-input>
                <b-input-group-append>
                  <b-button :href="authURL" :disabled="!authURL" variant="success">Get OAuth Token now!</b-button>
                </b-input-group-append>
              </b-input-group>

              <div class="accordion" role="tablist">
                <b-card no-body class="mb-1">
                  <b-card-header header-tag="header" class="p-1" role="tab">
                    <b-button block v-b-toggle.detailconfig variant="secondary">
                      Let me customize the scopes!
                    </b-button>
                    <b-collapse id="detailconfig" accordion="detailconfig" role="tabpanel">
                      <b-card-body>

                        <p>I want my bot to be able to&hellip;</p>

                        <b-form-checkbox
                          :disabled="scope.required"
                          :key="scope.scope"
                          v-for="scope in scopeList"
                          v-model="scope.enabled"
                        >
                          <span
                            :title="scope.scope"
                            v-html="`&hellip;${scope.description}`"
                          ></span>
                        </b-form-checkbox>

                      </b-card-body>
                    </b-collapse>
                  </b-card-header>
                </b-card>
              </div>

              <hr>
              <p><strong>Security Hint:</strong> This website has no code to send your Client-ID or Access-Token to any place other than Twitch. Even though you should ensure you trust it before using as Twitch will send an AccessToken with following scopes here:</p>
              <p><code>{{ scopes }}</code></p>
              <p>For more information about the scopes see these two pages: <a href="https://dev.twitch.tv/docs/irc/guide">IRC Guide</a> and <a href="https://dev.twitch.tv/docs/authentication#scopes">API Scopes</a>
            </template>

          </b-jumbotron>

        </b-col>
      </b-row>
    </b-container>
  </div>

  <script src="https://cdn.jsdelivr.net/combine/npm/vue@2,npm/bootstrap-vue@2/dist/bootstrap-vue.min.js"></script>
  <script>
    new Vue({
      computed: {
        authURL() {
          if (!this.clientId) {
            return null
          }

          const params = {
            client_id: this.clientId,
            redirect_uri: this.redirURL,
            response_type: 'token',
            scope: this.scopes,
          }

          const paramString = Object.keys(params).map(k => [k, params[k]].join('=')).join('&')
          return `https://id.twitch.tv/oauth2/authorize?${paramString}`
        },

        scopes() {
          return this.scopeList
            .filter(scope => scope.enabled)
            .map(scope => scope.scope.split(' ')) // Split is required, some entries have multiple scopes
            .flat()
            .sort((i, j) => i.localeCompare(j))
            .join(' ')
        },

        redirURL() {
          return window.location.href
        }
      },

      data: {
        clientId: null,
        scopeList: [
          {
            description: 'read chat messages',
            enabled: true,
            required: true,
            scope: 'chat:read',
          },
          {
            description: 'send messages to the chat',
            enabled: true,
            required: true,
            scope: 'chat:edit',
          },
          {
            description: 'read messages sent as whispers',
            enabled: true,
            scope: 'whispers:read',
          },
          {
            description: 'send whispers',
            enabled: true,
            scope: 'whispers:edit',
          },
          {
            description: 'use moderation chat-commands like <code>/ban, /clear, /delete, /timeout</code>',
            enabled: true,
            scope: 'channel:moderate',
          },
          {
            description: 'use channel editor chat-commands like <code>/host, /marker, /raid</code>',
            enabled: true,
            scope: 'channel_editor',
          },
          {
            description: 'manage my channel’s broadcast configuration (title, game, &hellip;), stream markers and stream tags',
            enabled: true,
            scope: 'channel:manage:broadcast',
          },
          {
            description: 'run commercials on my channel',
            enabled: false,
            scope: 'channel:edit:commercial channel_commercial',
          },
          {
            description: 'manage Channel Points custom rewards and their redemptions on my channel',
            enabled: false,
            scope: 'channel:manage:redemptions channel:read:redemptions',
          },
          {
            description: 'create Clips on my channel',
            enabled: false,
            scope: 'clips:edit',
          },
        ],
        token: null,
      },

      el: '#app',

      mounted() {
        const hashParams = new URLSearchParams(window.location.hash.substr(1))
        if (hashParams.has('access_token')) {
          this.token = hashParams.get('access_token')
        }
      },
    })
  </script>

</html>