Skip to content

Commit

Permalink
feat: 支援 Bluesky 平台發表文章
Browse files Browse the repository at this point in the history
  • Loading branch information
Kantai235 committed Dec 17, 2023
1 parent aaee34d commit 969ebd5
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 0 deletions.
8 changes: 8 additions & 0 deletions app/Console/Commands/Social/PlatformCardsNotification.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Console\Commands\Social;

use App\Domains\Social\Jobs\Publish\BskyPublishJob;
use App\Domains\Social\Jobs\Publish\DiscordPublishJob;
use App\Domains\Social\Jobs\Publish\FacebookPublishJob;
use App\Domains\Social\Jobs\Publish\PlurkPublishJob;
Expand Down Expand Up @@ -239,6 +240,13 @@ public function handle()
dispatch(new TelegramPublishJob($card, $platform))->onQueue('highest');
break;

/**
* 丟給負責發表文章到 Bsky 的 Job
*/
case Platform::TYPE_BSKY:
dispatch(new BskyPublishJob($card, $platform))->onQueue('highest');
break;

/**
* 其它並不在支援名單當中的社群
*/
Expand Down
8 changes: 8 additions & 0 deletions app/Console/Commands/Social/PlatformCardsPublish.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Console\Commands\Social;

use App\Domains\Social\Jobs\Publish\BskyPublishJob;
use App\Domains\Social\Jobs\Publish\DiscordPublishJob;
use App\Domains\Social\Jobs\Publish\FacebookPublishJob;
use App\Domains\Social\Jobs\Publish\PlurkPublishJob;
Expand Down Expand Up @@ -247,6 +248,13 @@ public function handle()
dispatch(new TelegramPublishJob($card, $platform))->onQueue('highest');
break;

/**
* 丟給負責發表文章到 Bsky 的 Job
*/
case Platform::TYPE_BSKY:
dispatch(new BskyPublishJob($card, $platform))->onQueue('highest');
break;

/**
* 其它並不在支援名單當中的社群
*/
Expand Down
8 changes: 8 additions & 0 deletions app/Console/Commands/Social/ReviewsPublish.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Console\Commands\Social;

use App\Domains\Social\Jobs\Publish\BskyPublishJob;
use App\Domains\Social\Jobs\Publish\DiscordPublishJob;
use App\Domains\Social\Jobs\Publish\FacebookPublishJob;
use App\Domains\Social\Jobs\Publish\PlurkPublishJob;
Expand Down Expand Up @@ -248,6 +249,13 @@ public function handle()
dispatch(new TelegramPublishJob($model, $platform))->onQueue('highest');
break;

/**
* 丟給負責發表文章到 Bsky 的 Job
*/
case Platform::TYPE_BSKY:
dispatch(new BskyPublishJob($card, $platform))->onQueue('highest');
break;

/**
* 其它並不在支援名單當中的社群
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Domains\Social\Http\Controllers\Api\Cards;

use App\Domains\Social\Jobs\Publish\BskyPublishJob;
use App\Domains\Social\Jobs\Publish\DiscordPublishJob;
use App\Domains\Social\Jobs\Publish\FacebookPublishJob;
use App\Domains\Social\Jobs\Publish\PlurkPublishJob;
Expand Down Expand Up @@ -150,6 +151,13 @@ public function voting(Request $request, Cards $card, $status)
dispatch(new TelegramPublishJob($model, $platform))->onQueue('highest');
break;

/**
* 丟給負責發表文章到 Bsky 的 Job
*/
case Platform::TYPE_BSKY:
dispatch(new BskyPublishJob($card, $platform))->onQueue('highest');
break;

/**
* 其它並不在支援名單當中的社群
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Domains\Social\Http\Requests\Backend\Cards\EditCardsRequest;
use App\Domains\Social\Http\Requests\Backend\Cards\StoreCardsRequest;
use App\Domains\Social\Http\Requests\Backend\Cards\UpdateCardsRequest;
use App\Domains\Social\Jobs\Publish\BskyPublishJob;
use App\Domains\Social\Jobs\Publish\DiscordPublishJob;
use App\Domains\Social\Jobs\Publish\FacebookPublishJob;
use App\Domains\Social\Jobs\Publish\PlurkPublishJob;
Expand Down Expand Up @@ -153,6 +154,12 @@ public function platform(Cards $cards)
dispatch(new TelegramPublishJob($cards, $platform))->onQueue('highest');
break;

/**
* 丟給負責發表文章到 Bsky 的 Job
*/
case Platform::TYPE_BSKY:
dispatch(new BskyPublishJob($cards, $platform))->onQueue('highest');
break;
/**
* 其它並不在支援名單當中的社群
*/
Expand Down Expand Up @@ -234,6 +241,12 @@ public function notification(Cards $cards)
dispatch(new TelegramPublishJob($cards, $platform))->onQueue('highest');
break;

/**
* 丟給負責發表文章到 Bsky 的 Job
*/
case Platform::TYPE_BSKY:
dispatch(new BskyPublishJob($cards, $platform))->onQueue('highest');
break;
/**
* 其它並不在支援名單當中的社群
*/
Expand Down
178 changes: 178 additions & 0 deletions app/Domains/Social/Jobs/Publish/BskyPublishJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<?php

namespace App\Domains\Social\Jobs\Publish;

use App\Domains\Social\Models\Cards;
use App\Domains\Social\Models\Platform;
use App\Domains\Social\Services\Content\ContentFluent;
use App\Domains\Social\Services\PlatformCardService;
use Illuminate\Bus\Queueable;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;

/**
* Class BskyPublishJob.
*/
class BskyPublishJob implements ShouldQueue
{
use Dispatchable,
InteractsWithQueue,
Queueable,
SerializesModels;

/**
* @var Cards
*/
protected $cards;

/**
* @var Platform
*/
protected $platform;

/**
* Create a new job instance.
*
* @param Cards $cards
* @param Platform $platform
*
* @return void
*/
public function __construct(Cards $cards, Platform $platform)
{
$this->cards = $cards;
$this->platform = $platform;
}

/**
* Execute the job.
*
* 發表到 Bsky
* 文章內提及連結會影響觸及率,因此需要留言補充連結宣傳。
*
* @return void
*/
public function handle()
{
/**
* 判斷 Page ID、Access Token 是否為空
*/
if (!isset($this->platform->config['identifier']) ||
!isset($this->platform->config['password'])) {
/**
* Config 有問題,無法處理
*/
activity('social cards - publish error')
->performedOn($this->cards)
->log(json_encode($this->platform));

return;
}

/**
* 建立 Content 內容編排器
*/
$container = Container::getInstance();
$contentFluent = $container->make(ContentFluent::class);
$platformCardService = $container->make(PlatformCardService::class);

/**
* 判斷文章是否已經發表出去
*/
if ($platformCard = $platformCardService->findPlatformCardById($this->platform->id, $this->cards->id)) {
/**
* 在這個 Facebook 已經將文章發表出去,並且記錄起來了
*/
activity('social cards - facebook post published')
->performedOn($this->cards)
->log(json_encode($platformCard));

return;
}

/**
* 整理文章通知的內容
*/
$message = $contentFluent->reset()
->header($this->cards->id)
->hr()
->body($this->cards->content)
->build();

$accessResponse = Http::post('https://bsky.social/xrpc/com.atproto.server.createSession', [
'identifier' => $this->platform->config['identifier'],
'password' => $this->platform->config['password'],
]);

$path = str_replace(appUrl() . '/storage', 'public', $this->cards->getPicture());
$type = Storage::mimeType($path);
$file = Storage::get($path);
$blobResponse = Http::withHeaders([
'Authorization' => sprintf('Bearer %s', $accessResponse->json()['accessJwt']),
'Accept' => $type,
'Content-Type' => $type,
])->withBody($file, $type)->post('https://bsky.social/xrpc/com.atproto.repo.uploadBlob');

$recordResponse = Http::withHeaders([
'Accept' => 'application/json',
'Authorization' => sprintf('Bearer %s', $accessResponse->json()['accessJwt']),
])->post('https://bsky.social/xrpc/com.atproto.repo.createRecord', [
'repo' => $accessResponse->json()['did'],
'collection' => 'app.bsky.feed.post',
'record' => [
'$type' => 'app.bsky.feed.post',
'text' => $message,
'createdAt' => now()->toIso8601ZuluString(),
'langs' => [
'zh-TW',
],
'embed' => [
'$type' => 'app.bsky.embed.images',
'images' => [
[
'alt' => $message,
'image' => $blobResponse->json()['blob'],
],
],
],
],
]);

/**
* 紀錄 response 資訊
*/
activity('social cards - bsky publish')
->performedOn($this->cards)
->log($recordResponse->body());

/**
* 建立 PlatformCards 紀錄
*/
$platform_string_id = str_replace(sprintf('at://%s/app.bsky.feed.post/', $accessResponse->json()['did']), '', $recordResponse->json()['uri']);
$platformCard = $platformCardService->store([
'platform_type' => Platform::TYPE_BSKY,
'platform_id' => $this->platform->id,
'platform_string_id' => $platform_string_id,
'platform_url' => sprintf(
'https://bsky.app/profile/%s/post/%s',
$this->platform->config['pages_name'],
$platform_string_id,
),
'card_id' => $this->cards->id,
]);

/**
* 紀錄 PlatformCards
*/
activity('social cards - bsky platform card')
->performedOn($platformCard)
->log(json_encode($platformCard));

return;
}
}
7 changes: 7 additions & 0 deletions app/Domains/Social/Listeners/CardsEventListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Domains\Social\Events\Cards\ArticleCreated;
use App\Domains\Social\Events\Cards\PictureCreated;
use App\Domains\Social\Jobs\Publish\BskyPublishJob;
use App\Domains\Social\Jobs\Publish\DiscordPublishJob;
use App\Domains\Social\Jobs\Publish\FacebookPublishJob;
use App\Domains\Social\Jobs\Publish\PlurkPublishJob;
Expand Down Expand Up @@ -122,6 +123,12 @@ private function notification(array $data): void
dispatch(new TelegramPublishJob($card, $platform))->onQueue('highest');
break;

/**
* 丟給負責發表文章到 Bsky 的 Job
*/
case Platform::TYPE_BSKY:
dispatch(new BskyPublishJob($card, $platform))->onQueue('highest');
break;
/**
* 其它並不在支援名單當中的社群
*/
Expand Down
7 changes: 7 additions & 0 deletions app/Domains/Social/Models/Platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ class Platform extends Model
*/
public const TYPE_TELEGRAM = 'telegram';

/**
* 分類: 本地 Bsky
*
* @var string
*/
public const TYPE_BSKY = 'bsky';

/**
* The table associated with the model.
*
Expand Down

0 comments on commit 969ebd5

Please sign in to comment.