Google Services API Service bằng Go Backend – GoogleSvc.dll (8 người xem)

Người dùng đang xem chủ đề này

Kiều Mạnh

I don't program, I beat code into submission!!!
Tham gia
9/6/12
Bài viết
5,564
Được thích
4,142
Giới tính
Nam
1/ Tôi tách từ chủ đề sau từ bài số #16 sang chủ đề này ai có nhu cầu tìm hiểu và bàn luận xin mời vào đây

2/ Chủ đề này hổ trợ cho người dùng cá nhân sẽ còn chủ đề khác áp dụng cho sử dụng Server và Client mô tả bài #17 là

Mô hình sử dụng GoogleSvc Bridge​




Google Services API Service bằng Go Backend – GoogleSvc.dll​


Demo mẫu sử dụng đơn giản và còn cập nhật bổ sung các hàm tiện ích sau


Tài liệu tham khảo:

https://kieumanh366377.github.io/googlesvc-guide/


Vì sao cần tự tạo credentials.json?​

Trong hệ thống GoogleSvc.dll, file credentials.json là “chìa khóa xác thực” để kết nối tới Google Sheets, Drive hoặc Gmail của chính bạn.

File này không thể do bên thứ ba tạo sẵn, vì nó gắn trực tiếp với tài khoản Google cá nhân và quyền truy cập dữ liệu của bạn.


️ Lý do quan trọng về bảo mật​

Việc tự tạo file này giúp đảm bảo:

  • Dữ liệu Google thuộc quyền kiểm soát của chính bạn
  • Không phụ thuộc vào máy chủ trung gian
  • Không chia sẻ thông tin xác thực cho bên thứ ba
  • Giảm rủi ro lộ token hoặc truy cập trái phép

⚙️ Ý nghĩa thực tế​

Khi sử dụng GoogleSvc.dll:

  • Excel VBA hoặc tool nội bộ chỉ gọi service
  • Toàn bộ xác thực Google nằm trong credentials.json của bạn
  • Bạn là người duy nhất kiểm soát quyền truy cập dữ liệu

Kết luận​

Việc tự tạo credentials.json không phải là bước kỹ thuật phụ, mà là:

“cơ chế bảo vệ quyền sở hữu dữ liệu”
Nó đảm bảo hệ thống hoạt động theo đúng nguyên tắc:
dữ liệu Google của bạn luôn thuộc về bạn, không qua bất kỳ trung gian nào.


 
đang hoàn thiện tiếp các hàm tiện ích cho Google Drive

Tạm xem mã như sau

Mã:
' ============================================================
' modDriveTest.bas
' Test cac action Drive: list, get, search, createFolder,
' upload, download, copy, move, delete
'
' Cach dung:
'   1. Mo Excel 64-bit, Alt+F11
'   2. Insert > Module, paste file nay vao
'   3. Sua cac hang so o phan CONST truoc khi test
'   4. Goi tung ham Test_* trong Immediate Window (Ctrl+G)
'
' THU TU TEST KHUYEN NGHI:
'   Test_DriveList       -> lay fileId/folderId de dung cho cac test khac
'   Test_DriveGet        -> kiem tra chi tiet 1 file
'   Test_DriveSearch     -> tim kiem theo ten/type
'   Test_DriveCreateFolder -> tao folder test
'   Test_DriveUpload     -> upload file len folder vua tao
'   Test_DriveCopy       -> copy file vua upload
'   Test_DriveMove       -> move file copy sang folder khac
'   Test_DriveDownload   -> download file ve may
'   Test_DriveDelete     -> xoa file copy/move (can xac nhan)
' ============================================================

' ------------------------------------------------------------
' DECLARE
' ------------------------------------------------------------
Private Declare PtrSafe Function GBridgeExecute Lib "GoogleSvc.dll" _
        ( _
            ByVal reqJsonPtr As LongPtr, _
            ByVal outBuf As LongPtr, _
            ByVal outBufSize As Long) As LongLong

' ------------------------------------------------------------
' CONST - sua truoc khi test
' ------------------------------------------------------------
Private Const BUF_SIZE As Long = 65536   ' 64 KB

' File de upload test (phai ton tai tren may)
Private Const LOCAL_UPLOAD_FILE As String = "C:\Temp\GoogleSvc_Demo.xlsb"

' Thu muc download ve
Private Const LOCAL_DOWNLOAD_DIR As String = "D:\Downloads\"

' fileId de test drive.get / drive.copy / drive.move / drive.download
' Lay tu ket qua Test_DriveList hoac Test_DriveUpload
'Private Const TEST_FILE_ID As String = "PUT_FILE_ID_HERE"
Private Const TEST_FILE_ID As String = "16uNu1wRZMwR0kxfhKTpuoFA9RCSF7IXE"

' folderId de test drive.list / drive.createFolder / drive.upload
' De rong = My Drive goc. Lay tu ket qua Test_DriveCreateFolder
Private Const TEST_FOLDER_ID As String = ""

' ------------------------------------------------------------
' WRAPPER
' ------------------------------------------------------------
Private Function ExecuteJSON(ByVal sJSON As String) As String
    Dim buf()    As Integer
    Dim bufSize  As Long
    Dim bufSize2 As Long
    Dim ret      As LongLong
    Dim needed   As Long

    bufSize = BUF_SIZE
    ReDim buf(0 To bufSize - 1)
    ret = GBridgeExecute(StrPtr(sJSON), VarPtr(buf(0)), bufSize)

    If ret < 0 Then
        needed = CLng(-ret) + 1
        bufSize2 = needed
        ReDim buf(0 To bufSize2 - 1)
        ret = GBridgeExecute(StrPtr(sJSON), VarPtr(buf(0)), bufSize2)
    End If

    If ret >= 0 Then
        ExecuteJSON = Left$(buf2Str(buf), CLng(ret))
    Else
        ExecuteJSON = "{""ok"":false,""error"":""buffer van qua nho""}"
    End If
End Function

Private Function buf2Str(buf() As Integer) As String
    Dim i As Long
    Dim s As String
    For i = 0 To UBound(buf)
        If buf(i) = 0 Then Exit For
        s = s & ChrW(buf(i))
    Next i
    buf2Str = s
End Function

Private Sub PrintResult(ByVal sLabel As String, ByVal sJSON As String)
    Debug.Print "------------------------------------------------------------"
    Debug.Print "[" & sLabel & "]"
    Debug.Print sJSON
End Sub

' ------------------------------------------------------------
' TEST
' ------------------------------------------------------------

' Test_DriveList: liet ke file trong folder (rong = My Drive goc)
' Ket qua mong doi: {"ok":true,"data":[{"id":"...","name":"..."},...]}
Public Sub Test_DriveList()
    Dim sReq As String
    sReq = "{""action"":""drive.list"",""folderId"":""" & TEST_FOLDER_ID & """,""maxResults"":20}"
    PrintPretty "drive.list", ExecuteJSON(sReq)
End Sub

' Test_DriveGet: lay thong tin chi tiet 1 file theo fileId
' Ket qua mong doi: {"ok":true,"data":{"id":"...","name":"...","mimeType":"...","size":...}}
Public Sub Test_DriveGet()
    If TEST_FILE_ID = "PUT_FILE_ID_HERE" Then
        Debug.Print "[drive.get] Chua sua TEST_FILE_ID - lay tu Test_DriveList truoc"
        Exit Sub
    End If
    Dim sReq As String
    sReq = "{""action"":""drive.get"",""fileId"":""" & TEST_FILE_ID & """}"
    PrintPretty "drive.get", ExecuteJSON(sReq)
End Sub

' Test_DriveSearch: tim file theo ten
' Ket qua mong doi: {"ok":true,"data":[...]}
Public Sub Test_DriveSearch()
    Dim sReq As String
    ' Tim tat ca file Excel trong Drive
    sReq = "{""action"":""drive.search"",""query"":""mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'"",""maxResults"":10}"
    PrintPretty "drive.search (xlsx files)", ExecuteJSON(sReq)
End Sub

' Test_DriveSearch_ByName: tim file theo ten chua 'test'
Public Sub Test_DriveSearch_ByName()
    Dim sReq As String
    sReq = "{""action"":""drive.search"",""query"":""name contains 'test'"",""maxResults"":10}"
    PrintPretty "drive.search (name contains test)", ExecuteJSON(sReq)
End Sub

' Test_DriveCreateFolder: tao folder moi ten "GoogleSvc_Test"
' Ket qua mong doi: {"ok":true,"data":{"folderId":"...","name":"GoogleSvc_Test"}}
' SAU KHI CHAY: copy folderId de dung trong Test_DriveUpload/Move
Public Sub Test_DriveCreateFolder()
    Dim sReq As String
    sReq = "{""action"":""drive.createFolder"",""name"":""GoogleSvc_Test""}"
    PrintPretty "drive.createFolder", ExecuteJSON(sReq)
End Sub

' Test_DriveUpload: upload file tu dia len Drive
' Ket qua mong doi: {"ok":true,"data":{"fileId":"...","fileName":"...","webViewLink":"..."}}
' Truoc khi chay: tao file C:\Temp\test_upload.xlsx hoac sua LOCAL_UPLOAD_FILE
Public Sub Test_DriveUpload()
    Dim sReq    As String
    Dim sFolder As String

    sFolder = TEST_FOLDER_ID   ' rong = My Drive goc

    sReq = "{""action"":""drive.upload"",""localPath"":""" & _
           Replace(LOCAL_UPLOAD_FILE, "\", "\\") & """," & _
           """folderId"":""" & sFolder & """}"
    PrintPretty "drive.upload", ExecuteJSON(sReq)
End Sub

' Test_DriveCopy: tao ban sao file (doi ten thanh "test_upload_copy.xlsx")
' Ket qua mong doi: {"ok":true,"data":{"fileId":"...","name":"test_upload_copy.xlsx"}}
Public Sub Test_DriveCopy()
    If TEST_FILE_ID = "PUT_FILE_ID_HERE" Then
        Debug.Print "[drive.copy] Chua sua TEST_FILE_ID"
        Exit Sub
    End If
    Dim sReq As String
    sReq = "{""action"":""drive.copy"",""fileId"":""" & TEST_FILE_ID & """," & _
           """newName"":""test_upload_copy.xlsx""}"
    PrintPretty "drive.copy", ExecuteJSON(sReq)
End Sub

' Test_DriveMove: di chuyen file sang folder khac
' Can: fileId cua file muon move + newParentId cua folder dich
' oldParentId: lay tu ket qua drive.get (truong "parents")
Public Sub Test_DriveMove()
    If TEST_FILE_ID = "PUT_FILE_ID_HERE" Then
        Debug.Print "[drive.move] Chua sua TEST_FILE_ID"
        Exit Sub
    End If
    Dim sNewParent As String
    Dim sOldParent As String
    Dim sReq       As String

    sNewParent = "PUT_DEST_FOLDER_ID_HERE"  ' <-- folder dich
    sOldParent = ""                          ' <-- folder hien tai (lay tu drive.get)

    sReq = "{""action"":""drive.move"",""fileId"":""" & TEST_FILE_ID & """," & _
           """newParentId"":""" & sNewParent & """," & _
           """oldParentId"":""" & sOldParent & """}"
    PrintPretty "drive.move", ExecuteJSON(sReq)
End Sub

' Test_DriveDownload: download file ve may
' Ket qua mong doi: {"ok":true,"data":{"status":"download thanh cong","localPath":"..."}}
Public Sub Test_DriveDownload()
    If TEST_FILE_ID = "PUT_FILE_ID_HERE" Then
        Debug.Print "[drive.download] Chua sua TEST_FILE_ID"
        Exit Sub
    End If
    Dim sLocalPath As String
    Dim sReq       As String

    sLocalPath = LOCAL_DOWNLOAD_DIR & "downloaded_test.xlsx"

    sReq = "{""action"":""drive.download"",""fileId"":""" & TEST_FILE_ID & """," & _
           """localPath"":""" & Replace(sLocalPath, "\", "\\") & """}"
    PrintPretty "drive.download", ExecuteJSON(sReq)
End Sub

' Test_DriveDelete: xoa VINH VIEN 1 file (khong the hoan tac)
' CANH BAO: bo comment dong ExecuteJSON de chay that su
Public Sub Test_DriveDelete()
    Dim sFileToDelete As String
    Dim sReq          As String

    sFileToDelete = "PUT_FILE_ID_TO_DELETE_HERE"  ' <-- fileId can xoa

    If sFileToDelete = "PUT_FILE_ID_TO_DELETE_HERE" Then
        Debug.Print "[drive.delete] Chua sua sFileToDelete - an toan, bo qua"
        Exit Sub
    End If

    sReq = "{""action"":""drive.delete"",""fileId"":""" & sFileToDelete & """}"

    ' CANH BAO: bo comment dong duoi de chay that su - KHONG THE HOAN TAC
    ' PrintPretty "drive.delete", ExecuteJSON(sReq)
    Debug.Print "[drive.delete] Bo comment dong PrintResult de chay that su"
End Sub

' Test_AllDrive: chay cac test an toan (khong delete, khong move)
Public Sub Test_AllDrive()
    Debug.Print "============================================================"
    Debug.Print " TEST DRIVE ACTIONS (an toan)"
    Debug.Print "============================================================"
    Test_DriveList
    Test_DriveSearch
    Test_DriveSearch_ByName
    Test_DriveCreateFolder
    Debug.Print "============================================================"
    Debug.Print " HOAN THANH - Kiem tra Immediate Window"
    Debug.Print " Tiep theo: lay fileId/folderId de test Upload/Get/Copy/Move"
    Debug.Print "============================================================"
End Sub


Các hàm tiện ích cho Google Sheets

Mã:
' ============================================================
' modSheetsTest.bas
' Test cac action Sheets: read, write, append, clear,
' getInfo, create, rename, delete, batchUpdate
'
' Cach dung:
'   1. Mo Excel 64-bit, Alt+F11
'   2. Insert > Module, paste file nay vao
'   3. Sua SHEET_ID thanh Spreadsheet ID thuc te
'   4. Goi tung ham Test_* trong Immediate Window (Ctrl+G)
' ============================================================

' ------------------------------------------------------------
' DECLARE
' ------------------------------------------------------------
#If VBA7 Then
    Private Declare PtrSafe Function GBridgeExecute Lib "GoogleSvc.dll" _
        ( _
            ByVal reqJsonPtr As LongPtr, _
            ByVal outBuf As LongPtr, _
            ByVal outBufSize As Long) As LongLong
#End If

' ------------------------------------------------------------
' CONST - sua SHEET_ID truoc khi test
' ------------------------------------------------------------
'Private Const SHEET_ID As String = "PUT_YOUR_SPREADSHEET_ID_HERE"

Private Const SHEET_ID As String = "1punDQ-pRaMsopULsUaNthuHri5pj4ZrhNLFkOD3qkoo"  ' <- SUA O DAY

Private Const BUF_SIZE As Long = 65536   ' 64 KB

' ------------------------------------------------------------
' WRAPPER (chep tu modAuthTest, giu nhat quan)
' ------------------------------------------------------------
Private Function ExecuteJSON(ByVal sJSON As String) As String
    Dim buf()    As Integer
    Dim bufSize  As Long
    Dim bufSize2 As Long
    Dim ret      As LongLong
    Dim needed   As Long

    bufSize = BUF_SIZE
    ReDim buf(0 To bufSize - 1)
    ret = GBridgeExecute(StrPtr(sJSON), VarPtr(buf(0)), bufSize)

    If ret < 0 Then
        needed = CLng(-ret) + 1
        bufSize2 = needed
        ReDim buf(0 To bufSize2 - 1)
        ret = GBridgeExecute(StrPtr(sJSON), VarPtr(buf(0)), bufSize2)
    End If

    If ret >= 0 Then
        ExecuteJSON = Left$(buf2Str(buf), CLng(ret))
    Else
        ExecuteJSON = "{""ok"":false,""error"":""buffer van qua nho""}"
    End If
End Function

Private Function buf2Str(buf() As Integer) As String
    Dim i As Long
    Dim s As String
    For i = 0 To UBound(buf)
        If buf(i) = 0 Then Exit For
        s = s & ChrW(buf(i))
    Next i
    buf2Str = s
End Function

Private Sub PrintResult(ByVal sLabel As String, ByVal sJSON As String)
    Debug.Print "------------------------------------------------------------"
    Debug.Print "[" & sLabel & "]"
    Debug.Print sJSON
End Sub

' ------------------------------------------------------------
' HELPER - tao JSON request don gian
' ------------------------------------------------------------
Private Function MakeReq(ByVal sAction As String, ByVal sExtra As String) As String
    If sExtra = "" Then
        MakeReq = "{""action"":""" & sAction & """,""spreadsheetId"":""" & SHEET_ID & """}"
    Else
        MakeReq = "{""action"":""" & sAction & """,""spreadsheetId"":""" & SHEET_ID & """," & sExtra & "}"
    End If
End Function

' ------------------------------------------------------------
' TEST
' ------------------------------------------------------------

' Test_SheetsRead: doc du lieu 1 vung
' Ket qua mong doi: {"ok":true,"data":{"values":[...],"range":"..."}}
Public Sub Test_SheetsRead()
    Dim sReq As String
    sReq = MakeReq("sheets.read", """range"":""Sheet1!A1:C5""")
    PrintResult "sheets.read", ExecuteJSON(sReq)
End Sub

' Test_SheetsWrite: ghi du lieu vao 1 vung
' Ket qua mong doi: {"ok":true,"data":{"updatedRange":"...","updatedRows":2,...}}
Public Sub Test_SheetsWrite()
    Dim sReq As String
    sReq = MakeReq("sheets.write", """range"":""Sheet1!A1"",""values"":[[""Ten"",""Tuoi""],[""An"",25]]")
    PrintResult "sheets.write", ExecuteJSON(sReq)
End Sub

' Test_SheetsAppend: them dong moi vao cuoi du lieu
' Ket qua mong doi: {"ok":true,"data":{"updatedRows":1,...}}
Public Sub Test_SheetsAppend()
    Dim sReq As String
    sReq = MakeReq("sheets.append", """range"":""Sheet1!A1"",""values"":[[""Binh"",30]]")
    PrintResult "sheets.append", ExecuteJSON(sReq)
End Sub

' Test_SheetsClear: xoa du lieu trong 1 vung (giu dinh dang)
' Ket qua mong doi: {"ok":true,"data":{"clearedRange":"..."}}
Public Sub Test_SheetsClear()
    Dim sReq As String
    sReq = MakeReq("sheets.clear", """range"":""Sheet1!A1:C10""")
    PrintResult "sheets.clear", ExecuteJSON(sReq)
End Sub

' Test_SheetsGetInfo: lay thong tin spreadsheet va danh sach tab
' Ket qua mong doi: {"ok":true,"data":{"title":"...","sheets":[{"sheetId":0,"title":"Sheet1",...}]}}
Public Sub Test_SheetsGetInfo()
    PrintResult "sheets.getInfo", ExecuteJSON(MakeReq("sheets.getInfo", ""))
End Sub

' Test_SheetsCreate: tao spreadsheet moi
' Ket qua mong doi: {"ok":true,"data":{"spreadsheetId":"...","title":"...","webViewLink":"..."}}
' SAU KHI CHAY: copy spreadsheetId de dung trong Test_SheetsRename/Delete
Public Sub Test_SheetsCreate()
    Dim sReq As String
    sReq = "{""action"":""sheets.create"",""title"":""Test GoogleSvc""}"
    PrintResult "sheets.create", ExecuteJSON(sReq)
End Sub

' Test_SheetsRename: doi ten 1 tab (can sheetId lay tu getInfo)
' sheetId = 0 la tab dau tien (Sheet1 mac dinh)
' Ket qua mong doi: {"ok":true,"data":{"status":"doi ten thanh cong",...}}
Public Sub Test_SheetsRename()
    Dim sReq As String
    ' sheetId: lay tu ket qua Test_SheetsGetInfo
    ' Sua sheetId va newTitle truoc khi chay
    sReq = MakeReq("sheets.rename", """sheetId"":0,""newTitle"":""DuLieu""")
    PrintResult "sheets.rename", ExecuteJSON(sReq)
End Sub

' Test_SheetsDelete: xoa 1 tab (can sheetId, spreadsheet phai con >= 1 tab)
' CANH BAO: thao tac nay khong hoan tac duoc.
' Ket qua mong doi: {"ok":true,"data":{"status":"xoa sheet thanh cong",...}}
Public Sub Test_SheetsDelete()
    Dim sSheetID As String
    Dim sReq     As String

    ' Dung spreadsheetId cua sheet vua tao (Test_SheetsCreate)
    ' Sua gia tri duoi day truoc khi chay
    Dim sTmpSpreadsheetID As String
    sTmpSpreadsheetID = "PUT_NEW_SPREADSHEET_ID_HERE"

    ' sheetId = 0 la tab mac dinh dau tien
    sReq = "{""action"":""sheets.delete"",""spreadsheetId"":""" & sTmpSpreadsheetID & """,""sheetId"":0}"

    ' CANH BAO: goi nay se xoa tab - chi chay khi spreadsheet co >= 2 tab
    ' PrintResult "sheets.delete", ExecuteJSON(sReq)
    Debug.Print "[sheets.delete] Bo qua - bo comment dong PrintResult de chay that su"
End Sub

' Test_SheetsBatchUpdate: dinh dang in dam header row
' Dung batchUpdate de to mau nen header (repeatCell)
' Ket qua mong doi: {"ok":true,"data":{"replyCount":1}}
Public Sub Test_SheetsBatchUpdate()
    Dim sReq As String

    ' Request: to mau nen xanh la + chu trang cho hang dau tien (A1:Z1)
    ' sheetId = 0 (tab dau tien), startRowIndex=0, endRowIndex=1 = hang 1
    sReq = MakeReq("sheets.batchUpdate", _
        """requests"":[{""repeatCell"":{" & _
            """range"":{""sheetId"":0,""startRowIndex"":0,""endRowIndex"":1}," & _
            """cell"":{""userEnteredFormat"":{" & _
                """backgroundColor"":{""red"":0.2,""green"":0.5,""blue"":0.9}," & _
                """textFormat"":{""bold"":true,""foregroundColor"":{""red"":1,""green"":1,""blue"":1}}" & _
            "}}," & _
            """fields"":""userEnteredFormat(backgroundColor,textFormat)""" & _
        "}}]")

    PrintResult "sheets.batchUpdate (header format)", ExecuteJSON(sReq)
End Sub

' Test_AllSheets: chay toan bo luong Sheets theo thu tu dung
' (khong bao gom Delete vi co rui ro mat du lieu)
Public Sub Test_AllSheets()
    Debug.Print "============================================================"
    Debug.Print " TEST TOAN BO SHEETS ACTIONS"
    Debug.Print "============================================================"
    Test_SheetsGetInfo
    Test_SheetsWrite
    Test_SheetsRead
    Test_SheetsAppend
    Test_SheetsBatchUpdate
    Test_SheetsClear
    Test_SheetsCreate
    Debug.Print "============================================================"
    Debug.Print " HOAN THANH - Kiem tra Immediate Window"
    Debug.Print "============================================================"
End Sub

Sẽ làm các hàm tiện ích cho Gmail sau .... sau khi hoàn tất xem xét tổng thể cần viết và tinh chỉnh gì viết sau

Ai có nhu cầu, mong muốn hoặc bài toán thực tế nào thì cứ trao đổi ngay tại chủ đề này.
Tôi sẽ xem xét và nếu phù hợp trong khả năng, sẽ viết thêm hoặc điều chỉnh mã để hỗ trợ.
 

Bài viết mới nhất

Back
Top Bottom