📅 行事曆語音提醒
忙碌的工作中,難免會忘記即將到來的會議。讓 Rose 幫你監控行事曆,在重要時刻前用語音提醒你——就像有位貼心秘書在旁邊。
情境描述
適用場景
| 場景 | 提醒時機 | 提醒方式 |
|---|---|---|
| 📞 客戶會議 | 會議前 15 分鐘 | 語音 + 文字 |
| 👥 團隊會議 | 會議前 10 分鐘 | 語音提醒 |
| 🎯 重要截止日 | 截止前 1 天 | 語音 + 詳細資訊 |
| ✈️ 出差行程 | 出發前 2 小時 | 語音 + 天氣資訊 |
| 💊 定期提醒 | 每日固定時間 | 簡短語音 |
預期效果
- 🔔 不再錯過會議:提前提醒,有時間準備
- 🎙️ 語音更醒目:比文字通知更難忽略
- 📱 行動中也能收到:手機播放語音,開車也能聽
- ⏰ 多時機提醒:提前一天、一個小時、15 分鐘分層提醒
行事曆連接
支援的行事曆來源
| 來源 | 連接方式 | 設定難度 |
|---|---|---|
| Google Calendar | Google API | ⭐⭐ |
| Microsoft Outlook | Microsoft Graph API | ⭐⭐ |
| CalDAV | 通用協議 | ⭐⭐⭐ |
| 本地行事曆檔案 | 讀取 .ics 檔案 | ⭐ |
Google Calendar 連接設定
{`1. 前往 Google Cloud Console
https://console.cloud.google.com/
2. 建立新專案或選擇現有專案
3. 啟用 Google Calendar API
- 進入「API 和服務」→「程式庫」
- 搜尋「Google Calendar API」
- 點擊「啟用」
4. 建立憑證
- 進入「API 和服務」→「憑證」
- 點擊「建立憑證」→「OAuth 2.0 用戶端 ID」
- 應用程式類型選「桌面應用程式」
- 下載 JSON 憑證檔案
5. 將憑證檔案儲存到:
~/.config/realvco/google-credentials.json`}
行事曆同步腳本
{`// 行事曆同步腳本
const { google } = require('googleapis');
const fs = require('fs');
async function getUpcomingEvents() {
// 載入憑證
const credentials = JSON.parse(
fs.readFileSync(process.env.GOOGLE_CREDENTIALS_PATH)
);
// 建立 OAuth2 客戶端
const { client_secret, client_id, redirect_uris } = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]
);
// 設定 Token(需先執行授權流程取得)
oAuth2Client.setCredentials({
access_token: process.env.GOOGLE_ACCESS_TOKEN,
refresh_token: process.env.GOOGLE_REFRESH_TOKEN
});
// 呼叫 Calendar API
const calendar = google.calendar({ version: 'v3', auth: oAuth2Client });
const now = new Date();
const tomorrow = new Date(now);
tomorrow.setDate(tomorrow.getDate() + 1);
const response = await calendar.events.list({
calendarId: 'primary',
timeMin: now.toISOString(),
timeMax: tomorrow.toISOString(),
singleEvents: true,
orderBy: 'startTime'
});
return response.data.items;
}
module.exports = { getUpcomingEvents };`}
語音提醒設定
語音提醒流程
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 檢查行事曆 │ → │ 判斷提醒時機 │ → │ 生成語音內容 │
├──────────────┤ ├──────────────┤ ├──────────────┤
│ 每 5 分鐘 │ │ • 15 分鐘前 │ │ • 會議名稱 │
│ 讀取事件 │ │ • 1 小時前 │ │ • 開始時間 │
│ │ │ • 1 天前 │ │ • 地點/連結 │
└──────────────┘ └──────────────┘ └──────┬───────┘
│
▼
┌──────────────┐
│ 發送提醒 │
├──────────────┤
│ • 文字訊息 │
│ • 語音訊息 │
│ • 手機推播 │
└──────────────┘
語音內容模板
{`# 會議前 15 分鐘提醒
⏰ 會議即將開始!
「金大,您的會議再過 15 分鐘就要開始了。
會議名稱:{meeting_title}
時間:{start_time}
地點:{location}
準備好了嗎?」
---
# 會議前 1 小時提醒
📅 會議提醒
「金大,1 小時後有個會議。
{meeting_title},{start_time} 開始。
{description}
別忘了準備相關資料!」
---
# 每日早晨預告
📋 今日行程
「金大早安!今天有 {count} 個行程:
{for each event}
- {time}:{title}
{/for}
祝今天順利!」`}
語音發送設定
{`# 語音提醒設定
tts:
provider: elevenlabs # 或 google, azure
voice_id: nova # 語音選擇
language: zh-TW # 繁體中文
reminders:
- name: meeting_15min
trigger: "event.start - 15 minutes"
message_template: "meeting_15min"
channels:
- telegram_voice
- telegram_text
- name: meeting_1hour
trigger: "event.start - 1 hour"
message_template: "meeting_1hour"
channels:
- telegram_text
- name: daily_briefing
trigger: "08:00 daily"
message_template: "daily_morning"
channels:
- telegram_voice
- name: deadline_alert
trigger: "deadline - 1 day"
message_template: "deadline_reminder"
channels:
- telegram_voice
- telegram_text`}
排程配置
Heartbeat 定期檢查
{`// Heartbeat 提醒檢查
const { getUpcomingEvents } = require('./calendar-sync');
const { sendVoiceMessage } = require('./telegram-bot');
const { generateTTS } = require('./tts-service');
async function checkReminders() {
const now = new Date();
const events = await getUpcomingEvents();
for (const event of events) {
const startTime = new Date(event.start.dateTime);
const diffMinutes = (startTime - now) / (1000 * 60);
// 檢查是否該發送 15 分鐘提醒
if (diffMinutes > 14 && diffMinutes < 15) {
await sendMeetingReminder(event, '15min');
}
// 檢查是否該發送 1 小時提醒
if (diffMinutes > 59 && diffMinutes < 60) {
await sendMeetingReminder(event, '1hour');
}
}
}
async function sendMeetingReminder(event, timing) {
const templates = {
'15min': `金大,您的會議再過 15 分鐘就要開始了。會議名稱:${event.summary}。時間:${formatTime(event.start.dateTime)}。`,
'1hour': `金大,1 小時後有個會議。${event.summary},${formatTime(event.start.dateTime)}開始。`
};
const message = templates[timing];
// 生成語音
const voiceBuffer = await generateTTS(message);
// 發送語音訊息
await sendVoiceMessage({
chat_id: process.env.ADMIN_CHAT_ID,
voice: voiceBuffer,
caption: message
});
console.log(`✅ 已發送 ${timing} 提醒:${event.summary}`);
}
// 每 5 分鐘檢查一次
setInterval(checkReminders, 5 * 60 * 1000);
module.exports = { checkReminders };`}
Cron 排程設定
{`# 每天早上 8 點發送今日行程預告
0 8 * * * cd /home/node/.openclaw/workspace && node scripts/daily-briefing.js
# 每 5 分鐘檢查即將到來的會議
*/5 * * * * cd /home/node/.openclaw/workspace && node scripts/check-reminders.js
# 每天晚上 9 點預告明天行程
0 21 * * * cd /home/node/.openclaw/workspace && node scripts/tomorrow-preview.js`}
進階應用
智能提醒升級
{`# 智能情境提醒
## 出差提醒
「金大,2 小時後要出發去機場了。
航班:{flight_number}
目的地:{destination}
當地天氣:{weather}
別忘記帶護照和充電器!」
## 客戶會議準備
「金大,30 分鐘後與 {client_name} 有會議。
上次對話紀錄:
{last_conversation_summary}
待確認事項:
{pending_items}
相關文件:
{relevant_documents}`}
多層提醒機制
重要會議(標記為重要):
├── 1 天前:詳細準備提醒 + 相關文件
├── 1 小時前:出發提醒 + 交通資訊
├── 15 分鐘前:立即準備提醒
└── 1 分鐘前:最後確認
一般會議:
└── 15 分鐘前:標準提醒
截止日:
├── 3 天前:提早準備提醒
├── 1 天前:明日截止提醒
└── 當天早上:今日截止提醒
與其他系統整合
{`# 與天氣 API 整合
會議地點在外縣市時,自動附加:
「台北明天有雨,記得帶傘!」
# 與交通 API 整合
會議地點不同時,提醒:
「預估車程 30 分鐘,建議 2:30 出發」
# 與 CRM 整合
客戶會議前,自動提醒:
「這是第三次與 XX 公司會議,
上次討論到 {previous_topic},
這次主要目標是 {meeting_goal}`}
常見問題
Q: 語音提醒聽不清楚怎麼辦?
- 選擇更清晰的語音模型
- 調整語速(建議 0.9-1.1 倍)
- 同時發送文字版本備份
- 測試不同環境(安靜/嘈雜)
Q: 可以調整提醒時間嗎?
可以!修改設定檔:
reminders:
- trigger: "event.start - 30 minutes" # 改為 30 分鐘前
Q: 如何暫停某個提醒?
在行事曆事件中加入標籤:
#no-reminder:完全不提醒#silent:只發文字,不發語音
Q: 支援哪些語音平台?
目前支援:
- ElevenLabs(品質最佳)
- Google Cloud Text-to-Speech
- Azure Cognitive Services
- 系統內建 TTS(免費但品質較差)
小結
📅 行事曆語音提醒讓你再也不錯過重要時刻:>
- 連接行事曆:Google/Outlook 自動同步> - 多時機提醒:提前一天、一小時、15 分鐘分層提醒> - 語音通知:比文字更醒目,開車也能聽> - 智能升級:結合天氣、交通、CRM 提供更完整資訊