How can I read file in Next js server api?

261 views Asked by At

I'm using nextjs 14 and making a function to create events in Google Calendar. I need to authenticate.

The problem occurs when I try to read the contents of the credentials.json file. This works in simple nodejs project but not in nextjs project

I tried to put this file in the root of project, close to service which use it, in .next directory.

Where should I put credentials.json? Or what am I doing wrong?

File location: app/api/_services/calendarService.ts

My code

    const fs = require('fs').promises
    import path from 'path'
    import process from 'process'
    import { authenticate } from '@google-cloud/local-auth'
    import { google } from 'googleapis'
    
    const SCOPES = ['https://www.googleapis.com/auth/calendar']
    const TOKEN_PATH = path.join(process.cwd(), 'token.json')
    const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json')
    
    export class CalendarService {
      private async loadSavedCredentialsIfExist() {
        try {
          const content = await fs.readFile(TOKEN_PATH)
          const credentials = JSON.parse(content)
          return google.auth.fromJSON(credentials)
        } catch (err) {
          return null
        }
      }
    
      private async saveCredentials(client: any) {
        const content = await fs.readFile(CREDENTIALS_PATH)
        const keys = JSON.parse(content)
        const key = keys.installed || keys.web
        const payload = JSON.stringify({
          type: 'authorized_user',
          client_id: key.client_id,
          client_secret: key.client_secret,
          refresh_token: client.credentials.refresh_token,
        })
        await fs.writeFile(TOKEN_PATH, payload)
      }
    
      private async authorize() {
        let client: any = await this.loadSavedCredentialsIfExist()
        if (client) {
          return client
        }
        client = await authenticate({
          scopes: SCOPES,
          keyfilePath: CREDENTIALS_PATH,
        })
        if (client?.credentials) {
          await this.saveCredentials(client)
        }
        return client
      }

      public makeEvent() {
        this.authorize().then(async (auth) => {
          // await this.insertEvent(auth)
        }).catch(console.error)
      }
    }

I get next error

Error: Cannot find module '/Users/username/Documents/Projects/projectname/credentials.json'
        at webpackEmptyContext (/Users/username/Documents/Projects/projectname/.next/server/app/api/(routes)/email/route.js:22:10)
        at authenticate (webpack-internal:///(rsc)/./node_modules/@google-cloud/local-auth/build/src/index.js:47:114)
        at CalendarService.authorize (webpack-internal:///(rsc)/./app/api/_services/calendarService.ts:53:94) {
      code: 'MODULE_NOT_FOUND'
    }
0

There are 0 answers