2017年11月19日更新

XML_RPC2を使ってWordpressに外部から投稿する方法

xml_rpcを使用して、ワードプレスの投稿画面外から投稿することが可能です。自動化には必須の方法ですが、xml_rpcこそあれ、xml_rpc2の情報はほとんどありません。xml_rpc2での外部投稿方法を紹介します。

  • 追加

Wordpressに外部から投稿する

外部から投稿する意味は、どんな部分にあるでしょうか。
家からでも投稿したい…というものではなく、
ほとんどの場合、決められたスケジュールに自動的に投稿をしたい、というニーズの為の外部投稿では無いかと思います。

さて、外部投稿自体は、xml_rpcと検索すると、すぐに出てきますが、xml_rpcがいつのまにかxml_rpc2に変更になりました。
Wordpressのスクレイピング自動投稿自体が、もう5年くらい前にピークだったので、
xml_rpc2にいざ書き換えようとしても、xml_rpcの情報は見つかってもxml_rpc2の情報がなかなかみつからずに困った覚えがあります。

今回、xml_rpc2で外部投稿をする方法を紹介します。
(ほとんどxml_rpcと変わりません。)

基本的には以下のように書き替えるだけです。
new XML_RPC_Value()

XML_RPC2_Value::createFromNative

$message = new XML_RPC_Message(
'wp.create',
array($blog_id, $username, $passwd, $file)
);

$prefix = 'wp.';
$options = array("prefix" => $prefix);
$c = XML_RPC2_client::create($this->to->url . $xmlrpc, $options);

(少々、XML_RPC時の物が見当たらなかったので似た部分を抜き出しているだけです。)

public function post($f) {

$host = parse_url($this->to->url, PHP_URL_HOST);
$path = rtrim(parse_url($this->to->url, PHP_URL_PATH), "/");
$xmlrpc = "/xmlrpc.php";

$D_USERNAME = $this->to->xpcid;
$D_PASSWORD = $this->to->xpcpass;

$username = XML_RPC2_Value::createFromNative($D_USERNAME, 'string');
$password = XML_RPC2_Value::createFromNative($D_PASSWORD, 'string');

$blogid = XML_RPC2_Value::createFromNative(0, 'string');
$encoding = "UTF-8";

$prefix = 'wp.';
$options = array("prefix" => $prefix);
$c = XML_RPC2_client::create($this->to->url . $xmlrpc, $options);
$w = $this->set_post($c, $username, $password, $f);

return $w;
}

出典:code

function set_post($c, $username, $password, $f) {
$D_BLOGTITLE = $this->history->title; //mb_convert_encoding($this->history->title,"UTF-8","auto");
$D_BODYTEXT = $f["desc"]; //mb_convert_encoding($f["desc"],"UTF-8","auto");
$D_BODYMORE = $f["more"]; //mb_convert_encoding($f["more"],"UTF-8","auto");
$blog_id = XML_RPC2_Value::createFromNative(0, "int");

if ($f["thumb"] != null) {
$thumb = $f["thumb"]->media_id;
} else {
$thumb = null;
}
if ($thumb == null and $this->to->thumb) {
$thumbs = collect(explode(",", $this->to->thumb));
if (count($thumbs)) {
$thumb = $thumbs->random();
if (!preg_match("/^[0-9]+$/", $thumb)) {
$imgfile = @file_get_contents($thumb);
$imagesize = @getimagesize($thumb);
if (isset($imagesize[2])) {
switch ($imagesize[2]) {
case IMAGETYPE_GIF:
$type = "image/gif";
break;
case IMAGETYPE_JPEG:
$type = "image/jpeg";
break;
case IMAGETYPE_PNG:
$type = "image/png";
break;
default:
$type = null;
$thumb = null;
}
} else {
$thumb = null;
$type = null;
}
$return = $this->image_upload($imgfile, $this->to, $type, $thumb);
if (isset($return["id"]) and preg_match("/^[0-9]+$/", $return["id"])) {
$thumb = $return["id"];
}
}
}
}
if ($this->to->draft == 1) {
$publish = "draft";
} else {
$publish = "publish";
}

$D_CATEGORY = explode(",", $this->history->category);
$categories = [];
foreach ($D_CATEGORY as $category) {
if ($category != "") {
$categories[] = XML_RPC2_Value::createFromNative($category, 'string');
}
}
$tags = [];
$terms = XML_RPC2_Value::createFromNative([
'category' => XML_RPC2_Value::createFromNative($categories, 'array'),
'post_tag' => XML_RPC2_Value::createFromNative($tags, 'array'),
], "struct");
$content = XML_RPC2_Value::createFromNative([
'post_title' => XML_RPC2_Value::createFromNative($D_BLOGTITLE, 'string'),
'post_content' => XML_RPC2_Value::createFromNative($D_BODYTEXT . $D_BODYMORE, 'string'),
'post_excerpt' => XML_RPC2_Value::createFromNative($D_BODYTEXT, 'string'),
'post_date' => XML_RPC2_Value::createFromNative(Carbon::now()->format("Ymd\TH:i:s"), 'datetime'),
'post_thumbnail' => XML_RPC2_Value::createFromNative($thumb, "int"),
'post_status' => XML_RPC2_Value::createFromNative($publish, "string"),
'terms_names' => $terms,
]
, 'struct');

try {
$message = $c->newPost($blog_id, $username, $password, $content);
} catch (XML_RPC2_FaultException $e) {
if (preg_match("/\<title\>(.*)\<\/title\>/", $e->getMessage(), $match)) {
return array("error" => $match[1]);
} else {
return array("error" => $e->getMessage());

}
} catch (Exception $e) {
if (preg_match("/\<title\>(.*)\<\/title\>/", $e->getMessage(), $match)) {
return array("error" => $match[1]);
} else {
return array("error" => $e->getMessage());

}
} catch (XML_RPC2_ReceivedInvalidStatusCodeException $e) {
if (preg_match("/\<title\>(.*)\<\/title\>/", $e->getMessage(), $match)) {
return array("error" => $match[1]);
} else {
return array("error" => $e->getMessage());

}
}

return ["id" => $message];

}

出典:code

これで、XML_RPC2での外部投稿が可能になります。
所々、2chまとめ自動投稿ツールのスクリプトの為、省略していたり、不要な部分はありますが、
その辺りは調整してみてください。

やや、Laravelを使用していますので、Carbon等も入っています。

この辺りも、指定する必要が有ります。
use XML_RPC2_Client;
use XML_RPC2_FaultException;
use XML_RPC2_ReceivedInvalidStatusCodeException;
use XML_RPC2_Value;

外部からの自動投稿方法はふたとおり

上記に上げた、XML_RPCもそうですが、もうひとつ、ATOMPUBと言う形式で外部からの投稿を受け付けているところもあります。
各ブログサービスごとに、外部投稿方法をリスト化して紹介します。

XML_RPCで投稿できるブログは、上の物を多少カスタマイズすることで、投稿できるようになります。
エンドポイントで検索し、
$host = parse_url($this->to->url, PHP_URL_HOST);
$path = rtrim(parse_url($this->to->url, PHP_URL_PATH), "/");
$xmlrpc = "/xmlrpc.php";
の部分等をそれぞれに合わせてカスタマイズしてください。

カテゴリーを最初から予め指定したものしか入力できないサイトなどもあるので、
その辺りは公式のドキュメント等をお読みください。

XML_RPC

Wordpress
FC2
Seesaa

AtomPub

Livedoor
Hatena

AtomPubはまた、全く別の方法になるため、
後ほど紹介したいと思います。

やること自体は一緒です。

おまけ 画像アップロード

上記のスクリプト上では、画像のアップロードがありませんが、
別枠でアップロードを先にしています。
XML_RPC2でのWordpressへの画像アップロードのスクリプトです。

function image_upload($imgfile, $to, $type, $imageurl = null) {
if ($imageurl == null) {
return;
}
if ($type == null) {
return;
}
$this->to = $to;

$host = parse_url($this->to->url, PHP_URL_HOST);
$path = rtrim(parse_url($this->to->url, PHP_URL_PATH), "/");
$xmlrpc = "/xmlrpc.php";

$D_USERNAME = $to->xpcid;
$D_PASSWORD = $to->xpcpass;

$username = XML_RPC2_Value::createFromNative($D_USERNAME, 'string');
$password = XML_RPC2_Value::createFromNative($D_PASSWORD, 'string');

$blogid = XML_RPC2_Value::createFromNative(0, 'string');
$encoding = "UTF-8";

$prefix = 'metaWeblog.';
$options = array("prefix" => $prefix);
$c = XML_RPC2_client::create($to->url . $xmlrpc, $options);

if ($imgfile) {
$dt = Carbon::now();
$filename = $dt->format("YmdHis") . $dt->micro;
switch ($type) {
case "image/jpeg":
$ext = ".jpg";
break;
case "image/gif":
$ext = ".gif";
break;
case "image/png":
$ext = ".png";
break;
}
$file = array(
'bits' => XML_RPC2_Value::createFromNative($imgfile, 'base64'),
// 'name' => XML_RPC2_Value::createFromNative(($this->history?mb_strimwidth(str_replace(["\"","'","<",">"," "," ",],$this->history->title),0,20,"","utf-8"):"thumb").$ext, 'string'),
'name' => XML_RPC2_Value::createFromNative(str_random(16) . $ext, 'string'),
'type' => XML_RPC2_Value::createFromNative($type, 'string'),
);
$wpFile = XML_RPC2_Value::createFromNative($file, 'struct');

try {
$message = $c->newMediaObject("", $username, $password, $wpFile);
} catch (XML_RPC2_FaultException $e) {
if (preg_match("/\<title\>(.*)\<\/title\>/", $e->getMessage(), $match)) {
return array("error" => $match[1]);
} else {
return array("error" => $e->getMessage());

}
} catch (Exception $e) {
if (preg_match("/\<title\>(.*)\<\/title\>/", $e->getMessage(), $match)) {
return array("error" => $match[1]);
} else {
return array("error" => $e->getMessage());

}
} catch (XML_RPC2_ReceivedInvalidStatusCodeException $e) {
if (preg_match("/\<title\>(.*)\<\/title\>/", $e->getMessage(), $match)) {
return array("error" => $match[1]);
} else {
return array("error" => $e->getMessage());

}
}

$uploadImageUrl = $message['url'];
return array("id" => $message["id"], "url" => $uploadImageUrl);
} else {
return array("error" => "Counld not get image");
}

}

出典:code

XML_RPCでWordpressに投稿する場合の注意点

サーバーによっては、XML_RPCを制限している場所があります。
投稿できない場合は、そうした制限を見てみてください。
サクラサーバーや、Xserverはそうした制限があります。

オススメの記事Gmatom注目まとめ

シェアする気になったらシェアする

ツイート

ユーザー情報ユーザーの紹介

Gmatom 浜田貴朗

2008年よりコミュニティサイトを運営しつつ、効果の高い広告はバナー広告では無く誘導的コンテンツ広告と気付き、コンテンツ作成を手掛ける。 ポイントサイト・キュレーションサイト・動画自動投稿サイトや自動記事作成ツール、自動フォローツール等ツールの開発等、主にウェブ系の業界にて開発・運営を行っています。 V系バーの立ち上げ・ウェブ戦略・立地戦略等飲食店の立ち上げ・運営も携わっていました。

関連するキーワードキーワードからまとめを探す