Last active
July 6, 2023 01:43
-
-
Save tiagoandrepro/9e0528b254a80baf466d1a8a8e540913 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"entry": [ | |
{ | |
"id": "108668968127687", | |
"time": 1688574192, | |
"changes": [ | |
{ | |
"field": "feed", | |
"value": { | |
"from": { | |
"id": "6641860719170915", | |
"name": "Tiago Ribeiro" | |
}, | |
"item": "comment", | |
"post": { | |
"id": "108668968127687_309238454782311", | |
"status_type": "mobile_status_update", | |
"is_published": true, | |
"updated_time": "2023-07-05T16:23:09+0000", | |
"permalink_url": "https://www.facebook.com/permalink.php?story_fbid=pfbid02ohGBfrSA1yFu39kCMRP6GzP5wq3bT7tbKvrVSqWWv4BFvfmDzZMXbUmqjjYhibuKl&id=100070884768232", | |
"promotion_status": "inactive" | |
}, | |
"verb": "add", | |
"message": "ore por minha familia", | |
"post_id": "108668968127687_309238454782311", | |
"parent_id": "108668968127687_309238454782311", | |
"comment_id": "309238454782311_1196445024343184", | |
"created_time": 1688574189 | |
} | |
} | |
] | |
} | |
], | |
"object": "page" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Jobs; | |
use App\Events\CommentEvent; | |
use App\Models\Api; | |
use App\Models\Comment; | |
use App\Models\Contact; | |
use App\Models\Conversation; | |
use App\Models\Post; | |
use App\Models\Service; | |
use App\Utils\Botpress; | |
use App\Utils\OpenAi; | |
use Illuminate\Bus\Queueable; | |
use Illuminate\Contracts\Queue\ShouldQueue; | |
use Illuminate\Foundation\Bus\Dispatchable; | |
use Illuminate\Queue\InteractsWithQueue; | |
use Illuminate\Queue\SerializesModels; | |
use Illuminate\Support\Facades\Log; | |
class CommentJob implements ShouldQueue | |
{ | |
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | |
/** | |
* Create a new job instance. | |
*/ | |
public $comment, $service; | |
public function __construct($service, $comment) | |
{ | |
$this->comment = $comment; | |
$this->service = $service; | |
} | |
/** | |
* Execute the job. | |
*/ | |
public function handle(): void | |
{ | |
$service = Service::where('external_id', $this->service)->first(); | |
$contact = Contact::updateOrCreate([ | |
'external_id' => $this->comment['value']['from']['id'], | |
'service_id' => $service->id | |
], [ | |
'name' => $this->comment['value']['from']['name'] | |
]); | |
$post = Post::updateOrCreate([ | |
'external_id' => $this->comment['value']['post']['id'] | |
], [ | |
'type' => $this->comment['value']['post']['status_type'], | |
'service_id' => $service->id, | |
]); | |
if ($post->wasRecentlyCreated) { | |
PostUpdateJob::dispatchSync($post); | |
} | |
$comment = Comment::updateOrCreate([ | |
'external_id' => $this->comment['value']['comment_id'], | |
], [ | |
'post_id' => $post->id, | |
'message' => $this->comment['value']['message'] ?? null, | |
'parent_id' => $this->comment['value']['parent_id'], | |
'created_time' => $this->comment['value']['created_time'], | |
'contact_id' => $contact->id, | |
'service_id' => $service->id, | |
'is_echo' => $service->external_id == $contact->external_id, | |
'photo' => $this->comment['value']['photo'] ?? null, | |
'video' => $this->comment['value']['video'] ?? null | |
]); | |
event(new CommentEvent($comment)); | |
if ($comment->message == null) { | |
try { | |
$response = \App\Utils\Facebook::run('GET', $comment->external_id, [ | |
'access_token' => $service->token, | |
'fields' => 'attachment' | |
]); | |
if (isset($response->attachment)) { | |
$comment->update([ | |
'attachment' => json_encode($response->attachment) | |
]); | |
} | |
} catch (Exception $e) { | |
Log::info($e); | |
} | |
} | |
if ($service->external_id != $contact->external_id) { | |
if (env('APP_ENV') == 'production') { | |
if (!is_null($comment->message) and $comment->is_reply_comment == false) { | |
$responses = Botpress::setText($comment->message, $contact->id, 'ely-teruel'); | |
$openAi = OpenAi::chat($comment->contact->name, $comment->message); | |
Api::create([ | |
'comment_id' => $comment->id, | |
'data' => $openAi, | |
'source' => 'OpenAI' | |
]); | |
$comment->update([ | |
'reply' => $openAi | |
]); | |
$comments = \App\Utils\Facebook::run('GET', $comment->external_id, [ | |
'access_token' => $service->token, | |
'fields' => 'id,parent,message' | |
]); | |
if (isset($comments->parent) == false) { | |
\App\Utils\Facebook::run('POST', $comment->external_id . '/comments', [ | |
'access_token' => $service->token, | |
'message' => $comment->reply->choices[0]->message->content | |
]); | |
$comment->update([ | |
'is_reply_comment' => true, | |
]); | |
if ($contact->chats->count() == 0) { | |
foreach ($responses->responses as $response) { | |
\App\Utils\Facebook::run('POST', $service->external_id . '/messages', [ | |
'access_token' => $service->token, | |
'message' => ['text' => $response->text], | |
'recipient' => ['comment_id' => $comment->external_id], | |
'message_type' => 'RESPONSE' | |
]); | |
$comment->update([ | |
'is_reply_inbox' => true, | |
]); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"entry": [ | |
{ | |
"id": "108668968127687", | |
"time": 1688572808933, | |
"messaging": [ | |
{ | |
"sender": { | |
"id": "6615556848467333" | |
}, | |
"message": { | |
"mid": "m_k_3qx353XpMA0iyb2J6cMOCyWxW6M26mqzWNxWlhxSK_5qIwnlpwfZxaNc3_cFF_CZwBBbGVqrg2m9LbgiVDrQ", | |
"text": "06149310" | |
}, | |
"recipient": { | |
"id": "108668968127687" | |
}, | |
"timestamp": 1688572808608 | |
} | |
] | |
} | |
], | |
"object": "page" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"entry": [ | |
{ | |
"id": "108668968127687", | |
"time": 1688572823341, | |
"messaging": [ | |
{ | |
"sender": { | |
"id": "108668968127687" | |
}, | |
"message": { | |
"mid": "m_6dHZ--vDXTloM9FjRT_EZOCyWxW6M26mqzWNxWlhxSLpgfjyIj9ABCeYs-ej0cRaYISlajVTj8BY0BaImdvRJQ", | |
"text": "Qual número da residencia?", | |
"app_id": 9315000188573062, | |
"is_echo": true | |
}, | |
"recipient": { | |
"id": "6615556848467333" | |
}, | |
"timestamp": 1688572823242 | |
} | |
] | |
} | |
], | |
"object": "page" | |
} |
jjcodes78
commented
Jul 6, 2023
$recMsg = (new WebhookData(receiveComment()));
// return $recMsg->getEntry();
$pipe = Pipeline::send($recMsg)
->through([
ValidateService::class,
ValidateMessage::class,
ValidateComment::class,
])->thenReturn();
<?php
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Pipeline;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
function sendMessage(): array
{
return json_decode(<<<EOD
{
"entry": [
{
"id": "108668968127687",
"time": 1688572823341,
"messaging": [
{
"sender": {
"id": "108668968127687"
},
"message": {
"mid": "m_6dHZ--vDXTloM9FjRT_EZOCyWxW6M26mqzWNxWlhxSLpgfjyIj9ABCeYs-ej0cRaYISlajVTj8BY0BaImdvRJQ",
"text": "Qual número da residencia?",
"app_id": 9315000188573062,
"is_echo": true
},
"recipient": {
"id": "6615556848467333"
},
"timestamp": 1688572823242
}
]
}
],
"object": "page"
}
EOD, true, 512, JSON_OBJECT_AS_ARRAY);
}
function receiveMessage(): array
{
return json_decode(<<<EOD
{
"entry": [
{
"id": "108668968127687",
"time": 1688572808933,
"messaging": [
{
"sender": {
"id": "6615556848467333"
},
"message": {
"mid": "m_k_3qx353XpMA0iyb2J6cMOCyWxW6M26mqzWNxWlhxSK_5qIwnlpwfZxaNc3_cFF_CZwBBbGVqrg2m9LbgiVDrQ",
"text": "06149310"
},
"recipient": {
"id": "108668968127687"
},
"timestamp": 1688572808608
}
]
}
],
"object": "page"
}
EOD, true, 512, JSON_OBJECT_AS_ARRAY);
}
function receiveComment(): array
{
return json_decode(<<<EOD
{
"entry": [
{
"id": "108668968127687",
"time": 1688574192,
"changes": [
{
"field": "feed",
"value": {
"from": {
"id": "6641860719170915",
"name": "Tiago Ribeiro"
},
"item": "comment",
"post": {
"id": "108668968127687_309238454782311",
"status_type": "mobile_status_update",
"is_published": true,
"updated_time": "2023-07-05T16:23:09+0000",
"permalink_url": "https://www.facebook.com/permalink.php?story_fbid=pfbid02ohGBfrSA1yFu39kCMRP6GzP5wq3bT7tbKvrVSqWWv4BFvfmDzZMXbUmqjjYhibuKl&id=100070884768232",
"promotion_status": "inactive"
},
"verb": "add",
"message": "ore por minha familia",
"post_id": "108668968127687_309238454782311",
"parent_id": "108668968127687_309238454782311",
"comment_id": "309238454782311_1196445024343184",
"created_time": 1688574189
}
}
]
}
],
"object": "page"
}
EOD, true, 512, JSON_OBJECT_AS_ARRAY);
}
class WebhookData implements JsonSerializable {
public array $entry;
public string $object;
public $service;
public function __construct(array $data) {
$this->entry = $data["entry"];
$this->object = $data["object"];
}
public function getEntry() {
return $this->entry[0];
}
public function getMessaging(): array {
if (Arr::has($this->getEntry(), "messaging")) {
return $this->getEntry()["messaging"];
}
return [];
}
protected function getEntryId(): string
{
return $this->getEntry()["id"];
}
protected function getSenderId(): string
{
if ($this->isMessaging()) {
return $this->getMessaging()[0]["sender"]["id"];
}
return "";
}
public function itsMe(): bool
{
return $this->getEntryId() == $this->getSenderId();
}
public function isMessaging(): bool
{
return Arr::has($this->getEntry(), "messaging");
}
protected function getChanges(): array
{
if (!collect($this->getEntry())->has("changes")) {
return [];
}
return $this->getEntry()["changes"];
}
protected function getChangesCollection(): \Illuminate\Support\Collection
{
return collect($this->getChanges());
}
public function isComment(): bool
{
if (Arr::has($this->getEntry(), "changes") && count($this->getChanges()) > 0) {
return $this->isAddingComment();
}
return false;
}
protected function isAddingComment(): bool
{
return ($this->getChanges()[0]["value"]["item"] == "comment"
&& $this->getChanges()[0]["value"]["verb"] == "add");
}
public function toJson(): string {
return collect([
'data' => $this->entry,
'service' => $this->service
])->toJson();
}
public function jsonSerialize(): mixed
{
return $this->toJson();
}
}
class TransformText {
public function __invoke(WebhookData $message, Closure $next)
{
$m = $message->getMessaging();
$m[0]["message"]["text"] = "Outro texto";
return $next($m);
}
}
class ValidateService {
public function __invoke(WebhookData $message, Closure $next)
{
$id = $message->getEntry()["id"];
//$service = Service::where('external_id', $id)->first();
if ($id != "108668968127687") {
return null;
}
$message->service = "XPTO";
return $next($message);
}
}
class ValidateMessage {
public function __invoke(WebhookData $message, Closure $next)
{
if (! $message->isMessaging()) {
return $next($message);
}
if ($message->itsMe()) {
return $next($message);
}
// fazer algo relacionado a mensagem
//event(new (UUUUUU($meesage));
$data = [
"message" => $message,
"service" => $message->service
];
$pipe = Pipeline::send($data)
->through([
function (array $data, Closure $next) {
//dd($data["service"]);
}
])->thenReturn();
// disparar um evento?
// atualizar o model
return $next($message);
}
}
class ValidateComment {
public function __invoke(WebhookData $message, Closure $next)
{
if (! $message->isComment()) {
return $next($message);
}
return $next($message);
}
}
class ValidatePost {
public function __invoke(WebhookData $message, Closure $next)
{
if (! $message->isComment()) {
return $next($message);
}
return $next($message);
}
}
Route::get('/', function () {
$recMsg = (new WebhookData(receiveMessage()));
// return $recMsg->getEntry();
$pipe = Pipeline::send($recMsg)
->through([
ValidateService::class,
ValidateMessage::class,
ValidateComment::class,
ValidatePost::class,
])->thenReturn();
return $pipe;
});
<?php
namespace App\DialogFlow;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
class FacebookComment extends Model
{
use ObjectFactory;
protected $fillable = [
'entry',
'object'
];
public function entries(): Attribute
{
return Attribute::make(
get: fn() => collect($this->entry)
);
}
public function comment(): Attribute
{
return Attribute::make(
get: fn() => $this->convertArrayToObject($this->entries->first())
);
}
public function changes(): Attribute
{
return Attribute::make(
get: fn() => $this->convertArrayToObject($this->comment()->changes)
);
}
}
<?php
namespace App\DialogFlow;
trait ObjectFactory
{
protected function convertArrayToObject(array $data): mixed
{
return json_decode(json_encode($data), false);
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment