如何使用 PHP GD 和 TwitterOAuth 动态更新 Twitter 封面图片以显示最新关注者
一周前,我看到了一条令我非常好奇的推文:
这让我想起职业生涯中其他几次兴奋不已,甚至近乎痴迷地想要弄清楚某样东西是如何制作的。第一次(很久以前)是看到一个“杂志封面工具”,只需上传一张照片即可生成杂志封面。这让我开启了一个全新的探索世界,也让我完成了第一个成功的项目,让我辞去了当时的工作,靠谷歌广告收入生活。没错,那是一个用PHP和GD语言制作的在线杂志封面生成器 :)
另一个让我同样渴望了解他们是如何做到的,是我发现了这个工具,可以追踪哪些人在 Twitter 上取消了关注。这又一次让我进入了一个充满发现、开源贡献和 Twitter API 深度挖掘的世界。
所以当我看到Tony的推文时,我意识到这基本上就是封面生成器 + Twitter API 的结合。我非常兴奋地想要实现它!花了大约一周时间,每天几个小时,因为我有一些可以重复使用和重新利用的小代码块。
这是最终结果,您也可以现场查看:
这个小项目让我兴奋的是,它的可能性是无限的。你可以展示任何你想要的内容,只要它有动态输出,并且可以通过编程方式获取(比如通过 API)。同样的方法也可以用来修改你的个人资料图片。
在本教程中,我们将构建一个更简单的动态标题版本,用于显示你最新的 5 位 Twitter 关注者。dynacover GitHub仓库包含一些其他模板,你稍后可以尝试一下。
好了,闲话少叙,我们开始行动吧!
开始之前
在继续之前,请确保您已准备好以下内容:
- 在dev.twitter.com上注册的具有读写权限的应用程序。
- 从应用程序设置页面获取以下4个令牌:
- 消费者/API 令牌(应用程序令牌)
- 消费者/API 秘密(应用程序秘密)
- 访问密钥(用户令牌)
- 访问秘密(用户秘密)
- 命令行中可运行的 PHP 开发环境,安装了以下依赖项:
php-cli
7.4+ext-gd
ext-json
ext-curl
- 作曲家
- 一张用作封面的 PNG 图片,将粘贴在所有图层的顶部。图片尺寸必须为 1500x500,并包含用于放置头像图片的透明占位符,例如这张,您可以自由使用和修改。如果您创建了包含不同位置占位符的自定义横幅,则还需要每个占位符的大小和坐标。
我们鼓励您使用源代码编辑器(例如Visual Studio Code)来促进 PHP 项目内的工作。
在本演示中,我们将使用Minicli(一个极简的 PHP 命令行应用程序框架)创建一个命令行应用程序。我们将使用TwitterOAuth库与 Twitter API 进行通信。
如果您希望使用现有存储库中的代码,或者只是想尝试一下这个演示,您可以查看GitHub 上的erikaheidi/dynacover。为了匹配本指南中的代码,请下载0.1 版本,因为main
分支会随着时间而变化。
1. 引导应用程序
首先使用Minicli启动一个小型命令行应用程序。这里我们将其命名为dynacover。
composer create-project --prefer-dist minicli/application dynacover
Creating a "minicli/application" project at "./dynacover"
Installing minicli/application (2.0.1)
- Installing minicli/application (2.0.1): Extracting archive
Created project in /home/erika/Projects/dynacover
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking minicli/minicli (2.2.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing minicli/minicli (2.2.1): Extracting archive
Generating autoload files
1 package you are using is looking for funding.
Use the `composer fund` command to find out more!
这将引导应用程序。进入新目录并查看文件。以下是新 Minicli 应用程序中目录结构的简要概述:
cd dynacover
.
├── app
│ └── Command
├── composer.json
├── composer.lock
├── LICENSE
├── minicli
├── README.md
└── vendor
├── autoload.php
├── composer
└── minicli
该app/Command
目录是所有命令的定义位置。我们将在下一步中处理这个问题。
接下来,abraham/twitteroauth
通过 Composer 将其作为依赖项包含进来:
composer require abraham/twitteroauth
您还可以重命名脚本以匹配应用程序名称:
mv minicli dynacover
要测试一切是否按预期工作,请运行:
php dynacover help
您应该看到以下输出:
Available Commands
help
└──table
└──test
这些命令已在目录中实现,app/Command/Help/
作为示例命令,您可以参考一下。下一步,我们将开始创建新命令。
2. 使用 TwitterOAuth 库获取新关注者
在编写动态生成图像的代码之前,首先确保您可以使用 TwitterOAuth 库和您的应用程序/用户密钥获取您的最新关注者。
我们将创建一个简单的命令来列出您的最新关注者。
首先,我们需要设置 Twitter 令牌,以便您可以从命令控制器获取它们。最简单的方法是创建一个包含凭证的单独文件,并将其导入到应用程序的配置中。.gitignore
如果您使用版本控制,还应确保此文件包含在您的配置文件中,以免它与应用程序代码一起提交。
安全存储 Twitter 凭证
在应用程序文件夹的根目录中创建一个名为 的新文件credentials.php
。该文件应返回一个包含应用程序敏感数据的数组。
将以下内容复制到您的credentials.php
文件中,并用您自己的 Twitter 凭据替换所有密钥:
#credentials.php
<?php
return [
'twitter_consumer_key' => 'APP_CONSUMER_KEY',
'twitter_consumer_secret' => 'APP_CONSUMER_SECRET',
'twitter_user_token' => 'USER_ACCESS_TOKEN',
'twitter_token_secret' => 'USER_ACCESS_TOKEN_SECRET',
];
为了确保此文件不包含在版本控制中,你应该在.gitignore
文件中添加一行。你可以使用以下命令执行此操作,该命令会将新行添加到该文件:
echo "credentials.php" >> .gitignore
然后,编辑dynacover
脚本将这些数据合并到主配置中。操作如下:
#dynacover
#!/usr/bin/php
<?php
if (php_sapi_name() !== 'cli') {
exit;
}
require __DIR__ . '/vendor/autoload.php';
use Minicli\App;
$config = [
'app_path' => __DIR__ . '/app/Command'
];
if (is_file(__DIR__ . '/credentials.php')) {
$config = array_merge($config, include __DIR__ . '/credentials.php');
}
$app = new App($config);
$app->runCommand($argv);
现在您应该能够从任何命令控制器获取这些凭据。
创建新命令来获取关注者
有了凭证后,您就可以开始使用 Twitter API 了。在其中创建一个app/Command
名为 的新目录Fetch
。
mkdir app/Command/Fetch
使用您首选的代码编辑器在 创建一个新文件app/Command/Fetch/FollowersController.php
。这是一个需要从 扩展的类,Minicli\Command\CommandController
并实现一个名为 的方法handle
,该方法将在从提示符调用命令时处理该命令。
从该handle
方法中,您将从对象中获取所需的凭据$this->getApp()->config
,可以作为魔术属性访问:
$api_token = $this->getApp()->config->twitter_consumer_key;
$api_secret = $this->getApp()->config->twitter_consumer_secret;
$access_token = $this->getApp()->config->twitter_user_token;
$token_secret = $this->getApp()->config->twitter_token_secret;
然后,使用该TwitterOAuth
库,您可以创建一个请求来获取您的最新关注者。
$client = new TwitterOAuth($api_token, $api_secret, $access_token, $token_secret);
$followers = $client->get('/followers/list', [
'skip_status' => true,
'count' => 10
]);
以下代码包含完整的实现,并在最后列出了结果作为输出:
#app/Command/Fetch/FollowersController.php
<?php
namespace App\Command\Fetch;
use Minicli\Command\CommandController;
use Abraham\TwitterOAuth\TwitterOAuth;
class FollowersController extends CommandController
{
public function handle()
{
$api_token = $this->getApp()->config->twitter_consumer_key;
$api_secret = $this->getApp()->config->twitter_consumer_secret;
$access_token = $this->getApp()->config->twitter_user_token;
$token_secret = $this->getApp()->config->twitter_token_secret;
$client = new TwitterOAuth($api_token, $api_secret, $access_token, $token_secret);
$followers = $client->get('/followers/list', [
'skip_status' => true,
'count' => 10
]);
$this->getPrinter()->info("Latest Followers", true);
foreach ($followers->users as $follower) {
$this->getPrinter()->info($follower->screen_name);
}
$this->getPrinter()->info("Finished.");
return 0;
}
}
您现在可以用以下命令运行此命令:
php dynacover fetch followers
如果一切按预期进行,您应该会看到一个包含最近 10 位新关注者的列表,如下所示:
有了这些数据,我们就可以开始构建动态封面图像。
3. 生成带有用户头像的封面
现在,您将构建一个新命令来生成封面图片。我们需要一张基础图片,将其粘贴在头像图片之上,以获得最佳效果。我使用Canva创建了封面图片,但您可以使用任何能够处理 PNG 格式和透明度的图像/照片编辑器。
在本演示中,我们将使用此示例图片。在 Canva 上创建此图片后,我在 Gimp 上打开了它,并使用圆形选择工具选择要放置个人资料图片的位置,然后点击“删除”按钮删除图片的该部分并使其透明:
我们的坐标将基于该图像。
设置示例封面图片
app
在目录中创建一个名为的新文件夹Resources
来放置此封面图像。
mkdir app/Resources
cp ~/Downloads/cover_basic.png app/Resources/twitter_cover.png
创建封面生成命令
mkdir app/Command/Cover
在该文件夹中创建一个名为 的新命令控制器GenerateController
,以便稍后可以访问它dynacover cover generate
。您可以将以下引导代码放入其中:
<?php
namespace App\Command\Cover;
use Minicli\Command\CommandController;
class GenerateController extends CommandController
{
public function handle()
{
// TODO: Implement handle() method.
}
}
以下是我们现在需要做的事情:
1) 获取最新关注者(5);
3) 将他们的头像下载到临时位置;
4) 使用创建一个新的 GD 图像资源imagecreatetruecolor
,尺寸为 1500x500;
5) 循环遍历具有正确坐标的数组以粘贴头像图像,并使用imagecopyresampled
将这些图像放置在空白的 GD 资源中;
6) 最后将 PNG 图像放在顶部;
7) 将图像写入固定位置,以便我们稍后将其上传到 Twitter。
如果你想挑战一下,自己动手实现一下,那就来吧!我鼓励你尝试一下。如果你只是想看看它能不能运行,可以将下面的控制器代码复制到你自己的GenerateController.php
文件中。
#app/Command/Cover/GenerateController.php
<?php
namespace App\Command\Cover;
use Abraham\TwitterOAuth\TwitterOAuth;
use Minicli\Command\CommandController;
class GenerateController extends CommandController
{
public function handle()
{
$api_token = $this->getApp()->config->twitter_consumer_key;
$api_secret = $this->getApp()->config->twitter_consumer_secret;
$access_token = $this->getApp()->config->twitter_user_token;
$token_secret = $this->getApp()->config->twitter_token_secret;
$client = new TwitterOAuth($api_token, $api_secret, $access_token, $token_secret);
$followers = $client->get('/followers/list', [
'skip_status' => true,
'count' => 5
]);
if (!isset($followers->users)) {
$this->getPrinter()->error("An error occurred.");
return 1;
}
$users = $followers->users;
$placeholders = $this->getPlaceholders();
$cover_final = imagecreatetruecolor(1500, 500);
foreach ($placeholders as $key => $placeholder) {
$follower = $users[$key];
$this->getPrinter()->info("Adding user to banner: $follower->screen_name");
$path = $this->downloadAvatar($follower->profile_image_url);
$resource = $this->getResource($path);
$info = getimagesize($path);
if ($resource) {
imagecopyresampled(
$cover_final,
$resource,
$placeholder['pos_x'],
$placeholder['pos_y'],
0,
0,
$placeholder['width'],
$placeholder['height'],
$info[0],
$info[1]
);
}
}
//now finish with the cover image on top
$cover = imagecreatefrompng(__DIR__ . '/../../Resources/cover_template.png');
if ($cover) {
imagecopyresized(
$cover_final,
$cover,
0,
0,
0,
0,
1500,
500,
1500,
500
);
}
$save_path = __DIR__ . '/../../../latest_header.png';
imagepng($cover_final, $save_path);
$this->getPrinter()->info("Finished generating cover at $save_path.");
return 0;
}
public function getPlaceholders(): array
{
return [
[
'pos_x' => 486,
'pos_y' => 272,
'width' => 130,
'height' => 130
],[
'pos_x' => 670,
'pos_y' => 272,
'width' => 130,
'height' => 130
],[
'pos_x' => 859,
'pos_y' => 272,
'width' => 130,
'height' => 130
],[
'pos_x' => 1049,
'pos_y' => 272,
'width' => 130,
'height' => 130
],[
'pos_x' => 1236,
'pos_y' => 272,
'width' => 130,
'height' => 130
]
];
}
public function getResource($path)
{
$info = getimagesize($path);
$extension = image_type_to_extension($info[2]);
if (strtolower($extension) == '.png') {
return imagecreatefrompng($path);
}
if (strtolower($extension) == '.jpeg' OR strtolower($extension) == '.jpg') {
return imagecreatefromjpeg($path);
}
return null;
}
public function downloadAvatar($url): string
{
$file_contents = file_get_contents($url);
$file_path = "/tmp/" . basename($url);
$image = fopen($file_path, "w+");
fwrite($image, $file_contents);
fclose($image);
return $file_path;
}
}
您可以使用以下命令运行该命令:
php dynacover cover generate
完成后,检查应用程序的根目录以查看生成的图像。它应该类似于以下内容:
当然,您可以随意自定义图片和占位符的位置。只需记住相应地调整坐标即可。Dynacover GitHub 仓库中还有其他一些封面模板。
一旦您对生成的封面感到满意,您就可以继续执行命令来更新您的推特封面。
4. 以编程方式更新 Twitter 封面图片
现在唯一缺少的是使用 API 实际更新 Twitter 个人资料中的封面图片的部分。
app/Command/Cover
在里面创建一个名为 的新命令控制器UpdateController
。
以下控制者将:
1) 调用dynacover cover generate
命令以确保我们有要上传的更新图像2) 使用 TwitterOAuth 库和/account/update_profile_banner
端点 将新图像发布到 Twitter 。
#app/Command/Cover/UpdateController
<?php
namespace App\Command\Cover;
use Abraham\TwitterOAuth\TwitterOAuth;
use Minicli\Command\CommandController;
class UpdateController extends CommandController
{
public function handle()
{
$banner_path = __DIR__ . '/../../../latest_header.png';
$this->getPrinter()->info("Generating new cover...");
$this->getApp()->runCommand(['dynacover', 'cover', 'generate']);
$api_token = $this->getApp()->config->twitter_consumer_key;
$api_secret = $this->getApp()->config->twitter_consumer_secret;
$access_token = $this->getApp()->config->twitter_user_token;
$token_secret = $this->getApp()->config->twitter_token_secret;
$client = new TwitterOAuth($api_token, $api_secret, $access_token, $token_secret);
$post = [
'width' => 1500,
'height' => 500,
'offset_top' => 0,
'offset_left' => 0,
'banner' => base64_encode(file_get_contents($banner_path))
];
$this->getPrinter()->info("Uploading cover to Twitter...");
$client->post('/account/update_profile_banner', $post);
$this->getPrinter()->info("Finished uploading new banner.");
return 0;
}
}
设置好此控制器后,您可以运行:
php dynacover cover update
然后检查您的 Twitter 个人资料以验证新封面是否已上传。
5. 在 Crontab 中包含脚本(可选)
自动生成封面的最后一步是将更新脚本包含在 Crontab 或同等程序中,以一定的固定间隔运行(例如每 5 或 10 分钟)。
我已将 Crontab 设置为每 5 分钟运行一次,以下是我执行的操作:
crontab -e
这将为您的用户打开一个包含 crontab 的文本编辑器。以下行将每 5 分钟(*/5
)执行一次指定的命令,并将输出发送到/dev/null
:
*/5 * * * * /usr/bin/php /home/erika/dynacover/dynacover cover update > /dev/null 2>&1
保存并退出后,新的 crontab 将被安装。请注意,此设置应在远程实时服务器上进行,使用本地计算机运行计划脚本不太可靠php
。请始终对可执行文件和脚本使用完整路径dynacover
。
结论
在本教程中,我们了解了如何以编程方式生成 Twitter 封面/标题图像并将其上传到您的个人资料,以便您可以显示您的最新关注者。
虽然本指南的主题是 Twitter 粉丝和 Twitter 个人资料标题图片,但同样的原则也适用于为其他网络生成图片并使用其他 API。查看dynacover GitHub获取一些思路。
PHP GD 库非常强大,这只是我们可以用它构建的有趣事物的冰山一角!
我希望您喜欢本教程,并请在实施后分享您的个人资料:)
文章来源:https://dev.to/erikaheidi/how-to-dynamically-update-twitter-cover-image-to-show-latest-followers-using-php-gd-and-twitteroauth-62n