見出し画像

カンバセーショナルカード(会話型カード)をTwitter APIとGASで作ってツイートする

※ 2023年9月追記 ※
TwitterのAPI仕様変更が度々あるので、現時点で使えるかどうか未検証です。

背景

Twitterのカンバセーショナルカードが2022年4月に廃止され、管理画面から作成することができなくなりました。
カンバセーショナルカードとはこういうのです。

https://blog.twitter.com/ja_jp/a/ja/2016/cac より

企業のキャンペーン広告などで見たことがある方も多いと思いますが、「#●● でツイート」みたいなボタンがついていて、押すだけで手軽にキャンペーン参加のツイートができるやつです。

以前は広告の管理画面から作成すれば広告でもオーガニックでも利用することができたのですが、現在は広告利用も含め管理画面からの作成ができなくなり、API経由でのみ作成できるようになっています。

そこで、今回はTwitter API、Twitter Ads API、GAS(Google App Script)を利用して、カンバセーショナルカードの作成と、そのカードを使ってツイートを投稿する方法をご紹介していきます。

書いている人

株式会社マインディア というスタートアップでBtoC・BtoB両方のマーケティングをしています。
非エンジニアなので用語の説明やクエリの書き方など雑なところがあると思いますが、何か気になるところがあったら優しくご指摘ください、、、!

twitterアカウント @takahirostone
ぜひフォローしてくださいー!

手順

1. Twitterアカウントと広告アカウントを用意する

既に持っていればもちろんそれで問題ありません。Twitterアカウントは作ってからしばらく(2週間くらい?)経たないと広告アカウントの利用ができないので、まだ持っていない場合は早めに作りましょう。

広告アカウントはクレジットカードの登録まで済ませておく必要があります。 ※ お金をかけて広告配信をする必要はありませんが、クレカが登録されていないとカンバセーショナルカードの作成か広告用ツイートの作成のどちらかのステップでエラーになるはずです。

逆に言うと、クレカの登録さえ済ませれば個人のアカウントでも使えるようになります。

2. Twitterの開発者アカウントを作成する

こちら からTwitter開発者アカウントの登録をしましょう。そうするとAPIが利用できるようになります。英語でいろいろ書くところがあって面倒ですが、例文を公開してくれている記事もたくさんあるのでコピペでも問題ないと思います。

3. アプリを作成する

そのまま流れでアプリを作成しましょう。アプリの名前は好きなもので大丈夫ですが、最終的にツイートしたときのソースとして表示されます。あまり変な名前にしないように気をつけましょう。

矢印のところがアプリ名です。「Hootsuite」とか「TweetDeck」とかよく使われてますね。

※2023年2月10日現在、アプリ名は表示されなくなっています。が、いつ復活するか分からないので変な名前は使わない方が無難ですね。

3. 「API Key」「API Secret Key」「Access Token」「Access Token Secret」の4つを発行して、メモする

このあたりもいろいろ記事があるので、分からないものがあればググれば大丈夫です。なくすと後からは再確認できませんので、なくさないように気をつけてください(再発行はできる)。

4. Twitter Ads APIの利用申請をする

Twitterでは、通常のツイートやアカウントを管理するAPIと広告を管理するAds APIが別で用意されています。カードの作成はAds API側の機能なので、Ads APIの利用申請が必要です。申請は こちら から出せます。これも書くところが多くて面倒ですが、なんとか頑張りましょう。
例えば「Ads APIを使って作ろうとしているあなたのサービスは、他のサービスと比べてどんなところがユニークなのか」という質問がありました。多分、ビジネスとして広告運用ツールを作りクライアントに提供する場合などを想定した質問だと思います。私は「インハウスで広告運用をするために使います。」とか適当に書いたのをDeepLで翻訳しただけですが、それでも通りました。

私の場合は申請から利用できるようになるまで1週間〜10日くらいかかりました。

5. カンバセーショナルカード機能の利用申請をする

初期設定では、セルフサービス広告主様はカンバセーションボタンをご利用できない仕様になっています。利用を希望される場合は、サポートチケットを申請してください。

https://business.twitter.com/ja/help/campaign-setup/conversation-buttons.html

となっていますので、サポートに連絡して機能を有効化してもらいましょう。
その際、単に「カンバセーションボタンを使いたい」とだけ書くと「既に廃止されました」的な返信が返ってきてしまいます。なので、

  • すでにAds APIが利用できる状態であること

  • APIを使ってカンバセーショナルカードを作りたいこと

を記載しましょう。私の場合は1営業日もかからずに有効化してもらえました。

6. GASを書いてカードとツイートを作成する

あとはGASを書くだけです。カードを使ったツイート方法は「カードを作る」→「そのカードを紐付けたツイートを作成する」という形式なので、それぞれ書いていきます。

APIの認証

まずは、APIがちゃんと利用できるか確かめるために、認証が通るかを確認してみましょう。
以下のスクリプトでは、自分が保有する広告アカウントの一覧が取得できます。

function getAccount() {

  // リクエスト先のURL
  const url = "https://ads-api.twitter.com/11/accounts/"; // 「11」はAPIバージョンです。多分11が最新です。10とかでも動きます。

  // リクエストのメソッド
  const method = "GET";

  // oauthに必要な情報
  const consumerKey = "*************";  // API Keyを入れる
  const signatureMethod = "HMAC-SHA1";
  const now = new Date();
  const timestamp = Date.parse(now)/1000;
  const nonce = timestamp;  // リクエストごとにユニークであれば何でもOKなのでタイムスタンプを流用。もし秒間2回以上リクエストを投げる場合はユニークになるように変更
  const token = "*************";  // Access Tokenを入れる
  const version = "1.0";

  // oauth用のパラメータ
  const params = [
    "oauth_consumer_key=" + consumerKey,
    "oauth_nonce=" + nonce,
    "oauth_signature_method=" + signatureMethod,
    "oauth_timestamp=" + timestamp,
    "oauth_token=" + token,
    "oauth_version=" + version
  ];
  params.sort();

  // signature用のベーステキスト
  const parameter = params.join('&');
  const signatureBase = method + "&" + encodeURIComponent(url) + "&" + encodeURIComponent(parameter);

  // signature用の署名キー
  const consumerSecret = "*************"; // API Secret Keyを入れる
  const tokenSecret = "*************"; // Access Token Secretを入れる
  const signingKey = consumerSecret + "&" + tokenSecret;

  // ベーステキストと署名キーからsignatureを生成
  const signatureSha1 = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_1, signatureBase, signingKey);
  const signatureBase64 = Utilities.base64Encode(signatureSha1);
  const signature = encodeURIComponent(signatureBase64);

  // リクエストヘッダに入れるoauth情報
  params.push("oauth_signature=" + signature);
  const oauthParams = params.join(',');

  // リクエストのオプション
  const options = {
    "method": method,
    "headers": {
      "authorization": "OAuth " + oauthParams,
    },
    "muteHttpExceptions": true
  };

  // リクエストを送ってレスポンスを取得
  const response = JSON.parse(UrlFetchApp.fetch(url + "?" + parameter, options));
  console.log(response);

}

ざっと解説をすると、

  1. 必要なパラメータを集める

  2. リクエストメソッド・URL・パラメータを「&」で繋いでベーステキストを作る ※パラメータはkeyのアルファベット昇順にし、URLエンコードされていない値があればエンコードする

  3. API Secret KeyとAccess Token Secretで署名キーを作る

  4. ベーステキストと署名キーをHMAC_SHA1でハッシュ化 → base64エンコード → URLエンコード したものをsignatureにしてパラメータに追加する

  5. URLにパラメータをつけたものをエンドポイントとしてリクエストを投げる

です。
実行して、レスポンスとして広告アカウントの一覧が返ってくれば成功です。

細かく知りたい方はこのあたりの公式ドキュメントが参考になります。

また、コードをgit管理するなど複数人が触る場合はトークンやシークレットがコードに直接書いてあるのはあまり良くないケースもあるので、GASのProperties Serviceを使ってプロパティにトークン等を書き込むか、自分しか閲覧できないスプレッドシートに記載 → 毎回そこから読み込む方が良いかもしれません。

カンバセーショナルカードの作成

無事に認証が通ることを確認できたらカンバセーショナルカードを作ってみます。

function createCard() {

  // リクエスト先のURL
  const baseUrl = "https://ads-api.twitter.com/11/accounts/";
  const accountId = "*************"; // 広告アカウントのID
  const sufUrl = "/cards/image_conversation";
  const url = baseUrl + accountId + sufUrl;

  // リクエストのメソッド
  const method = "POST";

  // oauthに必要な情報
  const consumerKey = "*************";    
  const signatureMethod = "HMAC-SHA1";
  const now = new Date();
  const timestamp = Date.parse(now)/1000;
  const nonce = timestamp;
  const token = "*************";
  const version = "1.0";

  // カード生成に必要な情報
  const firstCta = encodeURIComponent("#" + "ハッシュタグ");
  const firstCtaTweet = encodeURIComponent("ツイートのテスト");
  const mediaKey = "*************"; // 後ほど解説
  const name = encodeURIComponent("カード生成のテスト");
  const thankYouText = encodeURIComponent("サンキュー!");
  const title = encodeURIComponent("ツイートのタイトル");

  // oauth用のパラメータ
  const params  = [
    "oauth_consumer_key=" + consumerKey,
    "oauth_nonce=" + nonce,
    "oauth_signature_method=" + signatureMethod,
    "oauth_timestamp=" + timestamp,
    "oauth_token=" + token,
    "oauth_version=" + version,
    "first_cta=" + firstCta,
    "first_cta_tweet=" + firstCtaTweet,
    "media_key=" + mediaKey,
    "name=" + name,
    "thank_you_text=" + thankYouText,
    "title=" + title
  ];
  params.sort();

  // signature用のベーステキスト
  const parameter = params.join('&');
  const signatureBase = method + "&" + encodeURIComponent(url) + "&" + encodeURIComponent(parameter);

  // signature用の署名キー
  const consumerSecret = "*************";
  const tokenSecret = "*************";
  const signingKey = consumerSecret + "&" + tokenSecret;

  // ベーステキストと署名キーからsignatureを生成
  const signatureHmacSha1 = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_1, signatureBase, signingKey);
  const signatureBase64 = Utilities.base64Encode(signatureHmacSha1);
  const signature = encodeURIComponent(signatureBase64);

  // リクエストヘッダに入れるoauth情報
  params.push("oauth_signature=" + signature);
  const oauthParams = params.join(',');

  // リクエストのオプション
  const options = {
    "method": method,
    "headers": {
      "authorization": "OAuth " + oauthParams,
    },
    "muteHttpExceptions": true,
  };

  // リクエストを送ってレスポンスを取得
  const response = JSON.parse(UrlFetchApp.fetch(url + "?" + parameter, options));
  console.log(response);

}

先程のアカウント一覧を取得したコードとほとんど一緒ですね。違うのは

  • メソッドがPOSTになった

  • URLにアカウントIDやサフィックスがついた

  • カード作成に必要な情報がパラメータとして増えた

ぐらいです。

上記のサンプルは最低限のパラメータしか入れていないので、例えば2つ以上CTAをつけたい場合など、追加のパラメータが必要であればこちらを参考に追加してください。

パラメータの「media_key」は、事前にメディア(画像または動画)をアップロードして、IDを取得しておきます。
広告管理画面から「クリエイティブ」→「メディア」と進み、メディアをクリックするとURLにメディアのIDが入っています。

https://ads.twitter.com/accounts/{広告アカウントのID}/media/{メディアのID}/edit

こんな感じのURLになっているので、メディアのIDを取得して使います。なお、カンバセーショナルカードに使える画像はminimumサイズが横800 : 縦418で、1.91 : 1の比率を保ったものでないとエラーになります。
試してませんが800 : 418は厳密には1.91 : 1ではないので、それだとエラーになるかもしれません。今回は955 : 500で作成した画像を使いました。

なお、動画の場合は こちら で仕様を確認してください。

「first_cta」にはハッシュタグを入れる必要があるので、「#」がないとエラーになります。「#」とテキスト部分を分けてあるので、テキスト部分のみを変更しましょう。

上記スクリプトの例では「first_cta_tweet」にテキストしか入れていませんが、「first_cta」に入れたのと同じハッシュタグも入れた方が良いです。理由は最後に分かります。

このスクリプトを実行すると、以下のようなレスポンスが返ってきます。

{ data: 
   { name: 'カード生成のテスト',
     first_cta: '#ハッシュタグ',
     image_display_height: '500',
     media_url: 'https://pbs.twimg.com/media/*************.jpg',
     thank_you_text: 'サンキュー!',
     id: '*************',
     media_key: '*************',
     first_cta_tweet: 'ツイートのテスト',
     created_at: '2022-08-15T10:49:20Z',
     image_display_width: '955',
     card_uri: 'card://*************',
     title: 'ツイートのタイトル',
     updated_at: '2022-08-15T10:49:20Z',
     deleted: false,
     card_type: 'IMAGE_CONVERSATION' },
  request: 
   { params: 
      { name: 'カード生成のテスト',
        first_cta: '#ハッシュタグ',
        image_display_height: '500',
        media_url: 'https://pbs.twimg.com/media/*************.jpg',
        thank_you_text: 'サンキュー!',
        account_id: '*************',
        media_key: '*************',
        first_cta_tweet: 'ツイートのテスト',
        image_display_width: '955',
        title: 'ツイートのタイトル',
        card_type: 'IMAGE_CONVERSATION' } } }

この返ってきた情報の中で、「card_uri」をメモしておきます。

広告用ツイートの作成

カードが作成できたらあとはツイートを作成するだけです。いきなりツイートを作成してもいいのですが、できれば配信する前にプレビューしておきたいですよね。なので、まずはオーガニックのツイートではなく広告用ツイートを作成してみます。広告用ツイートは作成しただけでは公開されず、広告に利用しなければ基本的には見られません。 ※ 厳密に言うと、広告用ツイートも公開されたURLを持っているので、URL直打ちで当たれば見れます。ランダムでURL打って当たった場合とかは見れるので、見られる可能性は低いと思いますが、公開前のキャンペーン情報などは気をつけましょう。

function createAdTweet() {

  // リクエスト先のURL
  const baseUrl = "https://ads-api.twitter.com/11/accounts/";
  const accountId = "*************";
  const sufUrl = "/tweet";
  const url = baseUrl + accountId + sufUrl;

  // リクエストのメソッド
  const method = "POST";

  // oauthに必要な情報
  const consumerKey = "*************";    
  const signatureMethod = "HMAC-SHA1";
  const now = new Date();
  const timestamp = Date.parse(now)/1000;
  const nonce = timestamp;
  const token = "*************";
  const version = "1.0";

  const asUserId = "*************"; // 後で解説
  const cardUri = encodeURIComponent("card://*************"); // 先程取得したcard_uri
  const text = encodeURIComponent("カードのテストだよ");

  // oauth用のパラメータ
  const params = [
    "oauth_consumer_key=" + consumerKey,
    "oauth_nonce=" + nonce,
    "oauth_signature_method=" + signatureMethod,
    "oauth_timestamp=" + timestamp,
    "oauth_token=" + token,
    "oauth_version=" + version,
    "as_user_id=" + asUserId,
    "card_uri=" + cardUri,
    "text=" + text
  ];
  params.sort();

  // signature用のベーステキスト
  const parameter = params.join('&');
  const signatureBase = method + "&" + encodeURIComponent(url) + "&" + encodeURIComponent(parameter);

  // signature用の署名キー
  const consumerSecret = "*************";
  const tokenSecret = "*************";
  const signingKey = consumerSecret + "&" + tokenSecret;

  // ベーステキストと署名キーからsignatureを生成
  const signatureSha1 = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_1, signatureBase, signingKey);
  const signatureBase64 = Utilities.base64Encode(signatureSha1);
  const signature = encodeURIComponent(signatureBase64);

  // リクエストヘッダに入れるoauth情報
  params.push("oauth_signature=" + signature);
  const oauthParams = params.join(',');

  // リクエストのオプション
  const options = {
    "method": method,
    "headers": {
      "authorization": "OAuth " + oauthParams,
    },
    "muteHttpExceptions": true
  };

  // リクエストを送ってレスポンスを取得
  const response = JSON.parse(UrlFetchApp.fetch(url + "?" + parameter, options));
  console.log(response);

}

パラメータの「as_user_id」は、Twitterのアカウント(広告アカウントではなく普通のアカウント)のIDです。ユーザーネーム("@takahirostone" みたいなやつ)ではなくIDを入れる必要があります。

ユーザーIDが分からない場合はブラウザでTwitterを開き、ソースで「user_id」と検索して出てくる数字を探してください。

ユーザーIDの調べ方

これで広告用ツイートが作成できたので、広告管理画面で「クリエイティブ」→「ツイート」と進み、プレビューを確認してみてください。

広告用ツイートのプレビュー

オーガニックツイートの作成

最後に、オーガニックツイートの作成です。これを実行すると、実際にアカウントから投稿されますのでご注意ください。

function createTweet() {

  // リクエスト先のURL
  const url = "https://api.twitter.com/1.1/statuses/update.json";

  // リクエストのメソッド
  const method = "POST";

  // oauthに必要な情報
  const consumerKey = "*************";    
  const signatureMethod = "HMAC-SHA1";
  const now = new Date();
  const timestamp = Date.parse(now)/1000;
  const nonce = timestamp;
  const token = "*************";
  const version = "1.0";

  // ツイートに必要な情報
  const cardUri = encodeURIComponent("card://*************");
  const status = encodeURIComponent("テスト");

  // oauth用のパラメータ
  const params = [
    "oauth_consumer_key=" + consumerKey,
    "oauth_nonce=" + nonce,
    "oauth_signature_method=" + signatureMethod,
    "oauth_timestamp=" + timestamp,
    "oauth_token=" + token,
    "oauth_version=" + version,
    "card_uri=" + cardUri,
    "status=" + status
  ];
  params.sort();

  // signature用のベーステキスト
  const parameter = params.join('&');
  const signatureBase = method + "&" + encodeURIComponent(url) + "&" + encodeURIComponent(parameter);

  // signature用の署名キー
  const consumerSecret = "*************";
  const tokenSecret = "*************";
  const signingKey = consumerSecret + "&" + tokenSecret;

  // ベーステキストと署名キーからsignatureを生成
  const signatureSha1 = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_1, signatureBase, signingKey);
  const signatureBase64 = Utilities.base64Encode(signatureSha1);
  const signature = encodeURIComponent(signatureBase64);

  // リクエストヘッダに入れるoauth情報
  params.push("oauth_signature=" + signature);
  const oauthParams = params.join(',');

  // リクエストのオプション
  const options = {
    "method": method,
    "headers": {
      "authorization": "OAuth " + oauthParams,
    },
    "muteHttpExceptions": true
  };

  // リクエストを送ってレスポンスを取得
  const response = JSON.parse(UrlFetchApp.fetch(url + "?" + parameter, options));
  console.log(response);

}

いじるところはパラメータの「card_uri」と「status(ツイート本文)」ぐらいです。

ツイート用のAPIはv1.1とv2の2つあるのですが、v2の方ではcar_uriのパラメータが使えないっぽかったので、今回はv1.1を利用しています。 ※ 試してませんが、v2の方でも書いていないだけで使えるかもしれません。

v1.1の仕様 ↓

v2の仕様 ↓

実際の投稿はこんな感じです。

カンバセーショナルカードをオーガニックツイートした

ユーザーが「#●● でツイート」を押してツイートするとこんな感じになります。

ユーザーが「#●● でツイート」を押してツイートした

どうやら、ユーザーのツイートにハッシュタグを反映させるにはカード作成時のスクリプトで「first_cta_tweet」に設定したテキストにハッシュタグを入れておかないといけなかったようです。実施する際は忘れないようにしましょう。

GASでやる意味

正直、カンバセーショナルカードを作るだけならあまりGASで書く意味はないです。ただ、GASでAds APIの認証を通せるようにしておくと、広告用のツイートをスプレッドシートから大量に生成したり、キャンペーンのパフォーマンスをスプレッドシートで集計したりできるようになるので、他の用途で役立ちそうです。

最後に

気づいたらカンバセーショナルカードが廃止になっていて驚いたのですが、API経由で作れることが分かり一安心です。

今回の記事が参考になった方は、ぜひnoteのスキ、twitterのフォローをしていただけると嬉しいです!!カードのサンプルツイートも作成したので、ここでカンバセーションボタンを押してみてください笑。

Meetyも開けてますので、ご興味ある方いらっしゃればぜひお話しましょう!


この記事が参加している募集

よろしければサポートお願いします!そのうちオリジナルドメインにしたいなと思っているのでその資金にさせていただきます!