如何在使用 laravel/socialite 和 facebook/graph-sdk 时从控制器发送 Facebook 页面 post?
How can I send Facebook page post from controller while using laravel/socialite and facebook/graph-sdk?
我知道对于有经验的 Laravel 开发人员来说,这个问题听起来很愚蠢,但我遵循 this article 实施 Facebook SDK。
我遵循了从在数据库中添加新标记列到实现控制器的所有操作。
这是我的 GraphController.php
文件:
class GraphController extends Controller
{
private $api;
public function __construct(Facebook $fb)
{
$this->middleware(function ($request, $next) use ($fb) {
$fb->setDefaultAccessToken(Auth::user()->token);
$this->api = $fb;
return $next($request);
});
}
public function getPageAccessToken($page_id){
try {
// Get the \Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $this->api->get('/me/accounts', Auth::user()->token);
} catch(FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
try {
$pages = $response->getGraphEdge()->asArray();
foreach ($pages as $key) {
if ($key['id'] == $page_id) {
return $key['access_token'];
}
}
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
public function publishToPage(Request $request, $title){
$page_id = 'XXXXXXXXXXXXX';
try {
$post = $this->api->post('/' . $page_id . '/feed', array('message' => $title), $this->getPageAccessToken($page_id));
$post = $post->getGraphNode()->asArray();
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
}
这是我的 routes/web.php
:
Route::group(['middleware' => [
'auth'
]], function(){
Route::post('/page', 'GraphController@publishToPage');
});
FacebookServiceProvider
:
class FacebookServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
$this->app->singleton(Facebook::class, function ($app) {
$config = config('services.facebook');
return new Facebook([
'app_id' => $config['client_id'],
'app_secret' => $config['client_secret'],
'default_graph_version' => 'v2.6',
]);
});
}
}
现在,我需要在 PostController.php
文件中使用 publishToPage:
public function store(Requests\PostRequest $request)
{
$data = $this->handleRequest($request);
$newPost = $request->user()->posts()->create($data);
$newPost->createTags($data["post_tags"]);
/*
// My other notifications that are working:
// OneSignal
OneSignal::sendNotificationToAll(
"New warning ".$newPost->title
);
// MailChimp
$this->notify($request, $newPost);
// Twitter
$newPost->notify(new ArticlePublished());
*/
// I WOULD NEED SOMETHING IN THIS WAY ALSO FOR FACEBOOK BUT THIS OBVIOUSLY DOESN'T WORK
GraphController::publishToPage($request, $newPost->title);
}
你能从这里建议如何做的好方法吗?
如果您觉得我应该了解 Laravel 的基础知识,我需要再次道歉,但我真的很难理解这一点,您的建议确实可以帮助我更好地理解它。
集成 Twitter、MailChimp、OneSignal 通知真的很容易,但 Facebook 的限制政策让我很困惑。
谢谢你们。非常感谢!
遗憾的是,Facebook 仍然没有获得我自动发布的许可,所以我不能尝试,如果它真的有效。
我想我找到了解决这个特定问题的方法。感谢来自 Laracast 的 Sti3bas。
namespace App\Services;
class FacebookPoster
{
protected $api;
public function __construct(Facebook $fb)
{
$fb->setDefaultAccessToken(Auth::user()->token);
$this->api = $fb;
}
protected function getPageAccessToken($page_id){
try {
// Get the \Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $this->api->get('/me/accounts', Auth::user()->token);
} catch(FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
try {
$pages = $response->getGraphEdge()->asArray();
foreach ($pages as $key) {
if ($key['id'] == $page_id) {
return $key['access_token'];
}
}
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
public function publishToPage($page, $title){
try {
$post = $this->api->post('/' . $page . '/feed', array('message' => $title), $this->getPageAccessToken($page));
$post = $post->getGraphNode()->asArray();
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
}
然后重构控制器:
use App\Services\FacebookPoster;
//...
class GraphController extends Controller
{
public function publishToPage(Request $request, FacebookPoster $facebookPoster)
{
$page_id = 'XXXXXXXXXXXXX';
$title = 'XXXXXXXXXXXXX';
$facebookPoster->publishToPage($page_id, $title);
}
}
use App\Services\FacebookPoster;
//...
public function store(PostRequest $request, FacebookPoster $facebookPoster)
{
$data = $this->handleRequest($request);
$newPost = $request->user()->posts()->create($data);
$newPost->createTags($data["post_tags"]);
//...
$facebookPoster->publishToPage($page, $newPost->title);
}
我知道对于有经验的 Laravel 开发人员来说,这个问题听起来很愚蠢,但我遵循 this article 实施 Facebook SDK。
我遵循了从在数据库中添加新标记列到实现控制器的所有操作。
这是我的 GraphController.php
文件:
class GraphController extends Controller
{
private $api;
public function __construct(Facebook $fb)
{
$this->middleware(function ($request, $next) use ($fb) {
$fb->setDefaultAccessToken(Auth::user()->token);
$this->api = $fb;
return $next($request);
});
}
public function getPageAccessToken($page_id){
try {
// Get the \Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $this->api->get('/me/accounts', Auth::user()->token);
} catch(FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
try {
$pages = $response->getGraphEdge()->asArray();
foreach ($pages as $key) {
if ($key['id'] == $page_id) {
return $key['access_token'];
}
}
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
public function publishToPage(Request $request, $title){
$page_id = 'XXXXXXXXXXXXX';
try {
$post = $this->api->post('/' . $page_id . '/feed', array('message' => $title), $this->getPageAccessToken($page_id));
$post = $post->getGraphNode()->asArray();
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
}
这是我的 routes/web.php
:
Route::group(['middleware' => [
'auth'
]], function(){
Route::post('/page', 'GraphController@publishToPage');
});
FacebookServiceProvider
:
class FacebookServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
$this->app->singleton(Facebook::class, function ($app) {
$config = config('services.facebook');
return new Facebook([
'app_id' => $config['client_id'],
'app_secret' => $config['client_secret'],
'default_graph_version' => 'v2.6',
]);
});
}
}
现在,我需要在 PostController.php
文件中使用 publishToPage:
public function store(Requests\PostRequest $request)
{
$data = $this->handleRequest($request);
$newPost = $request->user()->posts()->create($data);
$newPost->createTags($data["post_tags"]);
/*
// My other notifications that are working:
// OneSignal
OneSignal::sendNotificationToAll(
"New warning ".$newPost->title
);
// MailChimp
$this->notify($request, $newPost);
// Twitter
$newPost->notify(new ArticlePublished());
*/
// I WOULD NEED SOMETHING IN THIS WAY ALSO FOR FACEBOOK BUT THIS OBVIOUSLY DOESN'T WORK
GraphController::publishToPage($request, $newPost->title);
}
你能从这里建议如何做的好方法吗?
如果您觉得我应该了解 Laravel 的基础知识,我需要再次道歉,但我真的很难理解这一点,您的建议确实可以帮助我更好地理解它。
集成 Twitter、MailChimp、OneSignal 通知真的很容易,但 Facebook 的限制政策让我很困惑。
谢谢你们。非常感谢!
遗憾的是,Facebook 仍然没有获得我自动发布的许可,所以我不能尝试,如果它真的有效。
我想我找到了解决这个特定问题的方法。感谢来自 Laracast 的 Sti3bas。
namespace App\Services;
class FacebookPoster
{
protected $api;
public function __construct(Facebook $fb)
{
$fb->setDefaultAccessToken(Auth::user()->token);
$this->api = $fb;
}
protected function getPageAccessToken($page_id){
try {
// Get the \Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $this->api->get('/me/accounts', Auth::user()->token);
} catch(FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
try {
$pages = $response->getGraphEdge()->asArray();
foreach ($pages as $key) {
if ($key['id'] == $page_id) {
return $key['access_token'];
}
}
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
public function publishToPage($page, $title){
try {
$post = $this->api->post('/' . $page . '/feed', array('message' => $title), $this->getPageAccessToken($page));
$post = $post->getGraphNode()->asArray();
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
}
然后重构控制器:
use App\Services\FacebookPoster;
//...
class GraphController extends Controller
{
public function publishToPage(Request $request, FacebookPoster $facebookPoster)
{
$page_id = 'XXXXXXXXXXXXX';
$title = 'XXXXXXXXXXXXX';
$facebookPoster->publishToPage($page_id, $title);
}
}
use App\Services\FacebookPoster;
//...
public function store(PostRequest $request, FacebookPoster $facebookPoster)
{
$data = $this->handleRequest($request);
$newPost = $request->user()->posts()->create($data);
$newPost->createTags($data["post_tags"]);
//...
$facebookPoster->publishToPage($page, $newPost->title);
}