纯代码自动将 WordPress 网站文章信息同步到 X(Twitter)推特

以前我们分享过使用纯代码为 WordPress 添加自动同步到 Telegram 的功能。而此次给大家带来的是通过代码,为网站文章添加自动同步到 X(Twitter)的功能。

想要通过网站自动发推,我们需要注册开通 X 开发者平台账号,X 开发者平台可以直接使用现有的 X 账号登录。之后到下方地址,根据提示一步一步,分别新建项目(Projects)和应用(Apps)。

https://developer.x.com/en/portal/projects-and-apps

建立过程中注意保存我们后边需要用到的凭据信息:Consumer Keys(API Key and Secret) 以及 Access Token and Secret,另外选择权限时记得选择 Read and Write(可读写)。

如果过程中忘记保存也没关系,可以在仪表板或者项目(应用)概况中,点击 🔑(Keys and tokens / 消费者密钥和身份验证令牌)查看。

Project App Keys and tokens.webp

Keys and tokens(Consumer Keys & Authentication Tok.webp

如果权限不是 Read and Write,点击其右侧的 Revoke 或者 Regenerate 应该就能重置权限了。

之后将下方代码放到 functions.php 文件或者自定义的插件中,修改“3. Twitter API 凭据(填写你自己的)”部分,就可以使用了!

// WordPress 同步文章到 X(Twitter)
// -----------------------------------------------------
// 1. 添加后台 Meta Box
// -----------------------------------------------------
function add_twitter_sync_meta_box() {
add_meta_box(
'twitter_sync_meta_box',
'同步到 X (Twitter)',
'twitter_sync_meta_box_callback',
'post',
'side',
'high'
);
}
add_action('add_meta_boxes', 'add_twitter_sync_meta_box');

function twitter_sync_meta_box_callback($post) {
$is_synced = get_post_meta($post->ID, '_twitter_sync', true);
$checked = ($is_synced == 1);

echo '<label>';
echo '<input type="checkbox" name="twitter_sync" value="1" ' . checked($checked, true, false) . ' />';
echo ' 发布或更新时自动同步到 X';
echo '</label>';
}

// -----------------------------------------------------
// 2. 保存勾选状态
// -----------------------------------------------------
function save_twitter_sync_meta($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (get_post_type($post_id) != 'post') return;

update_post_meta($post_id, '_twitter_sync', isset($_POST['twitter_sync']) ? 1 : 0);
}
add_action('save_post', 'save_twitter_sync_meta');

// -----------------------------------------------------
// 3. Twitter API 凭据(填写你自己的)
// -----------------------------------------------------
function get_twitter_api_credentials() {
return [
'api_key' => 'YOUR_API_KEY',
'api_secret' => 'YOUR_API_SECRET',
'access_token' => 'YOUR_ACCESS_TOKEN',
'access_token_secret' => 'YOUR_ACCESS_SECRET',
];
}

// -----------------------------------------------------
// 4. 获取文章图片(封面图 > 内容第一张)
// -----------------------------------------------------
function get_post_image_url_for_twitter($post_id) {
$image = get_the_post_thumbnail_url($post_id, 'full');
if ($image) return $image;

$post = get_post($post_id);
if ($post && preg_match('/<img.+src=['"]([^'"]+)['"]/', $post->post_content, $m)) {
return $m[1];
}
return null;
}

// -----------------------------------------------------
// 5. OAuth1.0 签名(V1.1 上传 / V2 发送通用)
// -----------------------------------------------------
function twitter_signed_request($method, $url, $params, $creds) {
$oauth = [
'oauth_consumer_key' => $creds['api_key'],
'oauth_nonce' => md5(microtime(true)),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => time(),
'oauth_token' => $creds['access_token'],
'oauth_version' => '1.0'
];

$is_upload = (strpos($url, 'upload.twitter.com') !== false);

$base_params = ($method === 'POST' && !$is_upload)
? $oauth
: array_merge($oauth, $params);

ksort($base_params);

$param_str = [];
foreach ($base_params as $k => $v) {
$param_str[] = rawurlencode($k) . "=" . rawurlencode($v);
}
$param_str = implode("&", $param_str);

$base_string = strtoupper($method) . "&" . rawurlencode($url) . "&" . rawurlencode($param_str);
$signing_key = rawurlencode($creds['api_secret']) . "&" . rawurlencode($creds['access_token_secret']);
$oauth['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_string, $signing_key, true));

$auth_header = "OAuth " . implode(", ", array_map(
fn($k, $v) => rawurlencode($k) . '="' . rawurlencode($v) . '"',
array_keys($oauth),
$oauth
));

$args = [
'method' => $method,
'timeout' => 30,
'headers' => [
'Authorization' => $auth_header,
'Expect' => '',
],
];

if ($method === 'POST') {
if ($is_upload) {
$args['headers']['Content-Type'] = 'application/x-www-form-urlencoded';
$args['body'] = http_build_query($params);
} else {
$args['headers']['Content-Type'] = 'application/json';
$args['body'] = json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
}

return wp_remote_request($url, $args);
}

// -----------------------------------------------------
// 6. 上传媒体到 Twitter(V1.1)
// -----------------------------------------------------
function twitter_upload_media($image_url) {
$creds = get_twitter_api_credentials();

$img = wp_remote_get($image_url, ['timeout' => 30, 'sslverify' => false]);
if (is_wp_error($img)) return null;

$data = base64_encode(wp_remote_retrieve_body($img));
$res = twitter_signed_request(
'POST',
'https://upload.twitter.com/1.1/media/upload.json',
['media_data' => $data],
$creds
);

if (is_wp_error($res)) return null;

$json = json_decode(wp_remote_retrieve_body($res), true);
return $json['media_id_string'] ?? null;
}

// -----------------------------------------------------
// 7. 发送推文(V2)
// -----------------------------------------------------
function twitter_post_tweet($text, $media_id = null) {
$creds = get_twitter_api_credentials();

$data = ['text' => $text];
if ($media_id) {
$data['media'] = ['media_ids' => [$media_id]];
}

twitter_signed_request('POST', 'https://api.twitter.com/2/tweets', $data, $creds);
}

// -----------------------------------------------------
// 8. 主同步逻辑
// -----------------------------------------------------
function send_to_twitter($post_id) {
$sync = get_post_meta($post_id, '_twitter_sync', true);
if (!$sync) return;

$post = get_post($post_id);
if (!$post || $post->post_status !== 'publish') return;

$title = wp_strip_all_tags($post->post_title);
$link = get_permalink($post_id);
$text = $title . "nn" . $link;

$image_url = get_post_image_url_for_twitter($post_id);
$media_id = $image_url ? twitter_upload_media($image_url) : null;

twitter_post_tweet($text, $media_id);
}

// -----------------------------------------------------
// 9. 延迟执行,避免重复触发(发布/更新通用)
// -----------------------------------------------------
function delay_send_to_twitter($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;

$post = get_post($post_id);
if (!$post || $post->post_type !== 'post' || $post->post_status !== 'publish') return;

if (!get_post_meta($post_id, '_twitter_sync', true)) return;

if (!wp_next_scheduled('delayed_send_to_twitter_hook', [$post_id])) {
wp_schedule_single_event(time() + 5, 'delayed_send_to_twitter_hook', [$post_id]);
}
}
add_action('save_post', 'delay_send_to_twitter');

add_action('delayed_send_to_twitter_hook', 'send_to_twitter');

跟之前同步到 TG 的功能类似,上述代码同样会在 WordPress 后台文章编辑页添加一个复选框,用来选择是否同步到 X。同步信息包括文章标题、链接、特色图片(没有设置的话,会自动选择文章首图)。

效果参考:https://x.com/intent/follow?screen_name=atszzyg

| 二合一版本

同步 X 和 TG 功能二合一,融合相同逻辑的冗余代码,提升安全性:可选择将密钥等敏感信息放到 wp-config.php 文件,当然也可以直接在代码中设置……

此内容查看价格为9点数立即购买
充值说明:如有疑问请联系客服QQ&微信1828868518
0

评论0

没有账号?注册  忘记密码?

社交账号快速登录

微信扫一扫关注
如已关注,请回复“登录”二字获取验证码