51 |
52 |
57 |
58 | Home
59 |
60 |
65 |
66 | Docs
67 |
68 |
69 |
70 |
71 |
72 |
73 | Todo List App
74 |
75 |
76 |
77 | This app was developed to demonstrate how to use{' '}
78 |
79 | gsheet-rest-api
80 | {' '}
81 | to build your next hobby project.
82 |
83 |
84 | You can find the complete code for this example in{' '}
85 |
91 | src/app/example
92 |
93 | .
94 |
95 |
96 |
97 |
98 |
99 |
100 | {todosResponse.data.map((todo: Todo) => {
101 | return (
102 |
103 |
104 |
105 | )
106 | })}
107 |
108 |
109 |
110 |
111 | Total: {todosResponse?.pagination?.total}
112 |
113 |
114 | Next:{' '}
115 | {todosResponse?.pagination?.hasNext?.toString()?.toUpperCase()}
116 |
117 |
118 | Cell Range: {todosResponse?.pagination?.cell_range}
119 |
120 |
121 | Limit: {todosResponse?.pagination?.limit}
122 |
123 |
124 | Offset: {todosResponse?.pagination?.offset}
125 |
126 |
127 | Next Offset: {todosResponse?.pagination?.next_offset}
128 |
129 |
130 |
131 |
132 | {/*
133 |
Google Sheet iFrame
134 |
135 | This is the Google Sheet iframe that shows the exact sheet we used.
136 | You can use it to compare the data with the list above.
137 |
138 |
142 |
*/}
143 |
144 |
156 |
157 | )
158 | }
159 |
--------------------------------------------------------------------------------
/src/utils/sheets.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Credits to:
3 | * - https://github.com/melalj
4 | *
5 | * Most of the code in this file are coming from
6 | * https://github.com/melalj/gsheet-api/blob/master/src/api/gsheet.js
7 | *
8 | * Refine the typing to have better intellisense
9 | * Fix some deprecated parameter when passing to newer "sheets_v4" api
10 | */
11 |
12 | /* eslint-disable @typescript-eslint/ban-ts-comment */
13 | import { google, type sheets_v4 } from 'googleapis'
14 | import { detectValues, numberToLetter } from './utils'
15 |
16 | // :oad the environment variable with our keys
17 | const keysEnvVar = process.env.GOOGLE_CREDENTIALS as string
18 | if (!keysEnvVar) {
19 | throw new Error('The $GOOGLE_CREDENTIALS environment variable was not found!')
20 | }
21 |
22 | const env = JSON.parse(keysEnvVar)
23 |
24 | const auth = new google.auth.JWT({
25 | email: env.client_email,
26 | key: env.private_key,
27 | scopes: ['https://www.googleapis.com/auth/drive'],
28 | })
29 |
30 | const drive = google.drive({ version: 'v3', auth })
31 | const sheets = google.sheets({ version: 'v4', auth })
32 |
33 | export type FileData = {
34 | id: string
35 | name: string
36 | /**
37 | * @sample: In format "2025-02-03T08:58:19.749Z"
38 | */
39 | modifiedTime: string
40 | }
41 |
42 | export type GetSpreadsheetOptions = {
43 | limit?: number
44 | nextToken?: string
45 | }
46 |
47 | export async function getAllFileList(
48 | options: GetSpreadsheetOptions = { limit: 10, nextToken: '' }
49 | ): Promise<{
50 | next_token: string
51 | data: FileData[] | null
52 | }> {
53 | try {
54 | const driveRes = await drive.files.list({
55 | q: "trashed = false and mimeType = 'application/vnd.google-apps.spreadsheet'",
56 | fields: 'files(id, name, modifiedTime)',
57 | spaces: 'drive',
58 | pageSize: options.limit,
59 | pageToken: options.nextToken ? undefined : options.nextToken,
60 | })
61 |
62 | return {
63 | next_token: driveRes.data.nextPageToken || '',
64 | data: (driveRes.data.files || []) as FileData[],
65 | }
66 | } catch (e) {
67 | console.error('Got error when invoke getAllFileList', e)
68 | return {
69 | next_token: '',
70 | data: null,
71 | }
72 | }
73 | }
74 |
75 | export type GetSheetsBySpreadsheetIdResponse = {
76 | title: string
77 | index: number
78 | sheetId: number
79 | rowCount: number
80 | columnCount: number
81 | }
82 |
83 | export async function getSheetsBySpreadsheetId(
84 | spreadsheetId: string
85 | ): Promise