1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Buffer GraphQL APIで複数SNSに自動投稿するシステムの実装

1
Posted at

はじめに

Futuristic Imagination LLC 代表の佐藤です。

弊社では現在、AIオウンドメディア18サイトを一人で運用しており、9言語展開で年間6,570記事を自動生成しています。この膨大な量のコンテンツをいかに効率的に多くの人々に届けるか、常に頭を悩ませていました。

手動でのSNS投稿は、記事数が増えれば増えるほど非現実的な作業量になります。そこで目をつけたのが、BufferのGraphQL APIを使ったSNS自動投稿システムでした。

「どうにかしてSNS運用も自動化できないか?」

そう思って作り上げたのが、今回のシステムです。結果的に、月間100時間以上かけていたSNS運用業務をほぼ完全に自動化することに成功しました。この記事では、その具体的な実装方法と、実際に使ってみて得られた知見を余すところなくお伝えします。

この記事でわかること

  • Buffer GraphQL APIを使った複数SNSへの自動投稿の仕組み
  • TypeScriptとNext.jsでBuffer APIを扱う具体的な実装例
  • コンテンツ生成からSNS投稿までの一連の自動化パイプライン構築のヒント
  • 月100時間分のSNS運用工数を削減した私の実践的なノウハウ

なぜBufferなのか?

SNS自動投稿ツールは世の中にたくさん存在します。その中でなぜ私がBufferを選んだのか、その理由を最初に説明しておきましょう。

  1. GraphQL APIの提供: REST APIと比較して、必要なデータだけを効率的に取得・送信できるGraphQLは、特に複雑な連携や大量のデータ処理を行うシステムにおいて非常に強力です。BufferがGraphQL APIを提供している点は、開発者にとって大きな魅力でした。
  2. 多様なSNS連携: X (旧Twitter)、Facebook、LinkedIn、Instagramなど、主要なSNSに対応しているため、一つのシステムで複数のプラットフォームへの投稿を一元管理できます。
  3. 投稿予約・スケジュール管理機能: API経由で投稿を予約できるため、最適な時間にコンテンツを配信することが可能です。これは、メディア運用において非常に重要な要素です。
  4. 信頼性と実績: 長年の運用実績があり、多くの企業や個人に利用されている信頼性の高いサービスである点も、選定の決め手となりました。

システム構成の概要

私が構築したSNS自動投稿システムの全体像は以下の通りです。

  1. 記事自動生成: Next.js + Gemini API + Vercel Cron を利用し、毎日新たな記事を自動生成。
  2. 記事保存: GitHubリポジトリにMarkdown形式で保存。
  3. SNS投稿トリガー: Vercel CronまたはGitHub Actionsを利用して、一定間隔で投稿キューをチェック。
  4. 投稿内容生成: 生成された記事のタイトル、URL、ハッシュタグなどを基にSNS投稿用のテキストを自動生成。
  5. Buffer API連携: 生成された投稿内容をBuffer GraphQL API経由で送信し、各SNSに投稿。
  6. 投稿履歴管理: 投稿済みの記事を管理し、重複投稿を防止。

この中でも特に核となるのが、Buffer GraphQL APIを使った部分です。

Buffer GraphQL APIのセットアップ

1. Bufferアカウントとアクセスキーの取得

BufferのDeveloperページでアプリケーションを登録し、client_idclient_secret を取得します。
次に、OAuth2フローを通じて、ユーザーの access_token を取得します。これは一度取得すれば、リフレッシュトークンを使って永続的に利用できます。

具体的な取得方法はBufferのドキュメントを参照してください。

2. 環境変数の設定

取得したキーは安全に管理するため、Next.jsの環境変数として設定します。

# .env.local
BUFFER_ACCESS_TOKEN="your_buffer_access_token_here"

Buffer GraphQL APIをTypeScriptで扱う

Next.jsプロジェクトでTypeScriptを使ってAPIを叩く際の実装例を見ていきましょう。
今回は graphql-request ライブラリを使用します。

1. 必要なライブラリのインストール

npm install graphql-request graphql
npm install -D @types/graphql

2. GraphQLクライアントの初期化

lib/bufferGraphqlClient.ts

import { GraphQLClient } from 'graphql-request';

const endpoint = 'https://api.bufferapp.com/graphql';

export const bufferGraphqlClient = new GraphQLClient(endpoint, {
  headers: {
    Authorization: `Bearer ${process.env.BUFFER_ACCESS_TOKEN}`,
    'Content-Type': 'application/json',
  },
});

これで、Buffer GraphQL APIを叩く準備ができました。

3. 投稿するSNSプロフィールの取得

Bufferでは、連携したSNSアカウントを「プロフィール」として管理します。投稿先のプロフィールIDを取得する必要があります。

queries/getProfiles.ts

import { gql } from 'graphql-request';

export const GET_PROFILES = gql`
  query GetProfiles {
    viewer {
      profiles {
        id
        service
        serviceUsername
      }
    }
  }
`;

serviceserviceUsername を見て、どのSNSアカウントに投稿するかを判別できます。

import { bufferGraphqlClient } from '../lib/bufferGraphqlClient';
import { GET_PROFILES } from '../queries/getProfiles';

interface BufferProfile {
  id: string;
  service: string;
  serviceUsername: string;
}

interface GetProfilesResponse {
  viewer: {
    profiles: BufferProfile[];
  };
}

const getBufferProfiles = async (): Promise<BufferProfile[]> => {
  try {
    const data = await bufferGraphqlClient.request<GetProfilesResponse>(GET_PROFILES);
    return data.viewer.profiles;
  } catch (error) {
    console.error('Failed to fetch Buffer profiles:', error);
    throw error;
  }
};

// 使い方
(async () => {
  const profiles = await getBufferProfiles();
  console.log('Buffer Profiles:', profiles);
  // 例: X (旧Twitter) のプロフィールIDを取得
  const twitterProfile = profiles.find(p => p.service === 'twitter');
  if (twitterProfile) {
    console.log('Twitter Profile ID:', twitterProfile.id);
  }
})();

4. SNS投稿の作成 (Create Share Mutation)

いよいよ投稿部分です。Bufferでは sharesCreate ミューテーションを使って投稿を作成します。

mutations/createShare.ts

import { gql } from 'graphql-request';

export const CREATE_SHARE = gql`
  mutation CreateShare($input: SharesCreateInput!) {
    sharesCreate(input: $input) {
      share {
        id
        text
        status
        # その他の必要なフィールド
      }
      errors {
        message
        field
      }
    }
  }
`;

SharesCreateInput の型定義はBufferのドキュメントを参照しますが、主要なフィールドは以下の通りです。

  • profileIds: 投稿先のプロフィールIDの配列
  • text: 投稿本文
  • mediaAttachments: 画像や動画などの添付ファイル (オプション)
  • scheduledAt: 投稿予約日時 (オプション、指定しない場合はすぐに投稿)

services/bufferService.ts

import { bufferGraphqlClient } from '../lib/bufferGraphqlClient';
import { CREATE_SHARE } from '../mutations/createShare';

interface SharesCreateInput {
  profileIds: string[];
  text: string;
  mediaAttachments?: {
    photo?: {
      url: string;
    };
  }[];
  scheduledAt?: string; // ISO 8601 format
}

interface SharesCreateResponse {
  sharesCreate: {
    share?: {
      id: string;
      text: string;
      status: string;
    };
    errors?: {
      message: string;
      field?: string;
    }[];
  };
}

export const postToBuffer = async (input: SharesCreateInput): Promise<boolean> => {
  try {
    const data = await bufferGraphqlClient.request<SharesCreateResponse>(CREATE_SHARE, { input });

    if (data.sharesCreate.errors && data.sharesCreate.errors.length > 0) {
      console.error('Buffer API Errors:', data.sharesCreate.errors);
      return false;
    }
    if (data.sharesCreate.share) {
      console.log('Successfully posted to Buffer:', data.sharesCreate.share.id);
      return true;
    }
    return false;
  } catch (error) {
    console.error('Failed to post to Buffer:', error);
    throw error;
  }
};

// 使い方
(async () => {
  const profiles = await getBufferProfiles();
  const targetProfileIds = profiles.filter(p => ['twitter', 'linkedin'].includes(p.service)).map(p => p.id);

  if (targetProfileIds.length === 0) {
    console.error('No target SNS profiles found.');
    return;
  }

  const postText = `新着記事公開!「Buffer GraphQL APIで複数SNSに自動投稿!月100時間分のSNS運用を自動化して寝てみた話」\n\n最新のAIとWeb開発を駆使して、SNS運用を徹底的に自動化する方法を解説しました。これであなたも睡眠時間を確保できる! #BufferAPI #自動化 #SNS運用 #AI #Nextjs\n\n${'https://futuristicimagination.co.jp/blog/buffer-graphql-api-sns-automation'}`;

  const success = await postToBuffer({
    profileIds: targetProfileIds,
    text: postText,
    // mediaAttachments: [{ photo: { url: 'https://example.com/ogp.jpg' } }], // OGP画像などを添付する場合
    scheduledAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(), // 1時間後に予約投稿
  });

  if (success) {
    console.log('SNS投稿が正常にキューに追加されました。');
  } else {
    console.log('SNS投稿に失敗しました。');
  }
})();

これで、記事が公開された際に自動的にSNSに投稿される仕組みの核ができました。

コンテンツ生成からSNS投稿までの自動化パイプライン

私が実際に運用しているパイプラインは以下のようになっています。

  1. Vercel CronでNext.js API Routeをトリガー: 毎日指定時間に記事自動生成処理を開始。
  2. Gemini APIで記事コンテンツとSNS投稿文を生成:
    • 記事タイトル、本文、SEOメタ情報
    • SNS投稿用の短いテキスト(X用、LinkedIn用など、プラットフォームごとに調整)
    • 関連ハッシュタグ
  3. 生成されたコンテンツをGitHubに保存: 記事はMarkdownファイルとしてGitHubリポジトリにコミットされます。これにより、バージョン管理と記事の永続化を実現。
  4. 記事URLの取得とSNS投稿処理の実行:
    • 記事の公開URLを確定。
    • 前述の postToBuffer 関数を呼び出し、生成されたSNS投稿文と記事URLをBufferに送信。
    • 複数のSNSに同時に、あるいは時間差で投稿するよう設定。
  5. Discord通知: 投稿が成功したか失敗したかをDiscordに通知し、常にシステムの状態を把握できるようにしています。

この一連の流れを完全に自動化することで、私が手動で関与する部分はほとんどありません。

投稿文生成のコツ

Generative AIを使ってSNS投稿文を生成する際は、以下の点を意識しています。

  • 文字数制限: 各SNSの文字数制限を考慮し、短く要点をまとめる。
  • ハッシュタグ: 関連性の高いハッシュタグを適切に付与し、視認性と検索性を高める。
  • CTA (Call To Action): 「詳細はこちら」「続きはブログで」など、記事への誘導を促す文言を入れる。
  • 絵文字: 適度に絵文字を使うことで、投稿に親しみやすさを持たせる。
  • プラットフォーム特性: LinkedInではビジネス寄りの真面目なトーン、Xではカジュアルなトーンなど、プラットフォームに合わせて調整。

例:

const generateSocialPostText = (articleTitle: string, articleUrl: string): { twitter: string, linkedin: string } => {
  const baseText = `新着記事: ${articleTitle}\n\nAIと自動化で、あなたのビジネスを次のステージへ🚀✨ #自動化 #AI #Web開発`;
  
  const twitterText = `${baseText}\n詳細はこちら: ${articleUrl}`;
  
  const linkedinText = `【${articleTitle}】公開しました!\n\nGenerative AIとWeb開発を駆使したビジネス自動化の最前線について解説しています。業務効率化にご興味のある方はぜひご一読ください。\n\n記事はこちら: ${articleUrl}\n\n#AI活用 #ビジネス自動化 #Nextjs開発`;

  return { twitter: twitterText, linkedin: linkedinText };
};

このように、記事の内容から自動的に生成し、各SNSへ適切な形で投稿するようにしています。

実際に動かしてみて

このシステムを導入してから、メディア運営が劇的に変わりました。

  • 月100時間以上の工数削減: これまで手動で各SNSに投稿していた作業がゼロになり、他の戦略的業務に時間を割けるようになりました。
  • SNSからの流入増加: 安定的に投稿されることで、フォロワーのエンゲージメントが向上し、結果としてサイトへの流入が増加しました。
  • 一貫したブランドイメージ: 投稿のフォーマットやトーンが自動で統一されるため、ブランドイメージの一貫性を保ちやすくなりました。
  • 「寝ている間に仕事が進む」感覚: 文字通り、私が寝ている間に記事が生成され、SNSに投稿され、集客活動が行われているというのは、エンジニアとして最高の体験です。

もちろん、AIが生成したコンテンツの最終チェックや、トレンドに応じたハッシュタグの調整など、人間が介入すべきポイントは残ります。しかし、その作業量は圧倒的に削減され、より本質的な価値創造に集中できるようになりました。

「一人で大きな価値を生み出す完全自動化」という弊社のビジョンは、着実に現実のものとなっています。

まとめ

本記事では、Buffer GraphQL APIをNext.jsとTypeScriptで活用し、複数SNSへの投稿を自動化するシステムの実装方法を解説しました。コンテンツ自動生成からSNS投稿までの一連のパイプラインを構築することで、月間100時間以上ものSNS運用工数を削減し、効率的なメディア運用を実現できることを示しました。

Generative AIとWeb開発技術を組み合わせることで、これまで人間が行っていた定型業務の多くは自動化可能です。この自動化は、単なる効率化に留まらず、私たちのビジネスの可能性を大きく広げるものだと確信しています。

今回紹介したようなシステムの構築代行も行っていますので、ご興味があればぜひお問い合わせください。

また、転職・副業・キャリアに関するShorts動画を毎日配信中ですので、こちらもぜひご覧ください。

最後までお読みいただきありがとうございました。この記事があなたの開発の一助となれば幸いです。LGTMいただけると大変励みになります!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?