プラグイン(Jetpack等)を使っても予約投稿時にTwitterに投稿されない等の問題が出たため自作しました。
デモ
手順
1. Twitter APIの使用準備
Twitter APIを使うため下記URLにアクセスしてアプリケーションを作成してください。
https://apps.twitter.com
アプリケーションの作成方法は下記記事を参照。
Twitter REST APIの使い方|SYNCER
作成後、consumer_key、consumer_secret、access_token、access_token_secretの4つをどこかに保存しておいてください。あとで使います。
2. ライブラリの導入
下記URLからライブラリをダウンロード。
https://github.com/abraham/twitteroauth
フォルダ名をtwitteroauth-masterからtwitteroauthにリネームしてテーマファイル内にぶち込んでください。
3. コード
下記コードをfunctions.phpにコピペしてお使いください。
やっていることはsave_postでTwitterに投稿する内容と投稿するかしないかのデータをwp_postmetaに保存しています。
そしてtransition_post_statusでTwitterへ投稿するファイル「post-twitter.php」を実行しています。
post-twitter.phpではsave_postで保存した内容を元にTwitterに投稿しています。
全てsave_postに書いても良いと思ったのですが、save_postだと予約投稿時に$_POSTデータ(post_idなど)が受け取れなかったので分けました。
// ここではTwitterの投稿だけを行う
add_action('transition_post_status', 'post_twitter', 10, 3);
function post_twitter($new_status, $old_status, $post) {
if ($new_status == 'publish') {
// コマンドでTwitterに投稿するファイルを実行(引数にpost_idを渡している)
$command = "/usr/bin/php ".__DIR__."/post-twitter.php $post->ID > /dev/null &";
exec($command);
}
}
// 管理画面が開いたときに実行
add_action('admin_menu', 'add_post_twitter_fields');
// カスタムフィールドを投稿画面に追加
function add_post_twitter_fields() {
// フィールドを追加
add_meta_box('post_twitter', 'Twitter', 'post_twitter_field', 'post', 'side', 'high');
}
// 投稿画面に表示するフォームのHTMLソース
function post_twitter_field() {
global $post;
$twitter_body = get_post_meta($post->ID, 'twitter_body', true);
$checked = get_post_meta($post->ID, 'whether_to_post', true);
if ($checked == 'checked') {
$checked = 'checked="'.$checked.'""';
}
echo '<div style="margin-bottom:5px;"><label><input type="checkbox" name="whether_to_post" id="whether_to_post" value="checked" '.$checked.'>Twitterに投稿する</label></div>';
echo '<textarea name="twitter_body" id="twitter_body" cols="50" rows="5" style="width: 100%;" readonly>'.$twitter_body.'</textarea>';
echo <<< EOF
<script>
(function($) {
// ロード時にチェックが入っていれば編集可に、入っていなかったら可に。
if($("#whether_to_post").prop('checked')) {
$("#twitter_body").prop('readonly', false);
$('#twitter_body').css({'background-color':'','color':'', 'pointer-events':''});
} else {
$("#twitter_body").prop('readonly', true);
$('#twitter_body').css({'background-color':'#fff','color':'#ccc', 'pointer-events':'none'});
}
// タイトルを自動入力(フォーカスが外れた時に反映)
$('#title').change(function() {
if ($('#twitter_body').val() == '') {
var title = $('input[name="post_title"]').val();
$('#twitter_body').val(title + "\\n");
}
});
// チェックを入れると編集可能に、外すと不可に。
$('input[name="whether_to_post"]').change(function() {
if($("#whether_to_post").prop('checked')) {
$("#twitter_body").prop('readonly', false);
$('#twitter_body').css({'background-color':'','color':'', 'pointer-events':''});
} else {
$("#twitter_body").prop('readonly', true);
$('#twitter_body').css({'background-color':'#fff','color':'#ccc', 'pointer-events':'none'});
}
});
})(jQuery);
</script>
EOF;
}
// 下書き・公開・更新ボタンが押されたときに実行される(ゴミ箱に移動したときも呼ばれるかも?)
add_action('save_post', 'save_post_twitter', 10, 3);
// 設定したカスタムフィールドの値をDBに書き込むコード
function save_post_twitter($post_id, $post) {
if (isset($_POST['whether_to_post']) || isset($_POST['twitter_body'])) {
$post_type = $post->post_type;
if ($post_type == 'post') {
$whether_to_post = $_POST['whether_to_post'] == '' ? '': $_POST['whether_to_post'];
update_post_meta($post_id, 'whether_to_post', $whether_to_post);
$twitter_body = $_POST['twitter_body'] == '' ? '': $_POST['twitter_body'];
update_post_meta($post_id, 'twitter_body', $twitter_body);
}
}
}
Twitterに投稿するファイル。
post-twitter.phpをテーマディレクトリに作成し、
下記コードをコピペしてください。(必要箇所は適宜変更)
require __DIR__. '/../../../wp-load.php';
require_once __DIR__."/twitteroauth/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
class Twitter {
private static $consumer_key = "hogehoge";
private static $consumer_secret = "hogehoge";
private static $access_token = "hogehoge";
private static $access_token_secret = "hogehoge";
public function post($post) {
// Twitterへ投稿
$connection = new TwitterOAuth(self::$consumer_key, self::$consumer_secret, self::$access_token, self::$access_token_secret);
$result = $connection->post("statuses/update", ["status" => $post]);
if ($connection->getLastHttpCode() == 200) {
echo "succes";
return;
} else {
// 投稿に失敗したらエラー内容をメールで送る
mb_language("Japanese");
mb_internal_encoding("UTF-8");
$to = 'to@example.com';
$subject = 'Twitter Debug';
$message = "Twitterへの投稿に失敗しました。\n$post\n\nエラーコード:".$result->errors[0]->code."\nエラーメッセージ:".$result->errors[0]->message;
$headers = 'From: from@example.com' . "\r\n";
mb_send_mail($to, $subject, $message, $headers);
}
}
}
// functions.phpに書いたtransition_post_statusは、
// save_postより先に実行されるので、念のためここで2秒遅らせてる。
sleep(2);
// post_id取得
$post_id = isset($argv[1]) ? $argv[1] : null;
$whether_to_post = get_post_meta($post_id, 'whether_to_post', true);
// checkedじゃなかったら処理中断
if ($whether_to_post != 'checked') return;
$twitter = new Twitter();
// 投稿内容を取得
$post = get_post_meta($post_id, 'twitter_body', true);
// post_url取得
$post_url = get_permalink($post_id);
if(strpos($post_url,'http://') !== false){
$post_url = str_replace('http://', 'https://', $post_url);
}
// 投稿内容とpost_urlを結合
$post .= "\n".$post_url;
$twitter->post($post);