jhonny-me/mirrorrim

[feature] - support tencentdoc

Opened this issue · 6 comments

TencentDoc always asks users to authorize even it is a public doc, which means after granting clientId and secret from Tencent. A backend middleware is needed to proxy the download request.

sequence diagram (mermaid)

sequenceDiagram
    rect rgb(191, 223, 255)
    Mirrorrim->>+Middleware: Init request
    note right of Mirrorrim: User clicks authorize OK
    Middleware->>+Tencent: OAuth2.0
    Tencent->>+Middleware: AccessToken + RefreshToken
    Middleware->>Tencent: getOpenId with AccessToken + RefreshToken
    Tencent->>Middleware: return OpenId
    Middleware-->>+Mirrorrim: OpenId 
    Mirrorrim->>Mirrorrim: Cache OpenId
    note over Mirrorrim,Tencent: Optional process, only the first time
    end
    Mirrorrim-->>-Middleware: request download + OpenId + fileID
    Middleware->>Tencent: /openapi/drive/v2/files/{fileID}/async-export + OpenId + ClientId + AccessToken
    Middleware->>Tencent: /openapi/drive/v2/files/{fileID}/export-progress
    Tencent->>Middleware: downloadUrl
    Middleware->>Mirrorrim: downloadUrl

OpenId can be saved at the configuration file to share across team or CI machines.

Another option is to write a web crawler script, but this would rely on the users to maintain the login state on every machine. Details need to be defined.

More details about the solution:

The Backend (middleware)

/login endpoint

  • request param:
    • none
  • response:
    • data.openID: String

files/{fileID}/async-export

  • request param:
    • none
  • header:
    • openId: String, optional
  • response:
  • data.operationID: String

files/{fileID}/export-progress

  • request param:
    • operationID: String
  • header:
    • openId: String
  • response:
  • data.url: String, optional
  • data.progress: Int, [0,100]

The Client (mirrorrim)

async func download(fileID, openID) => {
  if (!openID) {
    openID = await apiClient.login();
    console.log("your openID is \(openID), save it in your package.json")
  }
  
  let operationID = await apiClient.async-export(fileID);
  let downloadUrl = await apiClient.syncQueryExportStatus(fileID, operationID);
  return await downloadFile(downloadUrl);
}

FYI:
腾讯文档开放平台