簡體   English   中英

如何以編程方式實時更新 Google 文檔(通過 Chrome 擴展程序或外部 JS)

[英]How to programmatically update Google Docs in real-time (via Chrome Extension or external JS)

我想通過 Google Chrome 擴展程序或簡單的 JavaScript 以編程方式在外部編輯我的 Google Doc,並在 Google Doc 中實時(實時)查看更改。 當這個問題出現時,我正在尋找可以編輯 Google Doc 並以編程方式保存更改的 Chrome 擴展程序。 在我的研究過程中,我遇到了Grammarly 我對他們如何設法近乎實時地將拼寫更正應用到 Google Doc 印象深刻。 你可以像這樣重現它:

  1. 安裝語法 Chrome 擴展
  1. 打開/創建 Google 文檔
  2. 讓 Grammarly 檢查您的文本(突出顯示包含錯誤的單詞)
  3. 左鍵單擊突出顯示的單詞
  4. 單擊建議的更正

然后 Grammarly 將更新 Google Doc。 我由此注意到:

  • Google Doc 似乎沒有通過 Google Docs API 或 Google AppScript 更新
  • 當用戶手動編輯文檔時,保存過程的行為似乎與 Google 文檔本身的官方自動保存機制相同。 這可以解釋如下:
    • 自動保存指示器被觸發
      在此處輸入圖像描述
    • 谷歌文檔save HTTP 請求被執行
      HTTP FormData 還包含適當的參數組合(在數組的第一個命令中定義的索引范圍si (startIndex) 和ei (endIndex) 內的現有字被第二個命令中的新字替換)
[{"commands":[{"ty":"ds","si":229,"ei":232}, {"ty":"is","ibi":229,"s":"Test"}]}]

在此處輸入圖像描述

我已經嘗試過以下解決方案:

  1. 使用谷歌文檔 API
    結果:✓ 有效,但有長達 5 秒的明顯延遲
gapi.client.docs.documents.batchUpdate({
    documented: <docId>,
    requests: [
        {
            deleteContentRange: {
                range: {
                    startIndex: 1,
                    endIndex: 10,
                },
            },
        },
        {
            insertText: {
                location: {
                    index: 1,
                },
                text: 'Lorem ipsum',
            },
        },
    ],
})
  1. 使用Google Script API執行 AppScript function。
    結果:✓ 有效,但有長達 5 秒的明顯延遲
// API call
await gapi.client.script.scripts.run({
    scriptId: <scriptId>,
    resource: {
        function: 'myFunction'
    }
})

// AppScript function from Google Script Editor
function myFunction() {
    var body = DocumentApp.openById(<docId>).getBody()
    body.appendParagraph("Lorem ipsum")
}
  1. 直接在 Google Doc 中操作 DOM(這里我嘗試用 JavaScript 編輯 Google Doc 的文本,然后保存)。
    結果:✗我找不到觸發自動保存機制的方法
  2. 手動執行內部 Google 文檔(自動)保存方法。
    結果:✗導致內部服務器錯誤

不幸的是,到目前為止所有的嘗試都沒有成功或沒有達到預期的結果。

天哪,我終於找到了答案。 它一直在 Stack Overflow 上。

事實證明這非常容易; 我們都想多了。 您可以只模擬帶有事件的按鍵,並使用 for 循環立即替換您需要修改的任何文本。 但是,Google Docs 使用 Iframe 和內容來監聽關鍵事件

<html>
    <head></head>
    <body spellcheck="false" role="textbox" aria-label="Document content" contenteditable="true" style="background-color: transparent;"></body>
</html>

所以我們必須在 IFrame 而不是文檔上觸發事件。 此外,內容腳本對我不起作用,因此我不得不將另一個腳本注入頁面並使用自定義事件來告訴注入的腳本模擬按鍵。 您可以按照此處所述注入腳本,然后,從注入的腳本中,您可以像這樣在文檔上模擬按鍵:

const keyEvent = document.createEvent('Event')
  keyEvent.initEvent('keypress', true, true)
  keyEvent.key = KEY // A key like 'a' or 'B' or 'Backspace'
  // You will need to change this line if you want to use other special characters such as the left and right arrows; or you can just use this line without the .key line I think
  keyEvent.keyCode = KEY === 'Backspace' ? 8 : KEY.charCodeAt(0) 
  document.querySelector('.docs-texteventtarget-iframe').contentDocument.activeElement
    .dispatchEvent(keyEvent)

(從這個答案中獲得)

您可以將上述代碼包裝在注入腳本中的事件偵聽器中,並從您的內容腳本中分派一個自定義事件,將detail作為鍵名,以觸發這樣的按鍵。

對於我的用例,我不在乎 cursor 在哪里,但是如果您需要找到我們的 cursor 在哪里,這樣您就可以知道模擬左/右鍵的次數,您可以通過計算長度輕松獲得索引所有文本類,並找到 cursor 相對於每個字符的位置。 我找到了一個不錯的小庫來執行此操作(盡管它有一些警告,因為 Google Docs 顯然一次只加載一頁)太長而無法包含在此處,但您可以在 GitHub 上查看它

正如這里已經回答的那樣 - 是的,您需要將關鍵事件發送到特殊的 iframe,而不是當前文檔。

我最近在搜索相同的功能。 找到它后,我做了一個圖書館。 進一步你可以使用這個 - google-docs-utils

您可以將其與 Node.js 或直接在瀏覽器中使用:

這是使用google-docs-utils package 解決您的任務的代碼:

GoogleDocsUtils.typeText('test text'); // types at current caret position
GoogleDocsUtils.pressOn.Enter(); // move to new line
GoogleDocsUtils.typeText('another test text');

我查看了 Grammarly 的源代碼——它使用與這個庫相同的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM