LoginSignup
2
2

More than 3 years have passed since last update.

nuxtからGoogleカレンダーの予定を作る

Last updated at Posted at 2020-11-21

※ element ui使ってます

nuxtjs上でgoogle calendarに予定を作成する方法を勉強したのでqiitaにメモ
※もっと良いやり方があれば教えてください

以下インラインコメントで簡単に説明

add-event.vue
<template>
  <section>
    <el-button v-if="auth2 && !isLogined" @click="login" type="primary">
      ログイン
    </el-button>
    <el-button v-if="auth2 && isLogined" @click="logout" type="primary">
      ログアウト
    </el-button>
    <label>予定作成</label>
    <div v-if="auth2 && isLogined">
      <!-- 予定のある日をカレンダーで選ぶ -->
      <el-date-picker
        v-model="calendarDate"
        :picker-options="pickerOptionsFuture"
        type="date"
        format="yyyy/MM/dd"
      />
      <!-- 開始時間を8時から21時まで15分刻みで選ぶ -->
      <el-time-select
        v-model="calendarStartTime"
        :picker-options="{
          start: '08:00',
          step: '00:15',
          end: '21:00'
        }"
        placeholder="開始時間"
      >
      </el-time-select>
      <!-- 予定の継続時間を選ぶ -->
      <el-select v-model="calendarTerm" placeholder="継続時間">
        <el-option :value="15" label="15" />
        <el-option :value="30" label="30" />
        <el-option :value="45" label="45" />
        <el-option :value="60" label="60" />
        <el-option :value="75" label="75" />
        <el-option :value="90" label="90" />
        <el-option :value="105" label="105" />
        <el-option :value="120" label="120" />
      </el-select><!-- 予定の要約を記入する -->
      <el-input v-model="calendarSummray" placeholder="予定内容" />
      <el-button @click="addCalendar" type="primary">登録</el-button>
    </div>
  </section>
</template>

<script>
import moment from 'moment'

const SCOPE = 'https://www.googleapis.com/auth/calendar.events'
const CLIENT_ID = '<!-- gcp OAuth 2.0 クライアント ID -->'
const API_KEY = '<!-- firebase api key -->'
export default {
  head() {
    return {
      script: [{ hid: 'gapi', src: 'https://apis.google.com/js/client.js' }]
    }
  },
  data() {
    const isLogined = false
    const auth2 = undefined
    const pickerOptionsFuture = {
      disabledDate(time) {
        return moment(time).format('YYYY-MM-DD') < moment().format('YYYY-MM-DD')
      }
    }

    return {
      calendarDate: '',
      calendarStartTime: '',
      calendarTerm: '',
      calendarSummray: '',
      isLogined,
      auth2,
      pickerOptionsFuture
    }
  },
  async mounted() {
    // google apiが読み込まれるのを待つ
    while (!window.gapi || !window.gapi.auth2) {
      await new Promise(resolve => setTimeout(resolve, 10))
    }
    // google api auth2の初期化
    window.gapi.auth2.init({
      apiKey: API_KEY,
      client_id: CLIENT_ID,
      scope: SCOPE,
      immediate: true
    })
    this.auth2 = window.gapi.auth2.getAuthInstance()

    // ログイン済みかチェック
    if (this.auth2.isSignedIn.get()) {
      this.isLogined = true
    }

    // カレンダーの初期化
    window.gapi.load('client')
    window.gapi.client.init({
      discoveryDocs: [
        'https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'
      ],
      scope: SCOPE,
      apiKey: API_KEY,
      clientId: CLIENT_ID
    })
    window.gapi.client.load('calendar', 'v3')
  },
  methods: {
    async login() {
      if (this.auth2.isSignedIn.get()) {
        this.isLogined = true
        return
      }
      await this.auth2.signIn()
      this.isLogined = true
    },
    logout() {
      this.auth2.signOut()
      this.isLogined = false
    },
    addCalendar() {
      // ガードブロック
      if (!this.auth2.isSignedIn.get()) {
        this.$message({
          message: 'ログインしてください',
          type: 'error'
        })
        return
      }
      if (!this.calendarDate) {
        this.$message({
          message: '日付を選択してください',
          type: 'error'
        })
        return
      }
      if (!this.calendarStartTime) {
        this.$message({
          message: '開始時間を選択してください',
          type: 'error'
        })
        return
      }
      if (!this.calendarTerm) {
        this.$message({
          message: '期間を選択してください',
          type: 'error'
        })
        return
      }
      if (!this.calendarSummray) {
        this.$message({
          message: '予定内容を入力してください',
          type: 'error'
        })
        return
      }

      // 予定開始時刻・終了時刻を作る
      const eventDate = moment(this.calendarDate).format('YYYY-MM-DD')
      const eventFrom = this.calendarStartTime + ':00'
      const eventTo = moment(this.calendarStartTime, 'HH:mm')
        .add(this.calendarTerm, 'minutes')
        .format('HH:mm:00')
      const event = {
        summary: this.calendarSummray,
        start: {
          dateTime: `${eventDate}T${eventFrom}+09:00`,
          timeZone: 'Asia/Tokyo' // time zoneを日本にする
        },
        end: {
          dateTime: `${eventDate}T${eventTo}+09:00`,
          timeZone: 'Asia/Tokyo' // time zoneを日本にする
        },
        recurrence: [],
        attendees: [],
        reminders: {
          useDefault: false,
          overrides: [
            { method: 'email', minutes: 24 * 60 }, // 1日前にリマインドメール
            { method: 'popup', minutes: 10 } // 10分前にリマインドノーティフィケーション
          ]
        }
      }
      // 予定作成
      const request = window.gapi.client.calendar.events.insert({
        calendarId: 'primary',
        resource: event
      })
      request.execute(() => {
        this.$message({
          message: 'カレンダー登録しました。',
          type: 'success'
        })
      })
    }
  }
}
</script>
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2