Using twitter can sometimes feel like driving downtown, screaming what you want to say out the window, and hoping someone hears you. There might be tens of thousands of people downtown, but your message will only be heard by a few. Because of this, your best bet is to repeat your message as often as possible.
Twitter is free and if you want to reach as many people as possible, it’s another great tool for getting your message out there. But sending tweets on a scheduled basis can be a pain. There are client programs available which allow you to schedule your tweets (Hootsuite is one I have used in the past). You can load your tweets in the morning, and have the application tweet for you all day long. But you still have to load the application with your tweets—one by one.
A friend of mine asked me if there was a way to send the same 200 tweets over and over again, spaced out every 20 minutes or so. He has a consulting business, and just wants to build up a list of twitter followers by tweeting inspirational quotes. If he tweets for twenty hours a day, and sends three quotes an hour, it will take him a little more than three days to burn through his 200 quotes. And he can always add more quotes or space out the tweets as necessary. I decided to write a Perl script to do this for him.
To start, we will need a MySQL database to store the tweets. I use the MySQL Workbench product as my client application for connecting to MySQL. From within Workbench, I can create my tweet database:
1 |
CREATE DATABASE 'tweets' /*!40100 DEFAULT CHARACTER SET latin1 */ |
I will then need a table inside my database to store my tweets.
1
2
3
4
5
6
7
8
|
CREATE TABLE 'tweets' ( 'id' int(11) NOT NULL AUTO_INCREMENT, 'tweet' char(140) DEFAULT NULL, 'last_tweet_date' datetime NOT NULL DEFAULT '2015-01-01 00:00:00', 'tweet_count' int(5) DEFAULT NULL, 'tweet_length' int(3) DEFAULT NULL, PRIMARY KEY ('id') ) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=latin1 |
The tweet messages will be stored in the tweet column, and the last date the tweet was sent will have a time stamp in the last_tweet_date column. When we perform a search to find the next tweet, we will simply sort our search by the last_tweet_date and then id, and limit our output to one tweet. After we send the tweet, we will update the last_tweet_date column and send that tweet to the end of the line. The script will also incrementally change the tweet_count value (number of times the tweet has been sent), and record the length of the tweet in tweet_length. I do not do any error checking in the script to make sure the tweet was sent, but errors are printed.
We now need to insert some tweets into our table. Since my friend is going to be sending inspirational quotes, I found a few I can import. In order to make it easier for importing, all single quote marks (‘) will be replaced by the carat symbol (^). I can then swap these symbols inside the Perl script. You could use the backslash (\) before the single quote, but I prefer a single character substitution so I know how long the tweet will be.
I will also use the tilde (~) as a way to designate a carriage return in my tweet. The Perl script will replace the tilde with a carriage return (\n). Two tildes give me two carriage returns and a blank line.
1
2
3
|
insert into tweets (tweet) VALUES('I^m not afraid. -Luke~~You will be. -Yoda~~http://SomeWebSiteHere.com'); insert into tweets (tweet) VALUES('Do or do not. There is no try.~~-Yoda~~http://SomeWebSiteHere.com'); insert into tweets (tweet) VALUES('No, I am your father.~~-Darth~~http://SomeWebSiteHere.com'); |
I also created a history table to store the tweet identification numbers. Each tweet is assigned a unique number by twitter, and this is how you can access this tweet. I save this information so I can delete the tweets later using this number. I have included a short script for deleting tweets near the end of this post.
1
2
3
4
5
6
7
|
CREATE TABLE 'history' ( 'id' int(11) NOT NULL AUTO_INCREMENT, 'tweet' char(140) DEFAULT NULL, 'tweet_id' varchar(30) DEFAULT NULL, 'tweet_update' datetime DEFAULT NULL, PRIMARY KEY ('id') ) ENGINE=InnoDB AUTO_INCREMENT=1000032 DEFAULT CHARSET=latin1 |
You will need to register your application with twitter via apps.twitter.com, and obtain the following:
1
2
3
4
|
consumer_key consumer_secret access_token access_token_secret |
You will also need to register your mobile phone in order to link your twitter account to your application. I have not figured out how to use this script with someone else’s account, as the instructions for scripting Perl for use with twitter are not very thorough. I will try to add this at a later date.
Now that you have your application information and all of your tables created with data inserted, here is the Perl script for sending tweets. (You will need to install the necessary Perl modules that are used.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
#!/usr/bin/perl use Net::Twitter::Lite::WithAPIv1_1; use DBI; use DBD::mysql; my $Database = "tweets"; # ---------------------------------------------------------------------------------- # this has to be near the top - as other parts of the script rely on these figures # ---------------------------------------------------------------------------------- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime time; $year = $year + 1900; $mon = $mon + 1; # add a zero if the value is less than 10 if ($sec < 10) { $sec = "0$sec"; } if ($min < 10) { $min = "0$min"; } if ($hour < 10) { $hour = "0$hour"; } if ($mday < 10) { $mday = "0$mday"; } if ($mon < 10) { $mon = "0$mon"; } if ($year < 10) { $year = "0$year"; } if ($wday < 10) { $wday = "0$wday"; } if ($yday < 10) { $yday = "0$yday"; } if ($isdst prepare($query); $sth->execute(); while (@data = $sth->fetchrow_array()) { $id = $data[0]; $tweet = $data[1]; $last_tweet_date = $data[2]; $tweet_count = $data[3]; } $tweet_original = $tweet; # ---------------------------------------------------------------------------- # find tildes ~ and substitute for carriage return # find carats and substitue for single quote # ---------------------------------------------------------------------------- $tweet =~ s/~/\n/g; $tweet =~ s/\^/\'/g; # ---------------------------------------------------------------------------------- # check length of tweet # ---------------------------------------------------------------------------------- $tweet_length = length($tweet); if (length($tweet) > 140) { print "Error - tweet is longer than 140 characters\n"; exit; } # add to the tweet count $tweet_count++; # ---------------------------------------------------------------------------- # send tweet # ---------------------------------------------------------------------------- my $nt = Net::Twitter::Lite::WithAPIv1_1->new( traits => [qw/API::RESTv1_1/], consumer_key => "$consumer_key", consumer_secret => "$consumer_secret", access_token => "$access_token", access_token_secret => "$access_token_secret", ssl => 1 ); my $results = eval { $nt->update("$tweet") }; if ( my $err = $@ ) { die $@ unless blessed $err && $err->isa('Net::Twitter::Lite::Error'); warn "HTTP Response Code: ", $err->code, "\n", "HTTP Message......: ", $err->message, "\n", "Twitter error.....: ", $err->error, "\n"; } # ---------------------------------------------------------------------------- # update mysql with new date for last_tweet date/time # ---------------------------------------------------------------------------- $dbh = ConnectToMySql($Database); $query = "UPDATE tweets SET last_tweet_date = '$DateTime' , tweet_count = '$tweet_count' , tweet_length = '$tweet_length' where id = '$id'"; $sth = $dbh->prepare($query); $sth->execute(); # ---------------------------------------------------------------------------- # get the status id of the last tweet # ---------------------------------------------------------------------------- my $statuses = $nt->user_timeline({ user => "2044_The_Book", count=> 1 }); for my $status ( @$statuses ) { $tweet_id = "$status->{id}"; } if ( my $err = $@ ) { die $@ unless blessed $err && $err->isa('Net::Twitter::Lite::Error'); warn "HTTP Response Code: ", $err->code, "\n", "HTTP Message......: ", $err->message, "\n", "Twitter error.....: ", $err->error, "\n"; } # ---------------------------------------------------------------------------- # replace special characters # ---------------------------------------------------------------------------- $tweet =~ s/\\\n/~/g; $tweet =~ s/\'/^/g; # update mysql with new date for last_tweet date/time $dbh = ConnectToMySql($Database); $query = "insert into history (tweet,tweet_id,tweet_update) values ('$tweet_original','$tweet_id','$DateTime')"; $sth = $dbh->prepare($query); $sth->execute(); #---------------------------------------------------------------------- sub ConnectToMySql { #---------------------------------------------------------------------- my ($db) = @_; open(PW, "<..\/accessTweets") || die "Can't access login credentials"; my $db= ; my $host= ; my $userid= ; my $passwd= ; chomp($db); chomp($host); chomp($userid); chomp($passwd); my $connectionInfo="dbi:mysql:$db;$host:3306"; close(PW); # make connection to database my $l_dbh = DBI->connect($connectionInfo,$userid,$passwd); return $l_dbh; } |
In the subroutine ConnectToMySql, I store the MySQL login credentials in a text file one directory below where my Perl script is located. This file contains the following information:
1
2
3
4
|
database_name hostname or IP MySQL user name password |
You can instead include your information inside the file if you prefer.
If you want to delete your tweets, you can create a script to access the tweets in your history table, and then delete them one at a time. Here is an example without the database connections:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#!/usr/bin/perl use Net::Twitter::Lite::WithAPIv1_1; use DBI; use DBD::mysql; # ---------------------------------------------------------------------------- # delete tweet # ---------------------------------------------------------------------------- # replace the values for $consumer_key $consumer_secret $access_token $access_token_secret # with your values for your application my $nt = Net::Twitter::Lite::WithAPIv1_1->new( consumer_key => "$consumer_key", consumer_secret => "$consumer_secret", access_token => "$access_token", access_token_secret => "$access_token_secret", ssl => 1, ); my $statuses = $nt->destroy_status({ id => "$tweet_id" }); exit; |
Be sure to replace the value of
1 |
$tweet_id |
with the value from the tweet you want to delete.
That’s it for now. Hopefully this was fun, interesting, and even useful! Thank you for using MySQL!
Tony Darnell is a Principal Sales Consultant for MySQL, a division of Oracle, Inc. MySQL is the world’s most popular open-source database program. Tony may be reached at info [at] ScriptingMySQL.com and on LinkedIn. |