Automated posting on Vkontakte public pages using VK API and Python

Vk.com (Vkontakte) is the most popular social network Russia and Ex-USSR with 430+ million users. Traditional advantages of vk.com – huge amount of free music and video. The service allows users to upload and share files and for a long time was quite tolerant to piracy. In 2016 Mail.Ru Group, Vkontakte parent company, has solved all problems with major music labels and  now works closely with the rights holders.

VKontakte has very efficient features for creating communities: public pages (blogs) and groups (open and closed web-forums). In VK communities you can easily share news, photo, audio, video, text files in different formats, create discussions topics and wiki-pages. When I was studying at the University in 2003-2009, to share information in a study group we needed to create our own website and phpBB-based forum. Now practically all students simply use VKontakte groups for this. VKontakte shows all content in groups as is, without hiding and filtering.

With reach automation capabilities, you can do various interesting things based on VK. For a start, I decided to post all annotations from my https://avleonov.com blog to https://vk.com/avleonovcom Vkontakte page. I created this page in web GUI and filled it with content automatically using my own python scripts.

Creating a new application

I want to work with Vkontakte from my Python scripts. So, I will need to create a new Standalone Application for this. You can do it here: https://vk.com/editapp?act=create

vk new application

Upd. March 2018 Integration with Vkontakte suddenly broke, because they added mandatory version parameter to all calls.

Getting sms code for confirmation. And now I have a new application:

vk application settings

I changed status to “Application on and visible to all”.

Getting page info

Now let’s try to do something. All available methods are listed at https://vk.com/dev/methods

For most of the methods token authentication required. For example, using community token, you can do some operations on your page. Let’s get it. I go to the page https://vk.com/avleonovcom?act=tokens

Create token

Select required rights for a new access token:

  • Allow the application to control the community
  • Allow access to community messages
  • Allow access to community photos
  • Allow access to community documents

Getting sms code for confirmation. And now I have a token:

vk new token created

Now let’s get information about the group:

#!/usr/bin/python

import 

community_token = "3bXXXXXXXXXXXXXXXXa3"

params = (
    ('group_id', 'avleonovcom'),
    ('access_token', community_token),
)

response = requests.get('https://api.vk.com/method/groups.getById', params=params)

print(response.text)

Response in Json:

{“response”:[{“gid”:149273431,”name”:”Alexander Leonov”,”screen_name”:”avleonovcom”,”is_closed”:0,”type”:”page”,”is_admin”:1,”admin_level”:3,”is_member”:1,”photo”:”https:\/\/pp.userapi.com\/c638021\/v638021099\/5ebf2\/CMFlIiN7BRQ.jpg”,”photo_medium”:”https:\/\/pp.userapi.com\/c638021\/v638021099\/5ebf1\/ObJxr2sBTKg.jpg”,”photo_big”:”https:\/\/pp.userapi.com\/c638021\/v638021099\/5ebf0\/KQfDrQHHc4o.jpg”}]}

Creating a post

Ok, now let’s see how to post something on a community wall https://vk.com/dev/wall.post

For this I need user token. I will try “Implicit Flow” for User Access Token.

I simply open this url in browser:

https://oauth.vk.com/authorize?client_id=6096665&display=page&redirect_uri=https://oauth.vk.com/blank.html&scope=offline,photos,wall,groups&response_type=token&v=5.65

vk posting access

And when I press “Allow” I will be redirected to:

https://oauth.vk.com/blank.html#access_token=bd9487fcd4bd6de7e43aqjfo2n3tjdfi3323b6327b1128987c834ab0b13d8a2fbe1fedc0119bcb4762d2a49&expires_in=0&user_id=1468099

And now can use this token.

Note! “-” in owner_id. It’s important!

user_token = "bdXXXXXXXXXXXXXXXX49"

params = (
    ('owner_id', '-149273431'),
    ('from_group', '1'),  
    ('message', 'Hello world!'),   
    ('access_token', user_token),     
)

response = requests.get('https://api.vk.com/method/wall.post', params=params)

print(response.text)

{“response”:{“post_id”:3}}

vk post hello world

First automatically posted message! Great!

Ok, now let’s try to post url with some text and photo

params = (
    ('owner_id', '-149273431'),
    ('from_group', '1'),  
    ('message', 'Hello world2!'),   
    ('message', 'photo1468099_456239095,https://avleonov.com'),
    ('access_token', user_token),     
)

response = requests.get('https://api.vk.com/method/wall.post', params=params)

print(response.text)

{“response”:{“post_id”:6}}

vk post hello world 2

All necessary elements are here: multiline, hashtags, urls and pictures. It’s a pitty that I can’t specify image for any url, like I can do it in GUI. 🙁

As you see, I have used picture ID photo1468099_456239095 from my personal page. So, let’s also see how to add pictures to the community page.

Creating a new photo album

First of all, I need a photo album at my page. I can create it manually or use this method https://vk.com/dev/photos.createAlbum

params = (
    ('group_id', '149273431'),
    ('title', 'blog illustrations'),  
    ('description', 'images from avleonov.com'),   
    ('upload_by_admins_only', '0'),
    ('comments_disabled', '0'),
    ('access_token', user_token),     
)

response = requests.get('https://api.vk.com/method/photos.createAlbum', params=params)

print(response.text)

{“response”:{“aid”:245830662,”thumb_id”:0,”owner_id”:-149273431,”title”:”blog illustrations”,”description”:”images from avleonov.com”,”created”:1499006969,”updated”:1499006969,”privacy”:null,”comment_privacy”:null,”size”:0,”can_upload”:1}}

Ok, here is my new album:

https://vk.com/album-149273431_245830662

Now let’s add images to this album.

Uploading images

First of all, I need to ask Vk what server I can use for uploading images in particular community and album:  https://vk.com/dev/photos.getUploadServer

params = (
    ('group_id', '149273431'),
    ('album_id', '245830662'),  
    ('access_token', user_token),     
)

response = requests.get('https://api.vk.com/method/photos.getUploadServer', params=params)

print(response.text)

{“response”:{“upload_url”:”https:\/\/pu.vk.com\/c638625\/upload.php?act=do_add&mid=1468099&aid=245830662&gid=149273431&hash=376ebed109e24233586f11bb245567af&rhash=d97ac3f9662006c9cdeaf1bcfc5ee763&swfupload=1&api=1“,”aid”:245830662,”mid”:1468099}}

Getting url from this json:

import json
upload_server = json.loads(response.text)['response']['upload_url']
print(upload_server)

https://pu.vk.com/c638625/upload.php?act=do_add&mid=1468099&aid=245830662&gid=149273431&hash=376ebed109e24233586f11bb245567af&rhash=d97ac3f9662006c9cdeaf1bcfc5ee763&swfupload=1&api=1

Now I can upload image file petya.png to the server using this url

files = {'file1': open('petya.png','rb')}

response = requests.post(upload_server, files=files)

print(response.text)

{“server”:638625,”photos_list”:”[{\”photo\”:\”ae058e4488:z\”,\”sizes\”:[[\”s\”,\”638625099\”,\”46dfc\”,\”kq-CLsvmn1c\”,75,47],[\”m\”,\”638625099\”,\”46dfd\”,\”ARweXs4fNY4\”,130,81],[\”x\”,\”638625099\”,\”46dfe\”,\”azuLkrnJlEM\”,604,377],[\”y\”,\”638625099\”,\”46dff\”,\”Hhh9ZDOIG7A\”,807,504],[\”z\”,\”638625099\”,\”46e00\”,\”-oRXtMm8KoI\”,820,512],[\”o\”,\”638625099\”,\”46e01\”,\”BIuUvHI-jO4\”,130,87],[\”p\”,\”638625099\”,\”46e02\”,\”rvBynPb3ySs\”,200,133],[\”q\”,\”638625099\”,\”46e03\”,\”7co0uaiSnW4\”,320,213],[\”r\”,\”638625099\”,\”46e04\”,\”J3K4uca6G1E\”,510,340]],\”kid\”:\”646c7ed0cdac2164775b2ad14cd2b45b\”,\”debug\”:\”xszmzxzyzzzozpzqzrz\”}]“,”aid”:245830662,”hash”:”10e1442918ecfd9061e375a3db9fa545“,”gid”:149273431}

Getting necessary parameters:

img_hash = json.loads(response.text)['hash']
photos_list = json.loads(response.text)['photos_list']
server = json.loads(response.text)['server']

And finally save uploaded file to the photo album: https://vk.com/dev/photos.save

params = (
    ('group_id', '149273431'),
    ('album_id', '245830662'),  
    ('hash', img_hash),
    ('photos_list', photos_list),    
    ('server', server),
    ('caption', 'test image'),    
    ('access_token', user_token),
)

response = requests.get('https://api.vk.com/method/photos.save', params=params)
print(response.text)

{“response”:[{“pid”:456239022,”id”:”photo1468099_456239022“,”aid”:245830662,”owner_id”:-149273431,”user_id”:1468099,”src”:”https:\/\/pp.userapi.com\/c638625\/v638625099\/46efe\/climLuu7McI.jpg”,”src_big”:”https:\/\/pp.userapi.com\/c638625\/v638625099\/46eff\/9rAsDsEmiUg.jpg”,”src_small”:”https:\/\/pp.userapi.com\/c638625\/v638625099\/46efd\/mmeTVQjTAcE.jpg”,”src_xbig”:”https:\/\/pp.userapi.com\/c638625\/v638625099\/46f00\/vm8tYL62cTA.jpg”,”src_xxbig”:”https:\/\/pp.userapi.com\/c638625\/v638625099\/46f01\/RybUx0jlBX8.jpg”,”width”:820,”height”:512,”text”:”test image”,”created”:1499021877}]}

vk new illustration

Note! The server returns the ID photo1468099_456239022. This is my user ID. And the page ID is 149273431. I do not know why this ID is returned. So, I edit id with this substitution:

photo_id = re.sub("photo1468099", "photo-149273431",  photo_id) 

And it works!

So, now we can add pictures to community photo album. We can make a post from the image identifier, text description and the web-link. This is enough to make a successful integration of your site with your Vkontakte page. 😉

Note! There is a limit, you can create no more than 50 posts per day on the wall!

4 thoughts on “Automated posting on Vkontakte public pages using VK API and Python

  1. alebalweb

    Sorry, I try to post on my community wall. I put the “-” before my user_id and add the “from_group=1”, but I keep posting in my profile wall… What am I wrong? I use php curl.

    Reply
    1. Alexander Leonov Post author

      I also have problems with VK API and my old posting scripts don’t work any more. It seems that some new VK API restriction were implemented. And, honestly, I am not very interested in figuring out what happened. 🙂

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.