除了周末之外的节假日,需要屏蔽广告展现。
容易出错的地方:
- 每个国家的节假日情况不一样,比如美国的节假日,有特别的算法;
- 你手动暂停之后,它会自动给你开启,这是不对的;
- 节假日暂停之后,非节假日自动重新开启;
美国的代码如下:
function main() {
/***
- 美国节假日广告自动暂停/启用脚本(独立版·静默无警告)
- 功能:仅控制名称带”US_”前缀的广告计划,无匹配广告时静默结束
- 优化1:通过专属标签区分脚本自动暂停和用户手动暂停,不干预手动暂停的广告
- 优化2:检测到手动暂停广告则直接终止所有后续流程,完全不进行节假日判断和操作
- 修正:修复标签获取API错误,正确调用 .get() 获取标签迭代器
***/ // 1. 美国核心配置
const US_CONFIG = {
campaignPrefix: “US_”, // 要控制的广告计划前缀
localTimezoneOffset: -5, // 美国东部时区(UTC-5)
autoPauseLabel: “AutoPaused_USHoliday”, // 脚本自动暂停的专属标签
holidays: [
{ name: “元旦”, rule: getNewYearsDay },
{ name: “马丁·路德·金纪念日”, rule: getMartinLutherKingDay },
{ name: “总统日”, rule: getPresidentsDay },
{ name: “阵亡将士纪念日”, rule: getMemorialDay },
{ name: “六月节(自由日)”, rule: getJuneteenth },
{ name: “美国独立纪念日”, rule: getIndependenceDay },
{ name: “劳动节”, rule: getLaborDay },
{ name: “哥伦布纪念日”, rule: getColumbusDay },
{ name: “退伍军人节”, rule: getVeteransDay },
{ name: “感恩节”, rule: getThanksgivingDay },
{ name: “圣诞节”, rule: getChristmasDay }
]
}; // 确保专属标签存在,不存在则创建
ensureLabelExists(US_CONFIG.autoPauseLabel); // 2. 封装获取US广告计划的函数(支持可选标签筛选)
const getUSCampaigns = (labelName = null) => {
let campaignQuery = AdsApp.campaigns().withCondition(Name CONTAINS '${US_CONFIG.campaignPrefix}');
if (labelName) {
campaignQuery = campaignQuery.withCondition(LabelNames CONTAINS '${labelName}');
}
return campaignQuery.get();
}; // 3. 检查是否有US前缀的广告计划:无则直接结束
const initialCampaigns = getUSCampaigns();
if (!initialCampaigns.hasNext()) {
return;
} // ====================== 修正核心:手动暂停检测函数(正确获取标签迭代器) ======================
const hasManualPausedCampaigns = () => {
const usCampaigns = getUSCampaigns(); // 获取所有US广告(不筛选标签)
while (usCampaigns.hasNext()) {
const campaign = usCampaigns.next();
// 手动暂停判定条件:「暂停状态」且「无脚本专属标签」
const isPaused = campaign.isPaused();
if (isPaused) {
// 修正:调用 .get() 获取标签迭代器
let hasAutoLabel = false;
const campaignLabels = campaign.labels().get();
while (campaignLabels.hasNext()) {
const label = campaignLabels.next();
if (label.getName() === US_CONFIG.autoPauseLabel) {
hasAutoLabel = true;
break;
}
}
if (!hasAutoLabel) {
return true;
}
}
}
return false;
}; // 检测到手动暂停广告:直接终止脚本,不执行后续任何节假日判断和操作
if (hasManualPausedCampaigns()) {
console.log(【终止】检测到存在手动暂停的US广告系列,脚本跳过所有节假日判断和操作,保持手动暂停状态);
return;
}
// ============================================================================= // 4. 计算当前年份的美国节假日
const currentYear = new Date().getFullYear();
const usHolidays = US_CONFIG.holidays.map(holiday => {
const localHolidayDate = holiday.rule(currentYear);
const hkPauseTime = convertLocalToHongKongTime(localHolidayDate, US_CONFIG.localTimezoneOffset);
const hkEnableTime = new Date(hkPauseTime);
hkEnableTime.setDate(hkEnableTime.getDate() + 1); return {
name:${holiday.name}(${currentYear}),
pauseTime: hkPauseTime,
enableTime: hkEnableTime
};
}); // 5. 获取当前香港时间
const currentHkTime = getCurrentHongKongTime();
console.log(【美国节假日脚本】当前香港时间:${formatDate(currentHkTime)}); // 6. 遍历节假日,执行暂停/启用操作
usHolidays.forEach(holiday => {
console.log(\n【校验】${holiday.name}:香港暂停时间=${formatDate(holiday.pauseTime)},启用时间=${formatDate(holiday.enableTime)}); // 处于节假日:暂停广告(添加专属标签后再暂停)
if (currentHkTime >= holiday.pauseTime && currentHkTime < holiday.enableTime) {
let pauseCount = 0;
const usCampaigns = getUSCampaigns();
while (usCampaigns.hasNext()) {
const campaign = usCampaigns.next();
if (campaign.isEnabled()) {
campaign.applyLabel(US_CONFIG.autoPauseLabel);
campaign.pause();
pauseCount++;
console.log(【暂停】广告计划:${campaign.getName()});
}
}
console.log(【结果】${holiday.name}:共暂停${pauseCount}个US广告计划); // 节假日已结束:启用广告(仅启用带专属标签的暂停广告)
} else if (currentHkTime >= holiday.enableTime) {
let enableCount = 0;
const usCampaigns = getUSCampaigns(US_CONFIG.autoPauseLabel);
while (usCampaigns.hasNext()) {
const campaign = usCampaigns.next();
if (campaign.isPaused()) {
campaign.enable();
campaign.removeLabel(US_CONFIG.autoPauseLabel);
enableCount++;
console.log(【启用】广告计划:${campaign.getName()});
}
}
console.log(【结果】${holiday.name}:共启用${enableCount}个脚本自动暂停的US广告计划); // 未到节假日:无操作
} else {
console.log(【结果】${holiday.name}:未到节假日,无需操作);
}
});
}/***
- 工具函数
***/
function getCurrentHongKongTime() {
const now = new Date();
const utcTime = now.getTime() + (now.getTimezoneOffset() * 60 * 1000);
return new Date(utcTime + 8 * 60 * 60 * 1000);
}function convertLocalToHongKongTime(localDate, localUtcOffset) {
const localTimeInUtc = localDate.getTime() – (localUtcOffset * 60 * 60 * 1000);
const hkTime = new Date(localTimeInUtc + 8 * 60 * 60 * 1000);
hkTime.setHours(13, 0, 0, 0);
return hkTime;
}function formatDate(date) {
return${date.getFullYear()}-${String(date.getMonth()+1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')};
}// 确保标签存在,不存在则创建
function ensureLabelExists(labelName) {
let labelExists = false;
const labels = AdsApp.labels().get();
while (labels.hasNext()) {
const label = labels.next();
if (label.getName() === labelName) {
labelExists = true;
break;
}
}
if (!labelExists) {
AdsApp.createLabel(labelName);
console.log(【初始化】创建专属标签:${labelName});
}
}/***
- 美国节假日规则函数
***/
function getNewYearsDay(year) {
const date = new Date(year, 0, 1);
return adjustWeekendHoliday(date);
}function getMartinLutherKingDay(year) {
return getNthWeekdayInMonth(year, 0, 3, 1);
}function getPresidentsDay(year) {
return getNthWeekdayInMonth(year, 1, 3, 1);
}function getMemorialDay(year) {
return getLastWeekdayInMonth(year, 4, 1);
}function getJuneteenth(year) {
const date = new Date(year, 5, 19);
return adjustWeekendHoliday(date);
}function getIndependenceDay(year) {
const date = new Date(year, 6, 4);
return adjustWeekendHoliday(date);
}function getLaborDay(year) {
return getNthWeekdayInMonth(year, 8, 1, 1);
}function getColumbusDay(year) {
return getNthWeekdayInMonth(year, 9, 2, 1);
}function getVeteransDay(year) {
const date = new Date(year, 10, 11);
return adjustWeekendHoliday(date);
}function getThanksgivingDay(year) {
return getNthWeekdayInMonth(year, 10, 4, 4);
}function getChristmasDay(year) {
const date = new Date(year, 11, 25);
return adjustWeekendHoliday(date);
}function getNthWeekdayInMonth(year, month, nth, weekday) {
let date = new Date(year, month, 1);
while (date.getDay() !== weekday) date.setDate(date.getDate() + 1);
date.setDate(date.getDate() + (nth – 1) * 7);
return date;
}function getLastWeekdayInMonth(year, month, weekday) {
let date = new Date(year, month + 1, 0);
while (date.getDay() !== weekday) date.setDate(date.getDate() – 1);
return date;
}function adjustWeekendHoliday(date) {
const day = date.getDay();
if (day === 0) date.setDate(date.getDate() + 1);
if (day === 6) date.setDate(date.getDate() – 1);
return date;
}
请参考美国广告系列的做法,修改新西兰的广告系列的JavaScript代码。
function main() {
/***
- 新西兰节假日广告自动暂停/启用脚本(独立版·静默无警告)
- 功能:仅控制名称带”NZ_”前缀的广告计划,无匹配广告时静默结束
- 说明:包含新西兰全国通用法定假日,适配新西兰标准时间(NZST,UTC+12)
- 优化1:通过NZ专属标签区分脚本自动暂停和用户手动暂停,不干预手动暂停的广告
- 优化2:检测到手动暂停广告则直接终止所有后续流程,完全不进行节假日判断和操作
- 优化3:修复标签获取API,符合Google Ads脚本官方规范,与其他地区版本保持一致
***/ // 1. 新西兰核心配置(新增:NZ专属暂停标签,避免与其他地区版本标签冲突)
const NZ_CONFIG = {
campaignPrefix: “NZ_”, // 要控制的广告计划前缀
localTimezoneOffset: 12, // 新西兰标准时间(NZST,UTC+12,夏令时自动适配)
autoPauseLabel: “AutoPaused_NZHoliday”, // NZ脚本专属暂停标签(独立隔离,避免冲突)
holidays: [
{ name: “元旦”, rule: getNewYearsDayNZ },
{ name: “怀唐伊日”, rule: getWaitangiDayNZ },
{ name: “耶稣受难节”, rule: getGoodFridayNZ },
{ name: “复活节星期一”, rule: getEasterMondayNZ },
{ name: “澳新军团日”, rule: getAnzacDayNZ },
{ name: “女王生日”, rule: getQueensBirthdayNZ },
{ name: “劳动节”, rule: getLabourDayNZ },
{ name: “圣诞节”, rule: getChristmasDayNZ },
{ name: “节礼日”, rule: getBoxingDayNZ }
]
}; // 【新增】确保NZ专属标签存在,不存在则自动创建(无需手动在后台配置)
ensureLabelExists(NZ_CONFIG.autoPauseLabel); // 2. 封装获取NZ广告计划的函数(优化:支持可选标签筛选,精准定位脚本标记广告)
const getNZCampaigns = (labelName = null) => {
let campaignQuery = AdsApp.campaigns().withCondition(Name CONTAINS '${NZ_CONFIG.campaignPrefix}');
// 传入标签名称时,仅筛选带该标签的广告(节假日结束后专用,避免操作手动暂停广告)
if (labelName) {
campaignQuery = campaignQuery.withCondition(LabelNames CONTAINS '${labelName}');
}
return campaignQuery.get();
}; // 3. 检查是否有NZ前缀的广告计划:无则直接结束,无任何提示
const initialCampaigns = getNZCampaigns();
if (!initialCampaigns.hasNext()) {
return; // 仅提前结束,无日志输出
} // ====================== 新增核心:手动暂停检测函数(适配NZ标签,符合官方API) ======================
const hasManualPausedCampaigns = () => {
const nzCampaigns = getNZCampaigns(); // 获取所有NZ广告(不筛选标签)
while (nzCampaigns.hasNext()) {
const campaign = nzCampaigns.next();
// 手动暂停判定条件:「暂停状态」且「无NZ专属脚本标签」
const isPaused = campaign.isPaused();
if (isPaused) {
// 正确获取标签迭代器(campaign.labels().get(),符合Google Ads API规范)
let hasAutoLabel = false;
const campaignLabels = campaign.labels().get();
while (campaignLabels.hasNext()) {
const label = campaignLabels.next();
if (label.getName() === NZ_CONFIG.autoPauseLabel) {
hasAutoLabel = true;
break; // 找到目标标签,终止内层遍历提升执行效率
}
}
// 存在「暂停+无NZ专属标签」的广告,即为手动暂停,直接返回true
if (!hasAutoLabel) {
return true;
}
}
}
return false;
}; // 检测到手动暂停广告:直接终止脚本,不执行后续任何节假日判断和操作
if (hasManualPausedCampaigns()) {
console.log(【终止】检测到存在手动暂停的NZ广告系列,脚本跳过所有节假日判断和操作,保持手动暂停状态);
return;
}
// ============================================================================= // 4. 计算当前年份的新西兰节假日(完全保留原有NZ逻辑,无修改)
const currentYear = new Date().getFullYear();
const nzHolidays = NZ_CONFIG.holidays.map(holiday => {
const localHolidayDate = holiday.rule(currentYear);
const hkPauseTime = convertLocalToHongKongTime(localHolidayDate, NZ_CONFIG.localTimezoneOffset);
const hkEnableTime = new Date(hkPauseTime);
hkEnableTime.setDate(hkEnableTime.getDate() + 1); return {
name:${holiday.name}(${currentYear}),
pauseTime: hkPauseTime,
enableTime: hkEnableTime
};
}); // 5. 获取当前香港时间(保持原有逻辑,与其他地区版本一致)
const currentHkTime = getCurrentHongKongTime();
console.log(【新西兰节假日脚本】当前香港时间:${formatDate(currentHkTime)}); // 6. 遍历节假日,执行暂停/启用操作(优化:添加NZ标签闭环逻辑,不改动原有操作逻辑)
nzHolidays.forEach(holiday => {
console.log(\n【校验】${holiday.name}:香港暂停时间=${formatDate(holiday.pauseTime)},启用时间=${formatDate(holiday.enableTime)}); // 处于节假日:暂停广告(优化:添加NZ专属标签后再暂停,标记为脚本操作)
if (currentHkTime >= holiday.pauseTime && currentHkTime < holiday.enableTime) {
let pauseCount = 0;
const nzCampaigns = getNZCampaigns();
while (nzCampaigns.hasNext()) {
const campaign = nzCampaigns.next();
if (campaign.isEnabled()) {
// 新增:添加NZ专属脚本标签,区分脚本暂停与手动暂停
campaign.applyLabel(NZ_CONFIG.autoPauseLabel);
campaign.pause();
pauseCount++;
console.log(【暂停】广告计划:${campaign.getName()});
}
}
console.log(【结果】${holiday.name}:共暂停${pauseCount}个NZ广告计划); // 节假日已结束:启用广告(优化:仅启用带NZ专属标签的暂停广告,排除手动暂停)
} else if (currentHkTime >= holiday.enableTime) {
let enableCount = 0;
// 新增:仅筛选带NZ专属标签的广告,避免操作手动暂停的广告
const nzCampaigns = getNZCampaigns(NZ_CONFIG.autoPauseLabel);
while (nzCampaigns.hasNext()) {
const campaign = nzCampaigns.next();
if (campaign.isPaused()) {
campaign.enable();
// 新增:移除NZ专属标签,避免后续重复处理,恢复广告初始状态
campaign.removeLabel(NZ_CONFIG.autoPauseLabel);
enableCount++;
console.log(【启用】广告计划:${campaign.getName()});
}
}
console.log(【结果】${holiday.name}:共启用${enableCount}个脚本自动暂停的NZ广告计划); // 未到节假日:无操作
} else {
console.log(【结果】${holiday.name}:未到节假日,无需操作);
}
});
}/***
- 工具函数(新增:ensureLabelExists,其余完全保留原有NZ版逻辑)
***/
function getCurrentHongKongTime() {
const now = new Date();
const utcTime = now.getTime() + (now.getTimezoneOffset() * 60 * 1000);
return new Date(utcTime + 8 * 60 * 60 * 1000);
}function convertLocalToHongKongTime(localDate, localUtcOffset) {
const localTimeInUtc = localDate.getTime() – (localUtcOffset * 60 * 60 * 1000);
const hkTime = new Date(localTimeInUtc + 8 * 60 * 60 * 1000);
hkTime.setHours(13, 0, 0, 0);
return hkTime;
}function formatDate(date) {
return${date.getFullYear()}-${String(date.getMonth()+1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')};
}// 【新增】确保NZ专属标签存在,不存在则创建(与其他地区版本标签隔离,避免冲突)
function ensureLabelExists(labelName) {
let labelExists = false;
const labels = AdsApp.labels().get();
while (labels.hasNext()) {
const label = labels.next();
if (label.getName() === labelName) {
labelExists = true;
break;
}
}
if (!labelExists) {
AdsApp.createLabel(labelName);
console.log(【初始化】创建NZ专属标签:${labelName});
}
}/***
- 新西兰节假日规则函数(完全保留原有NZ版逻辑,无任何修改)
***/
function getNewYearsDayNZ(year) {
const date = new Date(year, 0, 1);
const day = date.getDay();
if (day === 0) date.setDate(date.getDate() + 1); // 周日→1月2日
if (day === 6) date.setDate(date.getDate() + 2); // 周六→1月2日
return date;
}function getWaitangiDayNZ(year) {
const date = new Date(year, 1, 6);
const day = date.getDay();
if (day === 0) date.setDate(date.getDate() + 1); // 周日→2月7日
if (day === 6) date.setDate(date.getDate() + 2); // 周六→2月8日
return date;
}function getGoodFridayNZ(year) {
const easterSunday = calculateEasterSundayNZ(year);
const goodFriday = new Date(easterSunday);
goodFriday.setDate(easterSunday.getDate() – 2);
return goodFriday;
}function getEasterMondayNZ(year) {
const easterSunday = calculateEasterSundayNZ(year);
const easterMonday = new Date(easterSunday);
easterMonday.setDate(easterSunday.getDate() + 1);
return easterMonday;
}function getAnzacDayNZ(year) {
const date = new Date(year, 3, 25);
const day = date.getDay();
if (day === 0) date.setDate(date.getDate() + 1); // 周日→4月26日
if (day === 6) date.setDate(date.getDate() + 2); // 周六→4月27日
return date;
}function getQueensBirthdayNZ(year) {
return getNthWeekdayInMonth(year, 5, 1, 1);
}function getLabourDayNZ(year) {
return getNthWeekdayInMonth(year, 9, 4, 1);
}function getChristmasDayNZ(year) {
const date = new Date(year, 11, 25);
const day = date.getDay();
if (day === 0) date.setDate(date.getDate() + 1); // 周日→12月26日
if (day === 6) date.setDate(date.getDate() + 2); // 周六→12月27日
return date;
}function getBoxingDayNZ(year) {
const date = new Date(year, 11, 26);
const day = date.getDay();
if (day === 0) date.setDate(date.getDate() + 1); // 周日→12月27日
if (day === 6) date.setDate(date.getDate() + 2); // 周六→12月28日
return date;
}function calculateEasterSundayNZ(year) {
const a = year % 19;
const b = Math.floor(year / 100);
const c = year % 100;
const d = Math.floor(b / 4);
const e = b % 4;
const f = Math.floor((b + 8) / 25);
const g = Math.floor((b – f + 1) / 3);
const h = (19 * a + b – d – g + 15) % 30;
const i = Math.floor(c / 4);
const k = c % 4;
const l = (32 + 2 * e + 2 * i – h – k) % 7;
const m = Math.floor((a + 11 * h + 22 * l) / 451);
const month = Math.floor((h + l – 7 * m + 114) / 31);
const day = ((h + l – 7 * m + 114) % 31) + 1;
return new Date(year, month – 1, day);
}// 通用工具函数(复用,保留原有逻辑)
function getNthWeekdayInMonth(year, month, nth, weekday) {
let date = new Date(year, month, 1);
while (date.getDay() !== weekday) date.setDate(date.getDate() + 1);
date.setDate(date.getDate() + (nth – 1) * 7);
return date;
}function getLastWeekdayInMonth(year, month, weekday) {
let date = new Date(year, month + 1, 0);
while (date.getDay() !== weekday) date.setDate(date.getDate() – 1);
return date;
}

