add_vk_module
This commit is contained in:
@@ -36,6 +36,15 @@ class VkAlbumService
|
||||
);
|
||||
}
|
||||
|
||||
public function getServerForUploadImagesOnWall($group_id)
|
||||
{
|
||||
return $this->vk->photos()->getWallUploadServer(
|
||||
$this->vkAuthService->getToken()->access_token,
|
||||
array(
|
||||
'group_id' => $group_id,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function uploadImagesToUploadServer($uploadUrl, $images)
|
||||
@@ -83,8 +92,6 @@ class VkAlbumService
|
||||
// Обработка ответа
|
||||
$responseData = json_decode($response, true);
|
||||
|
||||
|
||||
|
||||
// Удаление временных файлов
|
||||
foreach ($localFiles as $localFile) {
|
||||
unlink($localFile);
|
||||
@@ -167,5 +174,4 @@ class VkAlbumService
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,28 +33,51 @@ class VkAuthService
|
||||
}
|
||||
}
|
||||
|
||||
// public function redirectToProvider()
|
||||
// {
|
||||
// $state = bin2hex(random_bytes(16)); // Генерация случайной строки состояния
|
||||
// session(['vk_state' => $state]); //
|
||||
//
|
||||
// $code_verifier = $this->generateCodeVerifier();
|
||||
// $code_challenge = $this->generateCodeChallenge($code_verifier);
|
||||
//
|
||||
// session(['vk_code_verifier' => $code_verifier]);
|
||||
//
|
||||
//
|
||||
// $url = 'https://id.vk.com/authorize?' . http_build_query([
|
||||
// 'response_type' => 'code',
|
||||
// 'client_id' => env('VK_APP_ID'),
|
||||
// 'redirect_uri' => env('VK_REDIRECT_URI'),
|
||||
// 'state' => $state,
|
||||
// 'scope' => 'photos wall video docs',
|
||||
// 'code_challenge' => $code_challenge,
|
||||
// 'code_challenge_method' => 's256',
|
||||
// ]);
|
||||
//
|
||||
// return redirect($url);
|
||||
// }
|
||||
|
||||
public function redirectToProvider()
|
||||
{
|
||||
$state = bin2hex(random_bytes(16)); // Генерация случайной строки состояния
|
||||
session(['vk_state' => $state]);
|
||||
$state = bin2hex(random_bytes(16)); // Генерирует случайную строку состояния (state) для защиты от CSRF-атак.
|
||||
session(['vk_state' => $state]); // Сохраняет строку состояния в сессии под ключом 'vk_state'.
|
||||
|
||||
$code_verifier = $this->generateCodeVerifier();
|
||||
$code_challenge = $this->generateCodeChallenge($code_verifier);
|
||||
$code_verifier = $this->generateCodeVerifier(); // Создает случайную строку code_verifier для протокола PKCE.
|
||||
$code_challenge = $this->generateCodeChallenge($code_verifier); // Генерирует code_challenge на основе code_verifier (обычно хеш SHA-256).
|
||||
|
||||
session(['vk_code_verifier' => $code_verifier]);
|
||||
session(['vk_code_verifier' => $code_verifier]); // Сохраняет code_verifier в сессии под ключом 'vk_code_verifier'.
|
||||
|
||||
|
||||
$url = 'https://id.vk.com/authorize?' . http_build_query([
|
||||
'response_type' => 'code',
|
||||
'client_id' => env('VK_APP_ID'),
|
||||
'redirect_uri' => env('VK_REDIRECT_URI'),
|
||||
'state' => $state,
|
||||
'scope' => 'photos wall', // Укажите необходимые права доступа
|
||||
'code_challenge' => $code_challenge, // Добавьте код, если используете PKCE
|
||||
'code_challenge_method' => 's256',
|
||||
$url = 'https://id.vk.com/authorize?' . http_build_query([ // Формирует URL для перенаправления на страницу авторизации VK ID с параметрами:
|
||||
'response_type' => 'code', // Указывает, что нужен код авторизации.
|
||||
'client_id' => env('VK_APP_ID'), // ID приложения VK из переменных окружения.
|
||||
'redirect_uri' => env('VK_REDIRECT_URI'), // URI для перенаправления после авторизации.
|
||||
'state' => $state, // Передает строку состояния для проверки.
|
||||
'scope' => 'photos wall video docs', // Запрашивает доступ к фото, стене, видео и документам.
|
||||
'code_challenge' => $code_challenge, // Передает code_challenge для PKCE.
|
||||
'code_challenge_method' => 's256', // Указывает метод генерации code_challenge (SHA-256).
|
||||
]);
|
||||
|
||||
return redirect($url);
|
||||
return redirect($url); // Перенаправляет пользователя на сформированный URL для авторизации.
|
||||
}
|
||||
|
||||
public function handleProviderCallback(Request $request)
|
||||
@@ -97,7 +120,7 @@ class VkAuthService
|
||||
'client_id' => env('VK_APP_ID'),
|
||||
'device_id' => $request->device_id,
|
||||
'state' => $request->state,
|
||||
'scope' => 'photos wall',
|
||||
'scope' => 'photos wall video docs',
|
||||
])->object();
|
||||
}
|
||||
|
||||
@@ -109,7 +132,7 @@ class VkAuthService
|
||||
'client_id' => env('VK_APP_ID'),
|
||||
'device_id' => $device_id,
|
||||
'state' => $state,
|
||||
'scope' => 'photos wall',
|
||||
'scope' => 'photos wall video docs',
|
||||
]);
|
||||
|
||||
if ($response->failed()) {
|
||||
|
||||
@@ -4,6 +4,10 @@ namespace App\Services\VK;
|
||||
|
||||
use App\Services\VK\Album\VkAlbumService;
|
||||
use App\Services\VK\Wall\VkWallService;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use VK\Client\VKApiClient;
|
||||
|
||||
class VkService
|
||||
@@ -16,6 +20,7 @@ class VkService
|
||||
$this->wallService = new VkWallService($vk);
|
||||
$this->albumService = new VkAlbumService($vk);
|
||||
$this->public_id = env('PUBLIC_ID');
|
||||
$this->vkAuthService = new VkAuthService();
|
||||
}
|
||||
|
||||
public function getPosts(int $count = 10)
|
||||
@@ -28,16 +33,50 @@ class VkService
|
||||
return $this->wallService->getPostById($id);
|
||||
}
|
||||
|
||||
public function createPost(string $title, string $message, array $images = [], int|null $publish_date = null)
|
||||
// public function createPost(string $title, string $message, array $images = [], array $videos = [], int|null $publish_date = null)
|
||||
// {
|
||||
// $from_group = 1;
|
||||
// $attachments = [];
|
||||
//
|
||||
// if (!empty($images)) {
|
||||
// if (count($images) <= 10) {
|
||||
// $attachments[] = $this->prepareWallPhotos($images);
|
||||
// }
|
||||
// else{
|
||||
// $album = $this->createAlbum($title, $images);
|
||||
// $attachments[] = $this->createAlbumAttachmentParam($album['id']);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// $attachmentString = implode(',', $attachments);
|
||||
//
|
||||
// return $this->wallService->createPost($message, $from_group, $attachmentString, $publish_date);
|
||||
// }
|
||||
|
||||
public function createPost(string $title, string $message, array $images = [], array $videos = [], int|null $publish_date = null)
|
||||
{
|
||||
$from_group = 1;
|
||||
$album_attachment = '';
|
||||
if ($images !== []) {
|
||||
$album = $this->createAlbum($title, $images);
|
||||
$album_attachment = $this->createAlbumAttachmentParam($album['id']);
|
||||
$attachments = [];
|
||||
|
||||
if (!empty($images)) {
|
||||
if (count($images) <= 10) {
|
||||
$attachments[] = $this->prepareWallPhotos($images);
|
||||
} else {
|
||||
$attachments[] = $this->prepareWallPhotos(array_slice($images, 0, 10));
|
||||
|
||||
$album = $this->createAlbum($title, $images);
|
||||
if (isset($album['id'])) {
|
||||
$albumLink = "https://vk.com/album-{$this->public_id}_{$album['id']}";
|
||||
$message .= "\n[{$albumLink}|Ссылка на все фотографии]";
|
||||
} else {
|
||||
Log::error('Не удалось создать альбом');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->wallService->createPost($message, $from_group, $album_attachment, $publish_date);
|
||||
$attachmentString = implode(',', $attachments);
|
||||
|
||||
return $this->wallService->createPost($message, $from_group, $attachmentString, $publish_date);
|
||||
}
|
||||
|
||||
public function updatePost(int $id, string $title, string $message, array $images = [], int|null $publish_date = null)
|
||||
@@ -59,6 +98,13 @@ class VkService
|
||||
return $this->wallService->updatePost($id, $message, $from_group, $album_attachment, $publish_date);
|
||||
}
|
||||
|
||||
public function deletePost(int $post_id){
|
||||
$postRelation = DB::table('posts_vk_posts')->select()->where('post_id', $post_id)->first();
|
||||
$post_id = $postRelation->vk_post_id;
|
||||
$vk_post = $this->getPostById($post_id);
|
||||
$this->wallService->deletePost($vk_post['id']);
|
||||
}
|
||||
|
||||
public function createAlbum(string $title, $images)
|
||||
{
|
||||
$album = $this->albumService->createAlbum($title);
|
||||
@@ -89,4 +135,129 @@ class VkService
|
||||
return (isset($filteredAttachment[0]) ? $filteredAttachment[0] : null);
|
||||
}
|
||||
|
||||
private function prepareWallPhotos(array $images){
|
||||
$baseUrl = config('app.url');
|
||||
try {
|
||||
$imagePaths = array_map(function($img) use ($baseUrl) {
|
||||
return $baseUrl . $img;
|
||||
}, $images);
|
||||
|
||||
$photos = $this->uploadWallPhotos($imagePaths, env('PUBLIC_ID'));
|
||||
|
||||
return implode(',', array_map(function($photo) {
|
||||
return "photo{$photo['owner_id']}_{$photo['id']}";
|
||||
}, $photos));
|
||||
} catch (Exception $e) {
|
||||
Log::error("Ошибка: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function prepareVideos(array $videos)
|
||||
{
|
||||
$baseUrl = config('app.url');
|
||||
$videoPaths = array_map(function($vid) use ($baseUrl) {
|
||||
return $baseUrl . $vid;
|
||||
}, $videos);
|
||||
return $this->uploadVideos($videoPaths, env('PUBLIC_ID')); // Возвращает массив, например: ['video123_456', 'video789_012']
|
||||
}
|
||||
|
||||
private function uploadVideos(array $videoPaths, ?int $groupId = null): array
|
||||
{
|
||||
$uploadedVideos = [];
|
||||
|
||||
foreach ($videoPaths as $videoPath) {
|
||||
try {
|
||||
// Шаг 1: Получение сервера для загрузки
|
||||
$saveResponse = Http::get('https://api.vk.com/method/video.save', [
|
||||
'group_id' => $groupId,
|
||||
'access_token' => $this->vkAuthService->getToken()->access_token,
|
||||
'v' => '5.131',
|
||||
]);
|
||||
|
||||
$saveData = $saveResponse->json();
|
||||
if (!isset($saveData['response']['upload_url'])) {
|
||||
throw new Exception('Не удалось получить сервер для загрузки видео: ' . $videoPath);
|
||||
}
|
||||
$uploadUrl = $saveData['response']['upload_url'];
|
||||
|
||||
// Шаг 2: Загрузка видео на сервер
|
||||
$uploadResponse = Http::attach(
|
||||
'video_file',
|
||||
file_get_contents($videoPath),
|
||||
basename($videoPath)
|
||||
)->post($uploadUrl);
|
||||
|
||||
$uploadData = $uploadResponse->json();
|
||||
if (!isset($uploadData['video_id']) || !isset($uploadData['owner_id'])) {
|
||||
throw new Exception('Не удалось загрузить видео: ' . $videoPath);
|
||||
}
|
||||
|
||||
|
||||
$attachment = "video{$uploadData['owner_id']}_{$uploadData['video_id']}";
|
||||
$uploadedVideos[] = $attachment;
|
||||
} catch (Exception $e) {
|
||||
Log::error("Ошибка при загрузке видео {$videoPath}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $uploadedVideos;
|
||||
}
|
||||
|
||||
private function uploadWallPhotos(array $imagePaths, ?int $groupId = null): array
|
||||
{
|
||||
$uploadedPhotos = [];
|
||||
|
||||
foreach ($imagePaths as $imagePath) {
|
||||
try {
|
||||
$uploadServerResponse = Http::get('https://api.vk.com/method/photos.getWallUploadServer', [
|
||||
'group_id' => $groupId,
|
||||
'access_token' => $this->vkAuthService->getToken()->access_token,
|
||||
'v' => '5.131',
|
||||
]);
|
||||
|
||||
$uploadServerData = $uploadServerResponse->json();
|
||||
if (!isset($uploadServerData['response']['upload_url'])) {
|
||||
throw new Exception('Не удалось получить сервер для загрузки для изображения: ' . $imagePath);
|
||||
}
|
||||
$uploadUrl = $uploadServerData['response']['upload_url'];
|
||||
|
||||
// Шаг 2: Загрузка фотографии на сервер
|
||||
$uploadResponse = Http::attach(
|
||||
'photo',
|
||||
file_get_contents($imagePath),
|
||||
basename($imagePath)
|
||||
)->post($uploadUrl);
|
||||
|
||||
$uploadData = $uploadResponse->json();
|
||||
if (!isset($uploadData['photo']) || !isset($uploadData['server']) || !isset($uploadData['hash'])) {
|
||||
throw new Exception('Не удалось загрузить фотографию: ' . $imagePath);
|
||||
}
|
||||
|
||||
// Шаг 3: Сохранение фотографии
|
||||
$saveResponse = Http::get('https://api.vk.com/method/photos.saveWallPhoto', [
|
||||
'group_id' => $groupId,
|
||||
'photo' => $uploadData['photo'],
|
||||
'server' => $uploadData['server'],
|
||||
'hash' => $uploadData['hash'],
|
||||
'access_token' => $this->vkAuthService->getToken()->access_token,
|
||||
'v' => '5.131',
|
||||
]);
|
||||
|
||||
$saveData = $saveResponse->json();
|
||||
if (!isset($saveData['response'][0])) {
|
||||
throw new Exception('Не удалось сохранить фотографию: ' . $imagePath);
|
||||
}
|
||||
|
||||
// Добавляем данные о загруженной фотографии в массив
|
||||
$uploadedPhotos[] = $saveData['response'][0];
|
||||
Log::info("Фотография успешно загружена. ID: " . $saveData['response'][0]['id']);
|
||||
} catch (Exception $e) {
|
||||
// Логируем ошибку, но продолжаем загрузку остальных изображений
|
||||
Log::error("Ошибка при загрузке изображения {$imagePath}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $uploadedPhotos; // Возвращаем массив с данными о загруженных фотографиях
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@ use VK\Client\VKApiClient;
|
||||
class VkWallService
|
||||
{
|
||||
private VKApiClient $vk;
|
||||
private VkAuthService $vkAuthService;
|
||||
private string $wallToken;
|
||||
private string $serviceToken;
|
||||
private string $publicId;
|
||||
@@ -24,7 +25,6 @@ class VkWallService
|
||||
$this->publicId = env('PUBLIC_ID');
|
||||
$this->publicDomain = env('PUBLIC_DOMAIN');
|
||||
$this->vkAuthService = new VkAuthService();
|
||||
|
||||
}
|
||||
|
||||
public function getPosts(int $count)
|
||||
@@ -38,22 +38,25 @@ class VkWallService
|
||||
|
||||
public function getPostById(int $id)
|
||||
{
|
||||
$post = $this->vk->wall()->getById($this->serviceToken, array(
|
||||
'posts' => '-'. $this->publicId . '_' . $id,
|
||||
));
|
||||
return $post[0];
|
||||
try {
|
||||
$post = $this->vk->wall()->getById($this->vkAuthService->getToken()->access_token, array(
|
||||
'posts' => '-'. $this->publicId . '_' . $id,
|
||||
));
|
||||
return $post[0];
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Ошибка при попытке получения айди ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function createPost(string $message, int $from_group, string $attachments = '', int|null $publish_date = null)
|
||||
{
|
||||
$token = $this->vkAuthService->getToken()->access_token;
|
||||
$params = [
|
||||
'owner_id' => '-' . $this->publicId,
|
||||
'from_group' => $from_group,
|
||||
'message' => $message,
|
||||
'attachments' => $attachments,
|
||||
'access_token' => $this->wallToken,
|
||||
'access_token' => $token,
|
||||
'publish_date' => $publish_date,
|
||||
'v' => '5.131',
|
||||
];
|
||||
@@ -88,7 +91,6 @@ class VkWallService
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
return $this->vk->wall()->edit(
|
||||
$this->vkAuthService->getToken()->access_token,
|
||||
@@ -108,6 +110,36 @@ class VkWallService
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function deletePost(int $post_id)
|
||||
{
|
||||
$token = $this->vkAuthService->getToken()->access_token;
|
||||
$params = [
|
||||
'owner_id' => '-' . $this->publicId,
|
||||
'post_id' => $post_id,
|
||||
'access_token' => $token,
|
||||
'v' => '5.131',
|
||||
];
|
||||
|
||||
try {
|
||||
$response = Http::asForm()->post('https://api.vk.com/method/wall.delete', $params);
|
||||
|
||||
if ($response->successful() && isset($response['response']) && $response['response'] == 1) {
|
||||
return [
|
||||
'success' => true,
|
||||
];
|
||||
} else {
|
||||
throw new \Exception('Ошибка API: ' . json_encode($response->json()));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Ошибка при удалении поста: ' . $e->getMessage());
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Не удалось удалить пост: ' . $e->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function generateAttachmentsParams(string $attachmentType, int $attachmentId)
|
||||
{
|
||||
$pubic_id = env('PUBLIC_ID');
|
||||
@@ -117,6 +149,9 @@ class VkWallService
|
||||
}
|
||||
case 'doc': {
|
||||
|
||||
}
|
||||
case 'photo': {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user