8 changed files with 157 additions and 3 deletions
@ -0,0 +1,34 @@ |
|||
'use strict'; |
|||
|
|||
/** @type {import('sequelize-cli').Migration} */ |
|||
module.exports = { |
|||
async up (queryInterface, Sequelize) { |
|||
const transaction = await queryInterface.sequelize.transaction(); |
|||
try { |
|||
await queryInterface.addColumn( |
|||
'Users', |
|||
'googleId', |
|||
{ |
|||
type: Sequelize.STRING, |
|||
allowNull: true, |
|||
}, |
|||
{ transaction } |
|||
); |
|||
await transaction.commit(); |
|||
} catch (err) { |
|||
await transaction.rollback(); |
|||
throw err; |
|||
} |
|||
}, |
|||
|
|||
async down (queryInterface, Sequelize) { |
|||
const transaction = await queryInterface.sequelize.transaction(); |
|||
try { |
|||
await queryInterface.removeColumn('Users', 'googleId', { transaction }); |
|||
await transaction.commit(); |
|||
} catch (err) { |
|||
await transaction.rollback(); |
|||
throw err; |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,39 @@ |
|||
// auth/google.strategy.ts
|
|||
import { Injectable } from '@nestjs/common'; |
|||
import { PassportStrategy } from '@nestjs/passport'; |
|||
import { Strategy, VerifyCallback } from 'passport-google-oauth20'; |
|||
import { ConfigService } from '@nestjs/config'; |
|||
import { UsersService } from '../users/users.service'; |
|||
import { User } from '../../models/user.model'; |
|||
|
|||
@Injectable() |
|||
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { |
|||
constructor( |
|||
private readonly configService: ConfigService, |
|||
private readonly usersService: UsersService, |
|||
) { |
|||
super({ |
|||
clientID: configService.get<string>('GOOGLE_CLIENT_ID'), |
|||
clientSecret: configService.get<string>('GOOGLE_CLIENT_SECRET'), |
|||
callbackURL: configService.get<string>('GOOGLE_CALLBACK_URL'), |
|||
scope: ['email', 'profile'], |
|||
}); |
|||
} |
|||
|
|||
async validate( |
|||
accessToken: string, |
|||
refreshToken: string, |
|||
profile: any, |
|||
done: VerifyCallback, |
|||
): Promise<any> { |
|||
const { id, name, emails } = profile; |
|||
const user: Partial<User> = { |
|||
googleId: id, |
|||
email: emails[0].value, |
|||
name: name.givenName + ' ' + name.familyName, |
|||
}; |
|||
|
|||
const userFromDb = await this.usersService.findOrCreate(user); |
|||
done(null, userFromDb); |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
// google-sheets/google-sheets.service.ts
|
|||
import { Injectable } from '@nestjs/common'; |
|||
import { google, sheets_v4 } from 'googleapis'; |
|||
import { ConfigService } from '@nestjs/config'; |
|||
|
|||
@Injectable() |
|||
export class GoogleSheetsService { |
|||
private sheets: sheets_v4.Sheets; |
|||
|
|||
constructor(private readonly configService: ConfigService) { |
|||
const auth = new google.auth.OAuth2( |
|||
this.configService.get<string>('GOOGLE_CLIENT_ID'), |
|||
this.configService.get<string>('GOOGLE_CLIENT_SECRET'), |
|||
this.configService.get<string>('GOOGLE_CALLBACK_URL'), |
|||
); |
|||
this.sheets = google.sheets({ version: 'v4', auth }); |
|||
} |
|||
|
|||
async getSheetData(spreadsheetId: string, range: string) { |
|||
const response = await this.sheets.spreadsheets.values.get({ |
|||
spreadsheetId, |
|||
range, |
|||
}); |
|||
return response.data.values; |
|||
} |
|||
|
|||
async updateSheetData(spreadsheetId: string, range: string, values: any[]) { |
|||
const response = await this.sheets.spreadsheets.values.update({ |
|||
spreadsheetId, |
|||
range, |
|||
valueInputOption: 'RAW', |
|||
requestBody: { |
|||
values, |
|||
}, |
|||
}); |
|||
return response.data; |
|||
} |
|||
|
|||
async createSheet(title: string): Promise<string> { |
|||
const request = { |
|||
requestBody: { |
|||
properties: { |
|||
title, |
|||
}, |
|||
}, |
|||
}; |
|||
const response = await this.sheets.spreadsheets.create(request); |
|||
return response.data.spreadsheetId; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue