Как сформировать вложение для сообщения из локальных файлов или ссылок? · vknet/vk · Discussion #1104 (original) (raw)

Данный способ позволяет прикрепить к сообщению локальный файлы, а также файлы, взятые из интернета, то есть прикрепление файла через ссылку.

Если нужно отправить картинку, то для прикрепления её к сообщению можно использовать следующий метод:

public async void SendMessageWithImage(this VkApi Api) { var userId = 12345678; //Получатель сообщения

// Получить адрес сервера для загрузки картинок в сообщении
var uploadServer = Api.Photo.GetMessagesUploadServer(userId);

// Загрузить картинку на сервер VK.
var response = await UploadFile(uploadServer.UploadUrl, 
    "https://www.gstatic.com/webp/gallery/1.jpg", "jpg");

// Сохранить загруженный файл
var attachment = Api.Photo.SaveMessagesPhoto(response);

//Отправить сообщение с нашим вложением
Api.Messages.Send(new MessagesSendParams
{
    UserId = userId, //Id получателя
    Message = "Message", //Сообщение
    Attachments = attachment, //Вложение
    RandomId = new Random().Next(999999) //Уникальный идентификатор
});

}

Для прикрепления вложения к сообщению аналогичный метод будет выглядеть следующим образом:

public async void SendMessageWithFile(this VkApi Api) { var userId = 12345678; //Получатель сообщения

// Получить адрес сервера для загрузки файлов в сообщении
var uploadServer = Api.Docs.GetMessagesUploadServer(userId);

// Загрузить файл на сервер VK.
var response = await UploadFile(uploadServer.UploadUrl,
    "https://i.gifer.com/D446.gif", "gif");

// Сохранить загруженный файл
var title = "Test Gif"; //Название файла
var attachment = new List<MediaAttachment>
{
    Api.Docs.Save(response, title ?? Guid.NewGuid().ToString())[0].Instance
};

//Отправить сообщение с нашим вложением
Api.Messages.Send(new MessagesSendParams
{
    UserId = userId, //Id получателя
    Message = "Message", //Сообщение
    Attachments = attachment, //Вложение
    RandomId = new Random().Next(999999) //Уникальный идентификатор
});

}

Данный метод является универсальным для любых типов файлов.

Если файл взят из интернета то в метод UploadFile в качестве аргумента file мы передаем ссылку на этот файл.

Если мы загружаем локальный файл, то в аргумент file мы передаем путь к этому файлу.

private async Task UploadFile(string serverUrl, string file, string fileExtension) { // Получение массива байтов из файла var data = GetBytes(file);

// Создание запроса на загрузку файла на сервер
using (var client = new HttpClient())
{
    var requestContent = new MultipartFormDataContent();
    var content = new ByteArrayContent(data);
    content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
    requestContent.Add(content, "file", $"file.{fileExtension}");

    var response = client.PostAsync(serverUrl, requestContent).Result;
    return Encoding.Default.GetString(await response.Content.ReadAsByteArrayAsync());
}

}

В зависимости от того, где мы берем файл: локально или из интернета, есть две реализации метода GetBytes.

Для файла, взятого из интернета, нам достаточно передать ссылку на этот файл в данный метод:

private byte[] GetBytes(string fileUrl) { using (var webClient = new WebClient()) { return webClient.DownloadData(fileUrl); } }

Если мы используем локальный файл, то нужно передать путь к файлу в следующий метод:

private byte[] GetBytes(string filePath) { return File.ReadAllBytes(filePath); }