📜 ⬆️ ⬇️

SMS alert for students from the VKontakte page

Hello dear habrovchane!
I would like to tell you about how I made SMS notification for my faculty.
I am studying in the first year of FSFE ITMO . We have a so-called dispatching service at the faculty which is engaged in notifying students about a change in the schedule, on the Internet this is done through a page in contact and twitter.
Once there was a small scandal over the fact that half of the group did not show up for classes because they did not have time to track the change in the schedule. That day I had the idea to create an SMS alert from the very Vk page.
Yes, I know that there are specialized services for this, but it’s too easy ...



Lyrical digression

I am new to Linux, Phython and Sql, and this article is written on the principle of “Learn, Learn, Learn.”
So do not be angry much, if something is wrong, but rather just write down your comments in the comments.

Where to begin?


A little thought, I realized that I needed:

I have a home “server” on Debian which I proudly call GrindelServer, on its basis I was going to implement all this.
It was decided to start with just learning how to send sms from the command line. It so happened that I had about three 3G Huawei E1150 modems lying around, it was decided to use one of them. Google easily found material on this topic. In short, it was necessary to transfer the modem to the “only modem” mode (they still have a fake CD drive and card reader), and then set up the Gnokii or Gammu program to work with it.
I chose Gammu ...

Gammu


I can not say that with Gammu was easy, but in the end everything turned out.
')
Installation in Debian is standard:
$ sudo apt-get install gammu 

I have installed version 1.28.0
Gammu config: / etc / gammurc
A modem is usually defined as / dev / ttyUSB0, ttyUSB1, ttyUSB2. We need ttyUSB0
It is enough to add to the config
 [gammu] port= /dev/ttyUSB0 connection = at 

Connectinon is a connection type.

Everything! after that you can check
 $ sudo gammu --identify 

Must give something like
  : /dev/ttyUSB0 Manufacturer : huawei  : unknown (E1550) Firmware : 11.608.12.00.143 IMEI : 123456789101112  SIM (IMSI) : 123456789098765 

There should be no problems here, but if there are, then there is always $ man gammu and Google.

The first sms from the console

First you need to set the modem use rights, they will be needed only for this example, so do not worry about the fact that they are reset after a reboot.
 $ sudo chmod 777 /dev/ttyUSB0 

Now, if a SIM card is inserted into the modem and there is money on it, you can send SMS
For example:
 $ sudo echo " Grindel" | gammu sendsms TEXT +79811111111 -unicode 


Automate SMS sending

The gammu package in this case was needed only for verification, later I used the gammu-smsd daemon.
He can send sms from the database (you can read more about him on the gammu website, but note that a later version is described there.)
We put:
 $ sudo apt-get install gammu-smsd 

Config / etc / gammu-smsdrc
 [gammu] port = /dev/ttyUSB0 connection = at [smsd] #   service = MYSQL host = localhost logfile = /var/log/gammu-smsd #  user = smsd password = password #    pc = localhost #  database = smsd 

Now you need to create a base.
In $ man gammu-smsd-tables it is said that the necessary database dump is located at docs/sql/mysql.sql as far as I understand it is necessary to search for the source code of the program, so by downloading them (version 1.28.0) you can unpack the archive and find the necessary sql script, and then fill it in any convenient way, for example through phpMyAdmin. (If someone offers a more reasonable method, I will be glad!)

After all these steps, it is worth restarting the daemon.
 $ sudo /etc/init.d/gammu-smsd restart 

ATTENTION! After launching gammu-smsd , gammu --identify will gammu --identify error, this is normal!
Sending SMS via mysql

An example from $ man gammu-smsd-tables , this code can be executed in the same phpMyAdmin
 INSERT INTO outbox ( DestinationNumber, TextDecoded, CreatorID, Coding ) VALUES ( ' ', 'This is a SQL test message', 'Program', 'Default_No_Compression' ); 

The principle is the following

ATTENTION! Only 160 Latin and 70 Cyrillic characters can be sent to SMS! To send more text there are "multipart sms". Gammu-smsd supports sending them, the process is described in $ man gammu-smsd-tables

Writing your program to check the vk page


Honestly, I was completely at a loss, I never wrote such programs, all my programming experience was limited to the school Turbo Pascal and the small js project “Bart Chalkboard Generator” (can be found in my profile).
I did not even know which language to choose. It was decided to ask a question in Q & A.
Thank you very much for the answers g0lden and avalak !
As a result, I chose Python and began to study it at Codecademy . In parallel, I was looking for a way to implement working with the VK API in Python. And I found it on Habré, thanks dzhioev for it! I also slowly began to deal with VK api. Due to my free time I had very little time left and I moved very slowly.

Acquainted with Python more or less (I got to the lists and dictionaries on Codecademy), I decided that I was ready to start writing my own script.

I started by registering a VKontakte page on whose behalf the application will act, then I had to register my application. It is quite simple and described in the documentation of VKontakte, so I will not write about it.

Parsing script

In brief, the sequence of script actions is as follows:

It is necessary to explain about the database. I added the VkPosts and Groups tables to the smsd database. In VkPosts, the id of all posts sent by the program are added, so the next time you can request the id of the last post sent, respectively the latest one. And in groups there are student numbers and group numbers: group | number.

Now the script itself in pieces

We connect the necessary modules
 import vk_auth import json import urllib2 from urllib import urlencode import MySQLdb import logging import time import re 


We initialize the connection with the base, and set the encoding, so that there would be no cracks
 db = MySQLdb.connect(host="localhost", user="  ", passwd="", db="smsd") cursor = db.cursor() db.set_character_set('utf8') cursor.execute('SET NAMES utf8;') cursor.execute('SET CHARACTER SET utf8;') cursor.execute('SET character_set_connection=utf8;') 


We inform vk api login, password, application number and the requested privileges using the auth function from the vk_auth module, I remind the module is taken from here .
 token, user_id = vk_auth.auth(login, password, "3139526", "groups,wall") 

We get the application token in the token variable and in the user_id ID of the user whose data was entered.

Further we define some more variables.
 cursor.execute("SELECT postID FROM VKposts ORDER BY VKposts.number DESC LIMIT 0 , 1;") # id    lastSendedPostId = cursor.fetchall()[0][0] #   LastSendedPostId    groupId = -123456 # Id ,  id        vkapi    id   cursor.execute("SELECT DISTINCT `group` FROM `groups`") #    rawGroups = cursor.fetchall() groups = [] for rawGroup in rawGroups: groups.append(rawGroup[0]) 


Main part of the program
 post = call_api("wall.get", [("owner_id", groupId), ("count", "1")], token)[1] #      if post['id'] > lastSendedPostId and post['date'] > actualTime: # Id      Id  ,      ,       logging.info('I have found some new posts!') i = 0 while post['id'] > lastSendedPostId and post['date'] > actualTime: #      if not len(post) > 1: #         break post['text'] = post['text'].replace('<br>', ' ') #         for group in groups: #     if len(re.findall("(^| )" + str(group) + "( |$)", post['text'])) != 0: #           "(^| )" +   + "( |$)" logging.info("I have found %s group in %s post" % (group, post['id'])) cursor.execute("SELECT `tel` FROM `groups`WHERE `group`=%s;" % (group)) #      rawTels = cursor.fetchall() tels = [] for rawTel in rawTels: tels.append(rawTel[0]) for tel in tels: #    if len(post['text']) > 70: #     70         cursor.execute("INSERT INTO outbox(DestinationNumber, Coding, TextDecoded, CreatorID, Class)VALUES ('%s', 'Unicode_No_Compression', '    vk.com/wall%s_%s', 'Python', '-1')" % (tel, groupId, post['id'])) sendedPosts.insert(0, post['id']) # Id    logging.info("Send Cuted %s post to %s****" % (post['id'], tel[0:8])) else: #        cursor.execute("INSERT INTO outbox(DestinationNumber, Coding, TextDecoded, CreatorID, Class)VALUES ('%s', 'Unicode_No_Compression', '%s', 'Python', '-1')" % (tel, post['text'])) sendedPosts.insert(0, post['id']) # Id    logging.info("Send %s post to %s****" % (post['id'], tel[0:8])) i += 1 post = call_api("wall.get", [("owner_id", groupId), ("offset", i), ("count", "1")], token)[1] #   

There is a small snag. If the text of the post is more than 70 characters, I send instead of it - “Your schedule has changed” + link to the post, I do it because more than 70 characters will not fit into one Cyrillic SMS (it was said above), but I haven’t figured out multipart sms yet .
logging.info is a function of the logging function configured at the beginning of the code:
 logging.basicConfig(format='%(asctime)s | %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', filename='/home/NetDisk/sms/smslog.log',level=logging.DEBUG) 

That's all! It remains to make the script executable
 $ sudo chmod +x    

And add it to Cron with the required interval.
But the possibilities of gammu and all of the above listed do not end there, and yours, I am sure, too. So fantasize.

In the plans




Sources




PS


I was very interested in doing all these things, I was completely taken aback by this idea, I was happy to have the opportunity to do all this and study, even if it was not always easy (sometimes I wanted to give up everything).
Thanks for reading, I hope you enjoyed it!
Good luck with your ideas!

The source can be found here .

Source: https://habr.com/ru/post/153893/


All Articles