如何使用 Google 表格創建動態開放圖形圖像

已發表: 2022-02-26

開放式圖形圖像(OG 圖像)是當您的任何網站鏈接在 Facebook、LinkedIn 或 Twitter 上共享時顯示的圖像。 您可以在您網站的元標記中提供圖像的公共 URL,社交媒體網站將自動從那裡獲取。

 < head > < title > Digital Inspiration </ title > < meta property = " og:image " content = " https://www.labnol.org/og/default.png " /> </ head >

使用 Puppeteer 打開圖形圖像

Github 內部使用 Google 的 Puppeteer 庫來生成動態 Open Graph 圖像。 這些圖像是通過將自定義 HTML 輸入 Puppeteer 來動態生成的,然後 Puppeteer 會生成屏幕截圖。 您可以在這條推文中查看 Github 生成的示例 OG 圖像。

Next.js 背後的公司 Vercel 也使用 Puppeteer 作為他們的開放圖形圖像生成器。 Headless chromium 用於渲染 HTML 頁面,捕獲頁面的屏幕截圖並緩存文件以提高性能。

在沒有 Puppeteer 的情況下創建開放圖形圖像

Puppeteer 是一個很棒的庫(我在內部將它用於 screnshot.guru),但它確實需要一些技術知識才能將 Puppeteer 部署為雲功能。 將 Puppeteer 部署到雲還涉及成本,因為您必須為對該服務的任何請求付費。

Generate Open Graph Images

如果您正在尋找無代碼、無成本、無 puppeteer 的解決方案,您可以使用 Google 表格生成 Open Graph 圖像。 這就是我用來為我網站的每個頁面生成動態和獨特圖像的方法。 您可以在此推文中看到示例 OG 圖像。

這個想法的靈感來自 Document Studio。 您在 Google 幻燈片中創建圖像設計,將模板中的佔位符文本替換為您的網頁標題,然後生成演示文稿的屏幕截圖並將其保存在您的 Google Drive 中。

要開始使用,請在您的 Google 雲端硬盤中復制此 Google 表格。 將 A 列中的標題替換為您的頁面標題並清除“圖像 URL”列。 單擊“ Play按鈕,授權腳本,您會注意到電子表格會立即更新為每個頁面的圖像 URL。

在 Google 表格中添加更多頁面標題,再次點擊Play按鈕,電子表格將更新為僅包含新頁面的圖像 URL。 而已。

Open Graph Images

測試您的開放圖圖像

將 Open Graph 元標記添加到您的網站後,您可以使用以下工具測試您的 Open Graph 圖像。

  1. card-dev.twitter.com/validator - 將您網站的 URL 粘貼到 URL 字段中,然後單擊Validate按鈕以查看 Twitter 是否能夠呈現您的 Open Graph 元標記中提供的圖像。 您還可以使用此驗證器工具從 Twitter 緩存中清除任何頁面的 OG 圖像。

  2. developers.facebook.com/tools/debug/ - 將您網站的 URL 粘貼到 URL 字段中,然後單擊“ Debug ”按鈕以查看 Facebook 是否能夠呈現您的 Open Graph 元標記中提供的圖像。

  3. linkedin.com/post-inspector/ - LinkedIn 的 Post Inspector 工具可以幫助您確定您的網頁在 LinkedIn 平台上共享時的顯示方式。 如果關聯的 OG Image 已更改,您還可以請求 LinkedIn 重新抓取頁面。

開放圖圖像生成器如何工作?

在 Google Sheet 中,轉到 Extensions 菜單並選擇 Apps Script 以查看用於生成 Open Graph 圖像的源代碼。 您還可以使用任何可用模板在 Canva 中創建圖形,然後在 Google 幻燈片中導入 Canva 設計。

該應用程序是用 Google Apps 腳本編寫的。 它從 Google 表格中讀取帖子標題,為表格中的每一行生成演示文稿的副本,生成幻燈片的屏幕截圖並將其添加到您的 Google Drive。

 const FOLDER = 'Open Graph Images' ; const TEMPLATE_ID = '1QZ4mR6B36XEVyzJf-s8vq88SDnSRPiRDchJ71VM-cfU' ; const APP = { /* Create a folder in Google Drive for storing open graph images */ getFolder ( ) { if ( typeof this . folder === 'undefined' ) { const folders = DriveApp . getFoldersByName ( FOLDER ) ; this . folder = folders . hasNext ( ) ? folders . next ( ) : DriveApp . createFolder ( FOLDER ) ; } return this . folder ; } , /* Download the Slide thumbnail URL and save it to Google Drive */ getImageUrl ( contentUrl , title ) { const blob = UrlFetchApp . fetch ( contentUrl ) . getBlob ( ) ; const file = this . folder . createFile ( blob ) ; file . setName ( title ) ; return file . getUrl ( ) ; } , /* Make a temporary copy of the Google Slides template */ getTemplate ( title ) { const slideTemplate = DriveApp . getFileById ( TEMPLATE_ID ) ; const slideCopy = slideTemplate . makeCopy ( title , this . getFolder ( ) ) ; return slideCopy . getId ( ) ; } , /* Get the thumbnail URL of the Google Slides template */ getThumbnailUrl ( presentationId ) { const { slides : [ { objectId } ] = { } } = Slides . Presentations . get ( presentationId , { fields : 'slides/objectId' , } ) ; const data = Slides . Presentations . Pages . getThumbnail ( presentationId , objectId ) ; return data . contentUrl ; } , /* Replace the placeholder text with the title of the web page */ createImage ( title ) { const presentationId = this . getTemplate ( title ) ; Slides . Presentations . batchUpdate ( { requests : [ { replaceAllText : { containsText : { matchCase : false , text : '{{Title}}' } , replaceText : title , } , } , ] , } , presentationId ) ; const contentUrl = this . getThumbnailUrl ( presentationId ) ; const imageUrl = this . getImageUrl ( contentUrl , title ) ; /* Trash the presentation copy after the image is downloaded */ DriveApp . getFileById ( presentationId ) . setTrashed ( true ) ; return imageUrl ; } , /* Show job progress to the user */ toast ( title ) { SpreadsheetApp . getActiveSpreadsheet ( ) . toast ( '️ ' + title ) ; } , run ( ) { const sheet = SpreadsheetApp . getActiveSheet ( ) ; sheet . getDataRange ( ) . getDisplayValues ( ) . forEach ( ( [ title , url ] , index ) => { /* Only process rows that have a title */ if ( title && ! / ^http / . test ( url ) && index > 0 ) { const imageUrl = this . createImage ( title ) ; sheet . getRange ( index + 1 , 2 ) . setValue ( imageUrl ) ; this . toast ( title ) ; } } ) ; } , } ;