※ 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>