發表文章

簡記:Node.js使用google sheet API讀取(新版google-auth&typescript)

 這裡是serviceaccount的json放在環境變數中,並googleapis套件操作google sheet api。 因為新版google auth套件有改版把fromJSON()和給廢掉,導致升級版本程式要調整,跟google&AI弄了弄,範例都給我奇怪的結果,這篇把這些整理起來 pnpm add googleapis import { google , sheets_v4 } from 'googleapis' ; async function main ( ... args : string []) { const credentials = JSON . parse (process. env . SHEET_CREDENTIALS ); const authClient = new google . auth . JWT ({ scopes : [ 'https://www.googleapis.com/auth/spreadsheets' ] }) authClient . fromJSON ( credentials ); const sheetAPIs = google . sheets ({ version : 'v4' , auth : authClient }); const res = await sheetAPIs . spreadsheets . get ({ spreadsheetId : process. env . SHEET_ID }); if ( ! res . ok ) throw Error(`http error code:${ res . status }`); console . log ( res . data ) } const args = process . argv . slice ( 2 ); main ( ... args ). catch ( console . error ); scopes上面是提供讀寫 如果只讀取,就改成 scopes: ['https://www.go...

簡記:在typescript中自定義環境變數內容

declare namespace NodeJS { interface ProcessEnv { /** * App 執行環境 * - development: 開發環境 * - production: 正式環境 * - test: 測試環境 */ NODE_ENV : 'development' | 'production' | 'test' ; /** 僅伺服器端 */ PRODUCT_SHEET_CREDENTIALS : string ; PRODUCT_SHEET_ID : string ; STORAGE_CREDENTIALS : string ; STORAGE_BUCKET_NAME : string ; /** 公開給前端 */ NEXT_PUBLIC_FIREBASE_SDK_CONFIGS : string ; NEXT_PUBLIC_API_URL : string ; } }  

簡記:node.js v20中設定typescript與.env

pnpm init pnpm add -D typescript @types/node src/index.ts async function main ( ... args : string []) { console . debug ( 'process.env.NODE_ENV=' , process . env . NODE_ENV ) console . debug ( 'process.env.STORAGE_BUCKET_NAME=' , process . env . STORAGE_BUCKET_NAME ) } const args = process . argv . slice ( 2 ); main ( ... args ). catch ( console . error ); package.json "type" : "commonjs" , "scripts" : { "build" : "tsc" , "dev" : "pnpm run build && node --env-file=.env.development.local ." , "start" : "pnpm run build && node --env-file=.env.production.local ." }, tsconfig.json "compilerOptions" : { "module" : "CommonJS" , "moduleResolution" : "Node" , "outDir" : "dist" , "rootDir" : "src" 這個設定的優點是import不需要寫.js, 缺點就是沒有top-...

Dockerfile中設定locale成正體中文-以node.js為例

Configure Locale to Traditional Chinese in Dockerfile for Node.js 最近看了github發了些須修補安全性的信件,偶然發現VSCode內開dockerfile會提示使用的base image已經有安全疑慮,而且Docker hub已經將風險都列出來。 為了減少安全疑慮,我就決定改用最新發布的base image(無critical和high項目),翻一下以前寫過得文章:  在Ubuntu 16.04的Dockerfile中設定locale  開始修改。

在Github Action加入手動觸發

好一陣子沒有使用github flow,上週再用看文件,已有手動觸發的功能。想當年(疑?)我都寫個on push *讓它推入直接跑測試,確認改好後才改成想要的執行時機。git歷史都會有一堆測試(笑死)   如何加入? 現在只要在Github儲藏庫(.github/workflow/*.yml)內,於on觸發區下加入workflow_dispatch就能讓Github有手動觸發的按鈕! 範例:  github/workflow/deploy.yml name : build and deploy on : push : paths : - 'content/**' workflow_dispatch : # 👈 手動觸發加入這一行 jobs : deploy : runs-on : ubuntu-24.04 steps : - name : Checkout repository uses : actions/checkout@v4 .... 這樣在 GitHub 的 Actions 頁面中,就可以看到這個 workflow 並手動點選執行了 參考資料 Github官方文件workflow-syntax#onworkflow_dispatch

升級Mirochiu/React-Google-Apps-Script至3.1.0

今日完成的Mirochiu/React-Google-Apps-Script升級作業 今天完成了 Mirochiu/React-Google-Apps-Script 的升級作業。這個專案是延伸自 enuchi/React-Google-Apps-Script 3.1.0 版本,我將專案的打包與本機開發環境從 Webpack 升級到 Vite 。透過 Vite 的 HMR(Hot Module Replacement) ,開發效率得到了顯著提升,修改前端程式碼可以即時看到效果,開發流程更加順暢。 目前專案狀態: 前端 :專注於使用 React.js 後端 :仍使用 Google Apps Script (GAS) 作為網頁伺服器 程式語言與工具 :TypeScript + Vite + pnpm 套件管理 :使用 pnpm 支援指令 : start :本地開發 lint :程式碼檢查 test:integration :整合測試 deploy :部署到 GAS 整體來說,這次升級不僅更新了開發工具鏈,也讓前端開發體驗更加流暢,同時保留了後端 GAS 作為伺服器的架構,非常適合快速開發 React.js + GAS 的 Web 專案。

解決升級node.js 20版本後import json file的警示'assert' is deprecated in import statements and support will be removed in a future version

完整的警示訊息是 (node:16142) V8: file:///workspace//src/main.mjs:3 'assert' is deprecated in import statements and support will be removed in a future version; use 'with' instead   原本 import serviceAccount from '../serviceAccount.json' assert { type : 'json' }; 改成 import serviceAccount from '../serviceAccount.json' with { type : 'json' }; 解決!

用BASH批次改影片名-時間戳轉換與去除前綴

使用BASH修改影片檔名格式 1. 轉換時間戳成日期 舉例說明: 1685877964314.mp4 改成 20230604_192604.mp4  1688511747190.mp4 改成 20230705_070227.mp4 2. 去除前綴詞 舉例說明: video_20230601_204241.mp4 改成 20230601_204241.mp4

連拍照片轉成gif或影片(ffmpeg)

跑馬拉松會有場邊幫忙拍照的,有時候給一連串個人照片,我們就可以透過ffmpeg把他們轉成動圖或是影片 ffmpeg照片轉mp4影片 ffmpeg照片轉gif動圖 以下分別介紹轉換方法 ffmpeg照片轉mp4影片 ffmpeg -framerate 3 -i %02d.jpg -c:v libx264 -pix_fmt yuv420p output.mp4 如果覺得轉成的mp4影片速度比較慢,可以把-framerate 3改成-framerate 6或更大得數值;反之,若覺得mp4影片速度較快,可以把-framerate 3改成-framerate 2或更小得數值。 -i %02d.jpg 是指照片檔案的檔名為01.jpg,02.jpg,03.jpg.... ffmpeg照片轉gif動圖 ffmpeg -framerate 3 -i %02d.jpg -loop 0 output.gif 如果覺得轉成的動圖速度比較慢,可以把-framerate 3改成-framerate 6或更大得數值;反之,若覺得動圖速度較快,可以把-framerate 3改成-framerate 2或更小得數值。 -i %02d.jpg 是指照片檔案的檔名為01.jpg,02.jpg,03.jpg.... -loop 0是表示反覆播放 使用上述這個指令產生出來的圖片會有網格感,是因為採用的色盤沒有經過最佳化。 最佳化轉gif動圖 最佳化就是需要分成兩個階段來處理 階段1. 生成使用的顏色色盤 階段2. 轉換成動圖 ffmpeg -i %02d.jpg -vf palettegen palette.png ffmpeg -framerate 3 -i %02d.jpg -i palette.png -lavfi paletteuse - loop 0 output.gif 參數同前面得解釋

ffmpeg將mp4影片轉換成mp3音檔

  ffmpeg將mp4影片轉換成mp3音檔 原來我沒紀錄過這個,不過在AI時代,這些已經不重要了。 只要在google打一句話 convert mp4 video to mp3 audio using ffmpeg in bash, AI就會回答我們了 #!/bin/bash for file in *.mp4; do filename = "${ file % . * }" echo "to mp3 $filename ..." ffmpeg -y -i " $file " -vn -dn -sn -acodec libmp3lame -b:a 128k " $filename .mp3" done ffmpeg的參數 -y 若輸出的檔案已存在,強制覆蓋不詢問 -i 檔案名稱  指定輸入檔案 -vn -dn -sn 不要處理影片(video),資料(data),字幕(subtitle) -acodec 指定音訊編碼器 -b:a 指定audio的碼率(bitrate) 以前紀錄的只有Windows Prompt(命令提示字元)的版本 用ffmpeg轉換任意影片成mp3