RemoteFollowPipeline.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <?php
  2. namespace App\Jobs\RemoteFollowPipeline;
  3. use Zttp\Zttp;
  4. use App\{Profile};
  5. use GuzzleHttp\Client;
  6. use HttpSignatures\Context;
  7. use HttpSignatures\GuzzleHttpSignatures;
  8. use App\Jobs\RemoteFollowPipeline\RemoteFollowImportRecent;
  9. use App\Jobs\AvatarPipeline\CreateAvatar;
  10. use Illuminate\Bus\Queueable;
  11. use Illuminate\Queue\SerializesModels;
  12. use Illuminate\Queue\InteractsWithQueue;
  13. use Illuminate\Contracts\Queue\ShouldQueue;
  14. use Illuminate\Foundation\Bus\Dispatchable;
  15. class RemoteFollowPipeline implements ShouldQueue
  16. {
  17. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  18. protected $url;
  19. protected $follower;
  20. protected $response;
  21. /**
  22. * Create a new job instance.
  23. *
  24. * @return void
  25. */
  26. public function __construct($follower, $url)
  27. {
  28. $this->follower = $follower;
  29. $this->url = $url;
  30. }
  31. /**
  32. * Execute the job.
  33. *
  34. * @return void
  35. */
  36. public function handle()
  37. {
  38. $follower = $this->follower;
  39. $url = $this->url;
  40. if(Profile::whereRemoteUrl($url)->count() !== 0) {
  41. return true;
  42. }
  43. $this->discover($url);
  44. return true;
  45. }
  46. public function discover($url)
  47. {
  48. $context = new Context([
  49. 'keys' => ['examplekey' => 'secret-key-here'],
  50. 'algorithm' => 'hmac-sha256',
  51. 'headers' => ['(request-target)', 'date'],
  52. ]);
  53. $handlerStack = GuzzleHttpSignatures::defaultHandlerFromContext($context);
  54. $client = new Client(['handler' => $handlerStack]);
  55. $response = Zttp::withHeaders([
  56. 'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
  57. 'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org'
  58. ])->get($url);
  59. $this->response = $response->json();
  60. $this->storeProfile();
  61. }
  62. public function storeProfile()
  63. {
  64. $res = $this->response;
  65. $domain = parse_url($res['url'], PHP_URL_HOST);
  66. $username = $res['preferredUsername'];
  67. $remoteUsername = "@{$username}@{$domain}";
  68. $profile = new Profile;
  69. $profile->user_id = null;
  70. $profile->domain = $domain;
  71. $profile->username = $remoteUsername;
  72. $profile->name = $res['name'];
  73. $profile->bio = str_limit($res['summary'], 125);
  74. $profile->sharedInbox = $res['endpoints']['sharedInbox'];
  75. $profile->remote_url = $res['url'];
  76. $profile->save();
  77. RemoteFollowImportRecent::dispatch($this->response, $profile);
  78. CreateAvatar::dispatch($profile);
  79. }
  80. public function sendActivity()
  81. {
  82. $res = $this->response;
  83. $url = $res['inbox'];
  84. $activity = Zttp::withHeaders(['Content-Type' => 'application/activity+json'])->post($url, [
  85. 'type' => 'Follow',
  86. 'object' => $this->follower->url()
  87. ]);
  88. }
  89. }