コンテンツカレンダーは、どの記事や投稿をいつ・どのチャネルで出すかを1枚にまとめた計画表です。作ること自体は難しくありません。難しいのは、公開直前の差し替えや承認待ちが積み上がっても更新され続ける状態を保つことです。この記事では、持たせる列の設計からGoogleスプレッドシートでのテンプレート化、承認通知の自動化、専用ツールへ乗り換える判断ラインまでを、公式ドキュメントの数値に沿って整理します。
まとめ:コンテンツカレンダーの要点
- コンテンツカレンダーは公開計画の台帳です。エディトリアルカレンダーは編集方針やテーマの中長期計画を指す場合があり、SNSコンテンツカレンダーはSNS投稿の計画に限定した呼び方です。
- 最初に決めるのは列です。公開日・チャネル・担当・ステータス・成果指標の5系統を型付きで持たせれば、後からSEO用の列もSNS用の列も足せます。
- Googleスプレッドシートは1ファイル1,000万セルまで使えるため、年間数千件の投稿計画なら容量面で乗り換える理由になりません。
- 承認待ちの確認や進捗確認に時間を使っているなら、通知の自動化を優先します。投稿作業の負担が大きい場合は、予約投稿やAPI連携も比較対象です。Apps Scriptのトリガーは無料アカウントで1日90分まで動きます。
- 専用ツールへ移る理由は容量ではなく権限と履歴です。無料枠の人数上限は製品ごとに違い、AsanaのPersonalは2人まで、TrelloのFreeはワークスペースあたり10人までです。
以下、列の設計から順に具体化します。
コンテンツカレンダーの定義と呼び分け
エディトリアルカレンダー、SNSコンテンツカレンダーとの関係
呼び名の使い方は組織によって異なります。Asana公式では、エディトリアルカレンダーを中長期の編集計画(quarterly or annual planning)、コンテンツカレンダーを日々の制作・公開計画(day-to-day content production)として区別しています。一方、雑誌の編集台割に由来する語であることから、オウンドメディアの記事公開計画そのものをエディトリアルカレンダーと呼ぶ現場も多くあります。SNSコンテンツカレンダーはX、Instagram、LINEなどの投稿計画に限定した呼び方です。この記事では、記事とSNS投稿の両方を1枚で扱う表をコンテンツカレンダーと呼びます。
呼称より重要なのは、記事とSNS投稿を同じ表に混ぜるかどうかの判断です。記事とSNS投稿で制作リードタイムや更新頻度が異なる場合に、同じ一覧では直近の作業を追いにくくなります。チャネル列で分けたうえで、月次のキャンペーンだけを共通の親行にひもづける形が扱いやすくなります。SNSマーケティングとは?主要SNSの特徴・手法・始め方と外注判断【2026年版】で整理しているチャネル別の特性は、この頻度差の裏付けになります。
タスク管理ツールやCMSの公開予約との役割分担
カレンダーとタスク管理ツールは競合しません。カレンダーが答えるのは「いつ何が世に出るか」で、タスク管理ツールが答えるのは「誰が今日何をやるか」です。両方を1つの表に押し込むと、公開済みの行と作業中のサブタスクが同じ画面に並び、外部から見たときの公開計画が読めなくなります。
CMSやSNS側の公開予約機能も別物です。YouTubeであればYouTube Studioの「スケジュールを設定」カードで公開日時を指定できますが、これは決まったものを流す仕組みであり、決める前の検討状態は持てません。企画・執筆・レビュー・承認という公開前の状態遷移を保持するのがカレンダーの役割で、予約機能はその出口にあたります。
カレンダーに持たせる列の設計
どのチャネルでも必要になる基本列
列は後から足せますが、途中で型を変えると過去行が壊れます。最初に日付列を日付型、ステータス列をプルダウン(データの入力規則)で固定しておくと、後述する数式と自動化がそのまま乗ります。
| 列名 | 型 | 入力例 | 用途 |
|---|---|---|---|
| content_id | 文字列 | 2026-10-B-014 | 行の一意キー |
| 公開日 | 日付 | 2026-10-14 | 並べ替えと週次抽出 |
| チャネル | プルダウン | ブログ | 頻度の異なる行の分離 |
| タイトル | 文字列 | 在庫引当の設計 | 識別 |
| 担当 | プルダウン | 佐藤 | 通知の宛先 |
| ステータス | プルダウン | 承認待ち | 状態遷移 |
| 承認期限 | 日付 | 2026-10-10 | 遅延検知 |
| 公開URL | 文字列 | https://example.com/a/ | 実績突合 |
content_idを年月とチャネル頭文字と連番で組むのは、行を並べ替えても識別子が壊れないようにするためです。行番号を識別子に使うと、途中に1行挿入した瞬間に過去の議事録やSlackの言及が全部ずれます。
SEO記事とSNS投稿で追加する列
記事側に足すのは、対策キーワード、検索ボリューム、想定検索意図、内部リンク先の4列です。企画時点では読者と検索意図を明確にし、検索ボリュームや内部リンク先は調査の進行に応じて補完します。SNS側に足すのは、投稿本文、素材のリンク、ハッシュタグ、そして連動するキャンペーン名です。キャンペーン名を共通の列名でそろえておくと、チャネルをまたいだ調整がフィルタ一発で済みます。
成果指標の列は、公開後に手で埋める前提にしないでください。表示回数やクリック数は媒体側のAPIやレポートから実績用シートに取り込み、content_idで公開計画と対応付けます。カレンダーには実績への参照先と更新日を持たせます。集計をカレンダーの中でやり始めると、表が重くなるうえに数式の壊れた行が混ざっても誰も気づきません。
Googleスプレッドシートで作る手順とテンプレート化
シート分割とマスタ参照
1ファイルの中を、行が増え続けるcalendarシート、値を固定するmasterシート、見るためのweeklyシートの3枚に分けます。masterにはチャネル名、担当者名、ステータス名を縦に並べ、calendar側のプルダウンはこの範囲を参照させます。表記ゆれが起きなくなるので、後の数式が壊れません。
容量を心配する必要はありません。Googleスプレッドシートの上限は公式ヘルプに「Up to 10 million cells or 18,278 columns (column ZZZ)」と明記されています。1,000万セルを40列だけに割り当てた理論値は25万行ですが、実際には同じファイル内のmasterやweeklyなどのセルも含まれます。週20本を10年間登録する想定なら、年間52週として約1万400行です。スプレッドシートを離れる理由は容量ではなく、権限分離と同時編集の運用です。
FILTERによる直近7日間の公開予定ビュー
weeklyシートには、今日から6日後までに公開予定で、まだ公開済みになっていない行を自動で表示します。FILTERの構文は公式ヘルプで「FILTER(範囲, 条件1, [条件2, …])」と定義されており、条件は範囲と同じ行数のまま複数並べられます。
=FILTER(
calendar!A2:H,
calendar!B2:B >= TODAY(),
calendar!B2:B < TODAY() + 7,
calendar!F2:F <> "公開済み"
)
B列が公開日、F列がステータスです。3つ目の条件で公開済みを外しているのは、週次の編集会議で見たいのが「まだ動かせる行」だけだからです。この式をweeklyシートのA1に置くと、抽出結果が空いているセルへ展開されます。表示先は空けておき、該当行がない場合は#N/Aになるため、必要に応じて式全体をIFNAで囲んでください。
条件付き書式による承認期限超過の表示
承認期限を過ぎた行に色を付けます。calendarシートのA2からH列までを選び、条件付き書式のカスタム数式に次を入れます。
=AND(ISNUMBER($G2), $G2 < TODAY(), $F2 = "承認待ち")
G列が承認期限、F列がステータスです。$を列記号に付けると、横方向に判定するセルが移ってもG列とF列を参照します。行番号は固定していないため、各行の承認期限とステータスで判定します。ここまで作ったファイルを「ファイル」から「コピーを作成」しておけば、それが自社用のテンプレートです。配布用のテンプレートを外部から探す前に、自社のチャネル名と担当者名が入った1枚を作るほうが定着します。
手作業を残さない自動化の順序
承認期限超過のSlack通知
承認待ちの確認に時間がかかっているチームでは、まず期限超過の通知を自動化します。工数を実際に食っているのは、承認待ちの行を目で探して担当者をつつく作業と、公開後にステータスを手で書き換える作業だからです。投稿の自動送信は本数が少なく、止まったときの被害が大きいため、後回しにできます。
次のApps Scriptは、承認期限を過ぎた承認待ちの行をSlackへまとめて通知する例です。対象シートの「拡張機能」からApps Scriptを開き、Slackで発行したIncoming Webhook URLを設定して、初回は手動実行で権限を承認してください。UrlFetchApp.fetchのparamsに指定できるキーはmethod、contentType、payload、headers、muteHttpExceptionsなどで、タイムアウトは既定360秒です。
const WEBHOOK_URL = 'https://hooks.slack.com/services/XXX/YYY/ZZZ';
function notifyOverdueApprovals() {
const sheet = SpreadsheetApp.getActive().getSheetByName('calendar');
const rows = sheet.getDataRange().getValues();
const today = new Date();
today.setHours(0, 0, 0, 0);
const overdue = [];
for (let i = 1; i < rows.length; i++) {
const title = rows[i][3];
const owner = rows[i][4];
const status = rows[i][5];
const due = rows[i][6];
if (status !== '承認待ち') continue;
if (!(due instanceof Date)) continue;
if (due.getTime() >= today.getTime()) continue;
overdue.push(title + '(担当:' + owner + ')');
}
if (overdue.length === 0) return;
UrlFetchApp.fetch(WEBHOOK_URL, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify({
text: '承認期限を過ぎた行が' + overdue.length + '件あります\n' + overdue.join('\n')
}),
muteHttpExceptions: false
});
}
1回のfetchにまとめているのは通信量の節約ではありません。Slackのchat.postMessageは公式ドキュメントに「It will generally allow an app to post 1 message per second to a specific channel.」と書かれており、遅延行を1件ずつ送ると同じチャンネルへ毎秒1通の壁に当たります。Slackの公式レート制限ではIncoming Webhooksも原則毎秒1件です。この例では遅延行をまとめて送信しますが、長文になる場合はメッセージを分割し、送信間隔を調整します。
Apps Scriptの実行時間上限と一括読み取り
Apps Scriptには実行時間の上限があります。公式のQuotas for Google Servicesでは、Script runtimeが無料アカウント・Google Workspaceアカウントともに「6 min / execution」、時間主導トリガーの合計実行時間(Triggers total runtime)が無料アカウントで「90 min / day」、Workspaceアカウントで「6 hr / day」です。
この数字が意味するのは、1回の実行を6分以内に収める設計が必須だということです。getDataRange().getValues()で全行を一度に配列へ読み、ループの中でgetRange()を呼ばないのはそのためです。行ごとのシートアクセスはサービス呼び出しを増やすため、一括読み取りより実行時間が長くなることがあります。トリガーは1日1回、始業前の8時台に1本だけ置けば、無料アカウントの90分に対して十分な余裕が残ります。5分おきに回す必要はありません。
スクリプトに外部通信とスプレッドシートの読み書き権限を与える以上、承認範囲は事前に確認してください。権限の設計と公開設定の考え方はGASのセキュリティ|危険とされる理由と権限・公開設定・管理者統制の実務で扱っています。
投稿APIの利用制限と導入費用の比較
投稿そのものをAPIで自動化する前に、上限を確認します。Instagramの場合、公式ドキュメントに「Instagram accounts are limited to 100 API-published posts within a 24-hour moving period. Carousels count as a single post.」とあり、24時間で100投稿までです。カルーセルは何枚組でも1投稿として数えられます。1日数本の運用ならこの上限に触れることはなく、API実装の採否は、この上限とは別に、削減できる作業時間と実装・保守費を比較して判断します。
判断には、月間投稿数、1投稿あたりの手作業時間、チャネルごとの加工量、実装費と月々の保守費を使います。削減できる作業費が実装費と保守費を上回る見込みが立った場合に、自動投稿を採用します。個別の仕様と費用はInstagram Graph APIとは?できること・料金・使い方を2026年最新仕様で解説とX API(旧Twitter API)の従量課金と使い方|単価・レート制限・実装を解説で確認できます。
専用ツールへ乗り換える判断ライン
| ツール | 無料プラン | 無料の主な制限 | 有料の下位プラン |
|---|---|---|---|
| Googleスプレッドシート | あり | 1ファイル1,000万セル | Workspace契約に含む |
| Notion | フリー 0円 | 所有者2名以上で1,000ブロック/1ファイル5MB | プラス 1,650円(メンバー/月) |
| Asana | Personal 0円 | ユーザー2人まで | Starter 1,200円(年払い・1ユーザー/月) |
| Trello | Free 0ドル | Workspaceあたり10ボード/10人 | Standard 5ドル(年払い・1ユーザー/月) |
いずれも2026年9月10日時点の公式料金ページ(Notion/Asana/Trello)の表示です。AsanaはStarterが月間払いだと1,475円、Advancedが年払い2,700円・月間払い3,300円と、支払い周期で2割ほど変わります。TrelloのPremiumは年払い10ドル・月払い12.50ドルです。料金は改定されるため、稟議に使う数字は購入前に各ページで再確認してください。
無料枠で先に詰まるのはNotionです。公式ヘルプの表では、フリープランはワークスペース所有者が1人なら無制限ですが、所有者が2人以上になると「1,000 blocks per workspace」に切り替わります。ブロック数は、カレンダーの行数だけでなく各ページ内に作成する段落やチェックボックスなどにも左右されます。設定画面でワークスペースの使用量を確認してください。複数のワークスペース所有者で1,000ブロックを超えて作成するなら、有料化が必要です。所有者1人のまま共同作業者をゲストとして招待する方法も、必要な共有範囲に合うか確認してください。
乗り換えるべき条件
3つのうちどれかに当てはまったら移ります。第一に、社外の制作会社や運用代行が編集に入る場合です。特定の列だけ編集させる制御には保護範囲を使えますが、保護は閲覧やコピーを防ぐ仕組みではありません。外部担当者に見せる情報自体を制限したい場合は、別ファイルに分けるか権限機能のあるツールへ移します。第二に、承認の記録を後から追う必要がある場合です。誰がいつ承認したかをスプレッドシートの編集履歴から復元するのは現実的ではありません。第三に、Asanaの無料プランが2人までであるように、無料枠の人数上限を超えて権限を分けたい場合です。
外部パートナーを入れる前提なら、契約範囲に「カレンダーの更新責任をどちらが持つか」を明記してください。ここが曖昧な案件は、双方が相手の更新を待って表が止まります。SNS運用代行会社の選び方|実績の見極めと契約範囲・KPI要件で外れを避ける判断基準で契約範囲の詰め方を整理しています。
乗り換えなくてよい条件
社内運用で編集範囲を分ける必要がなく、承認記録も所定の方法で残せるなら、スプレッドシートを継続できます。ツールを変えても更新頻度は上がらないからです。テンプレートが豊富だからという理由だけで移行すると、既存の列と移行先のプロパティ型が合わず、データ変換と移行後の確認に手間がかかります。容量やテンプレートの多寡は移行理由になりません。移行理由になるのは権限と履歴です。
カレンダーが形骸化する原因と戻し方
更新が止まる原因は、だいたい3つに絞られます。
1つ目は、埋める列が多すぎることです。企画時点で埋まらない列を必須にすると、行を作る心理的なコストが上がり、そもそも登録されなくなります。企画時に必須なのは公開日・チャネル・タイトル・担当の4列だけにして、残りは着手後に埋める任意列へ落としてください。
2つ目は、実績が返ってこないことです。公開後の表示回数やクリック数がカレンダーに戻らないと、来月の企画が前月のコピーになります。月初に1回、前月分の実績を貼る時間を30分だけ固定枠で取るほうが、日次で自動集計する仕組みを作るより先に効きます。
3つ目は、承認待ちの行が滞留していることです。滞留自体は起きるものなので、滞留を検知できるかどうかが分かれ目になります。前述の条件付き書式と通知が効くのはここで、期限を過ぎた行が毎朝Slackに出るようになると、対応が必要な案件を把握できます。承認の平均待ち日数を測るには、承認依頼日と承認完了日を別途記録し、その差を集計します。カレンダーを見に行かせるのではなく、カレンダーから声をかけさせる構造にするのが復旧の要点です。
なお、カレンダーを作り直すのは最後の手段です。列を作り直す前に、更新担当と更新のタイミングが決まっているかを確認してください。週次の枠を先に決めてから、必要な列だけを足すほうが早く戻ります。
よくある質問
コンテンツカレンダーとエディトリアルカレンダーは何が違いますか?
同じ意味で使われる場合もありますが、エディトリアルカレンダーを中長期の編集方針やテーマの計画として区別する場合もあります。この記事では、記事とSNS投稿の両方を含む公開計画をコンテンツカレンダーと呼んでいます。社内で両方の呼び名が混在しているなら、表の名前をどちらかに統一するだけで会話が通じるようになります。
コンテンツカレンダーには最低限どの項目を書けばよいですか?
基本は公開日、チャネル、タイトル、担当、ステータスの5列です。本文の承認遅延検知には承認期限も必要で、掲載コードを使う場合は基本列の表にある8列を同じ順序で配置してください。対策キーワードや成果指標は、公開までの運用が回り始めてから足してください。最初から20列作ると、埋まらない列が並んだ表になります。
無料のテンプレートはどこで手に入りますか?
Notionのコンテンツカレンダー テンプレートやSmartsheetの無料コンテンツ カレンダー テンプレートが配布されています。ただし配布テンプレートは列名が英語だったり自社に無いチャネルが入っていたりするため、そのまま使えることはまれです。既存テンプレートの列構成が合わない場合は、この記事の列設計をGoogleスプレッドシートに写し、「コピーを作成」で複製する方法も選べます。
コンテンツカレンダーで手作業を減らすにはどこから着手しますか?
承認待ちの検知からです。投稿の自動送信ではありません。条件付き書式で期限超過を色分けし、Apps Scriptの時間主導トリガーで1日1回Slackへまとめて通知すれば、担当者を探して声をかける作業が消えます。無料アカウントのトリガー合計実行時間は1日90分ですが、同じユーザーの他のトリガーも使用します。1回6分の実行上限と、アカウント全体の使用量を確認してください。
承認フローをカレンダーに組み込むと公開が遅くなりませんか?
公開の遅れを防ぐには、承認依頼の見落としに加え、承認者の不在、確認項目の不明確さ、差し戻しの多さも点検します。ステータス列と承認期限列で期限超過を検知し、承認依頼日と承認完了日も記録すると、承認にかかった日数を計算できます。数字が見えると、承認者を増やすのか期限を延ばすのかという判断ができます。承認そのものを外すより、待ち時間を測るほうが先です。
複数チャネルのキャンペーンを1枚のカレンダーで調整できますか?
キャンペーン名の列をmasterシートのプルダウンで固定していれば可能です。チャネルごとに行を分けたまま、キャンペーン名でフィルタすれば、同一施策の展開順が1画面に並びます。逆にキャンペーン名を自由入力にすると表記ゆれでフィルタが効かず、チャネル間の調整だけ別の表を作るはめになります。