Граємося з VK API та Python, частина 5: self-delete повідомлення

3 хв. читання

Добридень, пані та панове. Давненько я сюди нічого не писав. Ну що ж, час виправлятися. Як можна здогадатися з назви, ми будемо писати повідомлення, що автоматично видаляться через деякий час. При чому видаляться відразу і у вас, і у співбесідника. Як таке можливо, адже повідомлення видаляються тільки "з однієї сторони"? А це вже я поясню нижче.

Зміст

Ви напевно знаєте, що якщо видалити картинку, що ви відправили в особистих повідомленнях, то вона видаляється і у вашого співбесідника? От від цього і будемо рухатися. Ми напишемо скрипт, що буде розміщувати ваше повідомлення на картинці, відправляти її потрібній людині, а за тім і видаляти її через певний час. Для роботи з зображенням будемо використовувати Pillow, встановити можна pip'ом:

pip install pillow

Відразу попереджу, що мій варіант скрипта досить "спартанський", його можна значно поліпшити.

from PIL import Image, ImageDraw, ImageFont
import vk, json, textwrap, os
from time import sleep
import requests as req

def getUserId(link):
    id = link
    if 'vk.com/' in link:
        id = link.split('/')[-1]
    if not id.replace('id', '').isdigit():
        id = vkapi.utils.resolveScreenName(screen_name=id)['object_id']
    else:
        id = id.replace('id', '')
    return int(id)

vkapi = vk.API(access_token='')
sl = lambda: sleep(0.4) # Тому що писати sleep(0.4) дуже довго
fnt = ImageFont.truetype('courier.ttf', 18) # 18 -- розмір шрифту

read_time = 60 * 1 # Час для читання повідомлення, інакше кажучи
                   # час життя нашої картинки
user_to_send = getUserId(input("Введіть посилання на користувача: "))
text = input("Введіть ваше повідомлення: ")

Як бачите, тут ми імпортували потрібні модулі (так, вийшло чимало, але вони всі потрібні), оголосили службову функцію для перетворення лінка на id і оголосили наші дані. Шрифт потрібно покласти в папку з скриптом. Продовжимо. Перш за все, потрібно згенерувати зображення:

im = Image.new("RGBA", (800, 800), color=(255, 255, 255))
imd = ImageDraw.Draw(im)
text_lines = textwrap.wrap(text, width=72) # розділення тексту на рядки
for i, line in enumerate(text_lines):
    imd.text((0, i*18), line, font=fnt, fill=(0, 0, 0))
del imd
crop_bottom = 18*len(text_lines) if len(text_lines) > 4 else 18*4 # бо вк не любить занадто низькі картинки 
im = im.crop((0, 0, 800, crop_bottom))  # обрізаємо зайве
im.save("output.jpg", "jpeg")

Тут потрібно пояснити, що для того, щоб малювати на зображенні - потрібно створити об'єкт-обгортку. Також скажу, що число 72 - виведене експериментальним шляхом. Можна і в коді знайти, але тоді сильно збільшиться об'єм. Згенероване зображення потрібно завантажити.

# <magic>
photo_server = vkapi.photos.getMessagesUploadServer()
sl()
files = {'photo': open('output.jpg', 'rb')}
data = {k.split('=')[0]: k.split('=')[1] for k in photo_server['upload_url'].split('?')[1].split('&')}
r = req.post(photo_server['upload_url'], data, files=files)
data = json.loads(r.text)
buf = vkapi.photos.saveMessagesPhoto(server=data['server'], photo=data['photo'], hash=data['hash'])[0]
# </magic>
sl()
photo_id = 'photo{}_{}'.format(buf['owner_id'], str(buf['id']))

vkapi.messages.send(user_id=user_to_send, attachment=photo_id)
sleep(read_time)
vkapi.photos.delete(owner_id=buf['owner_id'], photo_id=str(buf['id']))

Напевно, ви хочете спитати, що це за магія з завантаженням? Я не знаю. Ні, серйозно, це мій код, але я не пам'ятаю, як його писав. Головне, що він працює. Потім ми відправляємо повідомлення, чекаємо установлений час і видаляємо фото.

Стаття вийшла доволі маленькою, але, сподіваюсь, вам було цікаво. Сирці доступні на гітхабі.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.8K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація