im having exact same issue on laravel on my server i get the logs, but i also get this error trying to automate a response.
"response":{"error":{"message":"(#3) Application does not have the capability to make this API call.","type":"OAuthException","code":3,"fbtrace_id":"AV3dre69bePSZQP8odKyvhl"}}}
[2025-06-12 21:50:59] local.ERROR: Failed to send Instagram message {"error":"{\"error\":{\"message\":\"(#3) Application does not have the capability to make this API call.\",\"type\":\"OAuthException\",\"code\":3,\"fbtrace_>
public function verifyWebhook(Request $request)
{
$verifyToken = env('IG_VERIFY_TOKEN');
Log::info('incoming instagram webhook', ['payload' => $request->all()]);
$mode = $request->get('hub_mode');
$token = $request->get('hub_verify_token');
$challenge = $request->get('hub_challenge');
if ($mode === 'subscribe' && $token === $verifyToken) {
return response($challenge, 200);
}
}
public function handleWebhook(Request $request)
{
$data = $request->all();
Log::info('handling ig webhook', ['data' => $data]);
if (isset($data['object']) && $data['object'] === 'instagram') {
foreach ($data['entry'] as $entry) {
$instagramId = $entry['id'];
$integration = Integration::where('integration_name', 'instagram')
->where('integration_details->instagram_user_id', $instagramId)
->latest()
->first();
if (!$integration) {
Log::error('No integration found for Instagram ID', [
'instagram_id' => $instagramId,
'integration_details' => $integration->integration_details ?? null
]);
continue;
}
$slug = $integration->integration_details['slug'] ?? null;
$accessToken = $integration->integration_details['page_access_token'] ?? null; //page access token
$igUserId = $integration->integration_details['instagram_user_id'] ?? null;
// Check if the chatbot is allowed to respond on this integration
$chatbotSetting = ChatbotSetting::where('slug', $slug)->first();
if (!$chatbotSetting) {
Log::warning("No chatbot setting found for slug: $slug");
continue;
}
$userDataSettings = $chatbotSetting->chatbotUserDataSetting;
if (!$userDataSettings || !isset($userDataSettings['social_media_integration_ids'])) {
Log::warning("No userDataSettings or social_media_integration_ids for chatbot slug: {$slug}");
continue;
}
// Ensure the IDs are strings for consistent comparison
$allowedIntegrationIdsRaw = $userDataSettings['social_media_integration_ids'];
Log::info("Allowed integration IDs for chatbot slug {$slug}: ", $allowedIntegrationIdsRaw);
$allowedIntegrationIds = is_array($allowedIntegrationIdsRaw)
? array_map('strval', $allowedIntegrationIdsRaw)
: [];
$currentIntegrationId = (string) $integration->id;
if (!in_array($currentIntegrationId, $allowedIntegrationIds)) {
Log::info("Integration ID {$currentIntegrationId} not authorized to respond for chatbot: {$slug}");
continue;
}
Log::info('ing webhook', ['slug' => $slug]);
foreach ($entry['messaging'] as $event) {
if (isset($event['message']) && isset($event['sender']['id'])) {
$senderId = $event['sender']['id'];
$message = $event['message']['text'] ?? '';
$responseText = $this->generateAIResponse($message, $slug);
$this->sendInstagramMessage($senderId, $responseText, $accessToken, $igUserId);
}
}
}
}
return response('EVENT_RECEIVED', 200);
}
private function sendInstagramMessage($recipientId, $messageText, $accessToken, $igUserId)
{
$url = "https://graph.facebook.com/v22.0/{$igUserId}/messages?access_token=" . urlencode($accessToken);
$response = Http::post($url, [
'messaging_type' => 'RESPONSE',
'recipient' => ['id' => $recipientId],
'message' => ['text' => $messageText],
]);
Log::info('Instagram message sent', [
'recipient_id' => $recipientId,
'message_text' => $messageText,
'response' => $response->json()
]);
if (!$response->ok()) {
Log::error('Failed to send Instagram message', [
'error' => $response->body(),
'access_token' => substr($accessToken, 0, 6) . '...',
'ig_user_id' => $igUserId
]);
}
}