Medium

ソーシャルライティングプラットフォーム。執筆に集中できるミニマルなインターフェースと読者コミュニティ。

CMSブログソーシャルライティングパブリッシング収益化
ライセンス
Commercial
言語
Web Platform
料金
基本機能無料

CMS

Medium

概要

Mediumは、執筆に集中できるミニマルなインターフェースと読者コミュニティを特徴とするソーシャルライティングプラットフォームです。

詳細

Medium(ミディアム)は、Twitter共同創業者のEvan Williamsが2012年に立ち上げたオンラインパブリッシングプラットフォームです。「Quality over clicks(クリック数より質)」を理念とし、執筆者と読者をつなぐソーシャルプラットフォームとして発展してきました。

Mediumの最大の特徴は、執筆体験のシンプルさです。複雑な設定やカスタマイズを排除し、純粋に「書くこと」に集中できる環境を提供します。エディタは直感的で、テキストを選択するだけで書式設定が可能。画像、埋め込み、コードブロックなども簡単に挿入できます。

コミュニティ機能も充実しており、1億人以上の月間読者と400万人以上のライターが参加しています。「クラップ」(拍手)機能、ハイライト、レスポンス(返信記事)など、読者とライターの交流を促進する機能が豊富です。2023年8月にリニューアルされたPartner Programでは、オリジナリティと読者エンゲージメントを重視した収益化モデルを採用しています。

メリット・デメリット

メリット

  • 執筆に集中: 設定不要のシンプルなインターフェース
  • 既存の読者層: 1億人以上の月間アクティブ読者
  • 高いSEO効果: Mediumの高いドメイン権威性
  • 収益化可能: Partner Programによる記事の収益化
  • ソーシャル機能: クラップ、ハイライト、レスポンス機能
  • 無料で開始: 基本機能は完全無料で利用可能
  • モバイル対応: 優れたモバイルアプリとレスポンシブデザイン

デメリット

  • プラットフォーム依存: コンテンツの完全な所有権なし
  • カスタマイズ不可: デザインやレイアウトの変更不可
  • 独自ドメイン不可: Medium.comのサブドメインのみ
  • API制限: 公式APIは非推奨、更新機能なし
  • 収益の不安定性: アルゴリズム変更で収益が大きく変動
  • コンテンツ移行困難: 他プラットフォームへの移行が複雑

主要リンク

使い方の例

アカウント作成と基本設定

// Medium APIを使った基本的な認証(非推奨API)
// 注意:公式APIは新規統合には推奨されません

// Integration Tokenの取得方法:
// 1. Medium.comにログイン
// 2. Settings → Integration tokens
// 3. トークン名を入力して「Get token」をクリック

const MEDIUM_API_TOKEN = 'your-integration-token';
const API_BASE_URL = 'https://api.medium.com/v1';

// 認証ヘッダーの設定
const headers = {
  'Authorization': `Bearer ${MEDIUM_API_TOKEN}`,
  'Content-Type': 'application/json',
  'Accept': 'application/json'
};

記事の投稿(API使用)

// ユーザー情報の取得
async function getCurrentUser() {
  const response = await fetch(`${API_BASE_URL}/me`, {
    method: 'GET',
    headers: headers
  });
  
  const data = await response.json();
  return data.data;
}

// 記事の投稿
async function publishPost(userId, postData) {
  const post = {
    title: "Mediumで技術記事を書く方法",
    contentFormat: "html",
    content: `
      <h1>Mediumで技術記事を書く方法</h1>
      <p>Mediumは技術者にとって素晴らしいプラットフォームです。</p>
      <h2>なぜMediumか?</h2>
      <ul>
        <li>既存の読者層へのリーチ</li>
        <li>シンプルな執筆体験</li>
        <li>収益化の可能性</li>
      </ul>
      <pre><code class="language-javascript">
      console.log('Hello, Medium!');
      </code></pre>
    `,
    tags: ["プログラミング", "技術記事", "Medium"],
    publishStatus: "public", // "draft", "public", "unlisted"
    canonicalUrl: "https://your-blog.com/original-post"
  };

  const response = await fetch(
    `${API_BASE_URL}/users/${userId}/posts`,
    {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(post)
    }
  );

  return await response.json();
}

Publication(出版物)への投稿

// ユーザーのPublication一覧を取得
async function getUserPublications(userId) {
  const response = await fetch(
    `${API_BASE_URL}/users/${userId}/publications`,
    {
      method: 'GET',
      headers: headers
    }
  );
  
  const data = await response.json();
  return data.data;
}

// Publicationに記事を投稿
async function publishToPublication(publicationId, postData) {
  const post = {
    title: "チーム開発のベストプラクティス",
    contentFormat: "markdown",
    content: `
# チーム開発のベストプラクティス

## コードレビューの重要性

効果的なコードレビューは、チームの成長に不可欠です。

### レビューのポイント
1. コードの可読性
2. パフォーマンス
3. セキュリティ
4. テストカバレッジ

\`\`\`javascript
// Good practice
function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.price, 0);
}
\`\`\`
    `,
    tags: ["開発", "チーム", "ベストプラクティス"],
    publishStatus: "draft"
  };

  const response = await fetch(
    `${API_BASE_URL}/publications/${publicationId}/posts`,
    {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(post)
    }
  );

  return await response.json();
}

画像のアップロード

// 画像をMediumにアップロード
async function uploadImage(imageFile) {
  const formData = new FormData();
  formData.append('image', imageFile);

  const response = await fetch(`${API_BASE_URL}/images`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${MEDIUM_API_TOKEN}`
    },
    body: formData
  });

  const data = await response.json();
  return data.data.url; // アップロードされた画像のURL
}

// 記事内で画像を使用
const imageUrl = await uploadImage(imageFile);
const postContent = `
  <h1>画像付き記事</h1>
  <img src="${imageUrl}" alt="説明文" />
  <p>画像の説明テキスト</p>
`;

RSS/XMLフィードの活用

// MediumのRSSフィードを取得してブログに埋め込み
async function fetchMediumFeed(username) {
  const FEED_URL = `https://medium.com/feed/@${username}`;
  
  // RSSパーサーライブラリを使用(例:rss-parser)
  const Parser = require('rss-parser');
  const parser = new Parser();
  
  try {
    const feed = await parser.parseURL(FEED_URL);
    
    // 最新5記事を取得
    const latestPosts = feed.items.slice(0, 5).map(item => ({
      title: item.title,
      link: item.link,
      pubDate: item.pubDate,
      creator: item.creator,
      content: item['content:encoded'],
      categories: item.categories
    }));
    
    return latestPosts;
  } catch (error) {
    console.error('RSS取得エラー:', error);
  }
}

// 自分のウェブサイトに記事一覧を表示
function displayMediumPosts(posts) {
  const container = document.getElementById('medium-posts');
  
  posts.forEach(post => {
    const article = document.createElement('article');
    article.innerHTML = `
      <h3><a href="${post.link}" target="_blank">${post.title}</a></h3>
      <time>${new Date(post.pubDate).toLocaleDateString('ja-JP')}</time>
      <div>${post.content.substring(0, 200)}...</div>
      <a href="${post.link}" target="_blank">続きを読む</a>
    `;
    container.appendChild(article);
  });
}

非公式APIの活用例

// 非公式Medium APIを使った高度な機能
// (注意:サードパーティサービスの利用は自己責任で)

const UNOFFICIAL_API_KEY = 'your-api-key';
const UNOFFICIAL_API_URL = 'https://api.mediumapi.com/v1';

// ユーザーの詳細情報を取得
async function getUserDetails(username) {
  const response = await fetch(
    `${UNOFFICIAL_API_URL}/user/${username}`,
    {
      headers: {
        'x-api-key': UNOFFICIAL_API_KEY
      }
    }
  );
  
  return await response.json();
}

// 記事の統計情報を取得
async function getArticleStats(articleId) {
  const response = await fetch(
    `${UNOFFICIAL_API_URL}/article/${articleId}/stats`,
    {
      headers: {
        'x-api-key': UNOFFICIAL_API_KEY
      }
    }
  );
  
  const stats = await response.json();
  return {
    views: stats.views,
    reads: stats.reads,
    claps: stats.claps,
    responses: stats.responses_count
  };
}

// トップライターを検索
async function searchTopWriters(topic) {
  const response = await fetch(
    `${UNOFFICIAL_API_URL}/topwriters/${topic}`,
    {
      headers: {
        'x-api-key': UNOFFICIAL_API_KEY
      }
    }
  );
  
  return await response.json();
}