Profile picture

Co-founder @ RMOTR

Twitter Retweet Raffle Giveaway

Last updated: November 6th, 20182018-11-06Project preview

This notebooks shows how to select a random user that has retweeted a given list. We use it for our #bookgiveaways.

Last month, we introduced a Book Giveaway, a way to raise awareness about what we do + also doing some good by giving away an amazing book.

Getting Started

We're going to use the library Tweepy to pull the data from our tweets. IMPORTANT: you need to create a twitter App and get a couple of Auth tokens to do this.

First, I'll install tweepy (the ! before a line in Jupyter Notebooks lets you run shell commands):

In [1]:
!pip install tweepy
Collecting tweepy
  Downloading https://files.pythonhosted.org/packages/05/f1/2e8c7b202dd04117a378ac0c55cc7dafa80280ebd7f692f1fa8f27fd6288/tweepy-3.6.0-py2.py3-none-any.whl
Collecting requests-oauthlib>=0.7.0 (from tweepy)
  Downloading https://files.pythonhosted.org/packages/94/e7/c250d122992e1561690d9c0f7856dadb79d61fd4bdd0e598087dce607f6c/requests_oauthlib-1.0.0-py2.py3-none-any.whl
Collecting PySocks>=1.5.7 (from tweepy)
  Downloading https://files.pythonhosted.org/packages/53/12/6bf1d764f128636cef7408e8156b7235b150ea31650d0260969215bb8e7d/PySocks-1.6.8.tar.gz (283kB)
    100% |████████████████████████████████| 286kB 34.5MB/s 
Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.6/site-packages (from tweepy) (1.11.0)
Requirement already satisfied: requests>=2.11.1 in /usr/local/lib/python3.6/site-packages (from tweepy) (2.19.1)
Collecting oauthlib>=0.6.2 (from requests-oauthlib>=0.7.0->tweepy)
  Downloading https://files.pythonhosted.org/packages/e6/d1/ddd9cfea3e736399b97ded5c2dd62d1322adef4a72d816f1ed1049d6a179/oauthlib-2.1.0-py2.py3-none-any.whl (121kB)
    100% |████████████████████████████████| 122kB 41.2MB/s 
Requirement already satisfied: idna<2.8,>=2.5 in /usr/local/lib/python3.6/site-packages (from requests>=2.11.1->tweepy) (2.7)
Requirement already satisfied: urllib3<1.24,>=1.21.1 in /usr/local/lib/python3.6/site-packages (from requests>=2.11.1->tweepy) (1.23)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python3.6/site-packages (from requests>=2.11.1->tweepy) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/site-packages (from requests>=2.11.1->tweepy) (2018.8.24)
Building wheels for collected packages: PySocks
  Running setup.py bdist_wheel for PySocks ... done
  Stored in directory: /root/.cache/pip/wheels/22/5c/b5/12e0dfdfa85bea67b23628b6425fae715c687e947a45ee3df9
Successfully built PySocks
Installing collected packages: oauthlib, requests-oauthlib, PySocks, tweepy
Successfully installed PySocks-1.6.8 oauthlib-2.1.0 requests-oauthlib-1.0.0 tweepy-3.6.0
You are using pip version 18.0, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

We can verify that the installation worked:

In [2]:
import tweepy

I've already created my app and I have my access and secrent keys (I'll share the secret for the purpose of this tutorial, you can replace your owns:

In [3]:
CONSUMER_KEY = '5jc4v2VstT2ERGnQs6XhTA'
CONSUMER_SECRET = ''
In [4]:
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
api = tweepy.API(auth)

Our #giveaway tweet

This is the tweet we're using for our giveaway, id 1051188315855179776 (you can see a preview below): https://twitter.com/rmotr_com/status/1051188315855179776

In [5]:
tweet_id = '1051188315855179776'
In [6]:
tweet = api.get_status(tweet_id, tweet_mode='extended')
In [7]:
print(tweet.full_text)
This month we'll be giving away @joelgrus's fantastic book "Data Science from Scratch". We'll hold a raffle on Oct 30th 🍀.

To participate:
✅ Follow us
✅ RT this tweet

(we'll share the python script to find winners later 😎)

#GIVEAWAY #RMOTR https://t.co/d6RhAyBka6
In [8]:
tweet_image = tweet.entities['media'][0]['media_url_https']
tweet_image
Out[8]:
'https://pbs.twimg.com/media/DpaR74sWsAATHyu.jpg'
In [9]:
from IPython.core.display import Image, display
display(Image(tweet_image))

We can actually do a little bit better by just getting the embedded text of a tweet (we'll need the requests library):

In [10]:
import requests
In [11]:
class EmbededTweet:
    def __init__(self, tweet):
        self.tweet = tweet
    
    def _repr_html_(self):
        resp = requests.get('https://publish.twitter.com/oembed', params={
            'url': 'https://twitter.com/{author}/status/{tweet_id}'.format(
                author=tweet.author.screen_name,
                tweet_id=tweet.id_str
            )
        })
        resp.raise_for_status()
        return resp.json()['html']
In [12]:
EmbededTweet(tweet)
Out[12]:

Getting closer... does this user follow us?

The giveaway had as condition that the user had to retweet our original tweet (the one above) as well as follow us. We're going to use tweepy to check if a user follows rmotr_com

In [49]:
rmotr_com = tweet.author
In [50]:
rmotr_com.name
Out[50]:
'rmotr.com'
In [55]:
from IPython.core.display import Image, display
display(Image(rmotr_com.profile_image_url_https))

We can get the total list of follwers of @rmotr_com with the followers_ids method:

In [80]:
followers = rmotr_com.followers_ids()
In [77]:
type(followers)
Out[77]:
list
In [81]:
len(followers)
Out[81]:
2740

And we can check if some users are following us. For example, my User ID is:

In [82]:
api.get_user('santiagobasulto').id_str
Out[82]:
'27387166'
In [85]:
27387166 in followers
Out[85]:
True

I'm a follower 😊. But what about, for example @jack?

In [86]:
api.get_user('jack').id_str
Out[86]:
'12'
In [87]:
12 in followers
Out[87]:
False

Jack is not following us 😔

Important, as you might already know (and if you don't I recommend you our course 😉, a set is going to be more efficient for lookups than a list, so I'll turn the list into a set:

In [92]:
followers = set(followers)
In [93]:
27387166 in followers
Out[93]:
True

Finding all the retweets

We're now going to find all the users that retweeted our original tweet. The function to find retweets of a given tweet is api.retweets:

In [94]:
retweets = api.retweets(tweet_id, 100)
In [95]:
type(retweets)
Out[95]:
tweepy.models.ResultSet

Each retweet is a regular tweet with an author associated:

In [96]:
sample_retweet = retweets[0]
In [98]:
sample_retweet.author.screen_name
Out[98]:
'theAIJedi'

And we can now check if the user that retweeted us is also following us:

In [99]:
sample_retweet.author.id in followers
Out[99]:
True

Putting all together

We can now build a final set with all those users that are following us, we're going to call it participants, because it's the final list of participants for the givaway (those that meet both criteria, retweet + follow):

In [124]:
participants = [retweet.author for retweet in retweets if retweet.author.id in followers]

We have in total this number of participants:

In [125]:
len(participants)
Out[125]:
48

And originally, this number of retweets:

In [126]:
len(retweets)
Out[126]:
55

This is our final list of participants (note, we don't need pandas, I just use it to display a pretty table):

In [127]:
import pandas as pd
In [128]:
pd.DataFrame({
    'Name': [p.name for p in participants],
    'Handle': [p.screen_name for p in participants],
})
Out[128]:
Name Handle
0 The AI Jedi theAIJedi
1 Urban Rose UrbanRose2
2 Espoir Murhabazi EspyMur
3 🅺0🅶🆁🅰🅳 k0grad
4 Mike Ickes mickes
5 Marie McArdle mcardle70
6 Mac Feith maaac
7 Michael Harper harper_datamind
8 Zahed Shareef realzahed
9 Jamie jamiemetca
10 Juan Josue JuanJosue19
11 Joel Bryant keuzar
12 berm bitpid
13 Sam Null SamNull
14 Priya G priya_msft
15 Brandon Hoffman HoffmanCBrandon
16 GD's ♡ fulvenegoal
17 Richard L. Rogers RichardLRogers
18 FREEZZEE pgshandino
19 Sarahsong0302 sarahsong0302
20 Daniele Bongiovanni DanieleBongiov3
21 Stanley Ng stanleyhlng
22 Maraprik jar maraprikjar
23 Yugioh Yugioh1984
24 fabio marzotti MarzottiFabio
25 Kunule Imbayi kunule
26 Gokul Kathirvel _gokatz
27 Aditia A. Pratama aditia_ap
28 Tom Morgan whiskychat
29 Pat Harris HarrisPat
30 Jenny Rhee JennyRhee
31 Emillia 에밀리아 aemmillia
32 Djaballah DjaBaLLah_MI
33 Dan O. austerehound
34 Javi javiferrer
35 Totally not jay jaysupports
36 ECW wit_e
37 os uokesita
38 Kiki criostaidh
39 Norma wildlavender4
40 Abhi IntrepidLearner
41 Tigere Gurundoro RangTiger
42 Juan Carlos Quintero juancarlosqr
43 Sandra Garza sand2song
44 Erika vicErika
45 Zandra Kubota zan_toka
46 Kristian Erik Munk Googleulv
47 gulliverbear gulliverbear

Choosing the winner!

We can now pick a winner! Before that, we're going to shuffle our list to randomize the output first:

In [129]:
import random
In [130]:
random.shuffle(participants)

And we can check again the list of participants (should be a completely different order if you compare it with the one above:

In [131]:
pd.DataFrame({
    'Name': [p.name for p in participants],
    'Handle': [p.screen_name for p in participants],
})
Out[131]:
Name Handle
0 Tigere Gurundoro RangTiger
1 Stanley Ng stanleyhlng
2 Joel Bryant keuzar
3 Brandon Hoffman HoffmanCBrandon
4 The AI Jedi theAIJedi
5 Abhi IntrepidLearner
6 Pat Harris HarrisPat
7 Juan Josue JuanJosue19
8 🅺0🅶🆁🅰🅳 k0grad
9 Zandra Kubota zan_toka
10 Mac Feith maaac
11 Gokul Kathirvel _gokatz
12 Daniele Bongiovanni DanieleBongiov3
13 Urban Rose UrbanRose2
14 Totally not jay jaysupports
15 Yugioh Yugioh1984
16 Jamie jamiemetca
17 Djaballah DjaBaLLah_MI
18 Kristian Erik Munk Googleulv
19 Norma wildlavender4
20 FREEZZEE pgshandino
21 Richard L. Rogers RichardLRogers
22 Erika vicErika
23 ECW wit_e
24 Kunule Imbayi kunule
25 berm bitpid
26 gulliverbear gulliverbear
27 Javi javiferrer
28 Kiki criostaidh
29 Sam Null SamNull
30 Mike Ickes mickes
31 fabio marzotti MarzottiFabio
32 Sandra Garza sand2song
33 Jenny Rhee JennyRhee
34 Zahed Shareef realzahed
35 Espoir Murhabazi EspyMur
36 Maraprik jar maraprikjar
37 Priya G priya_msft
38 GD's ♡ fulvenegoal
39 Sarahsong0302 sarahsong0302
40 os uokesita
41 Juan Carlos Quintero juancarlosqr
42 Aditia A. Pratama aditia_ap
43 Marie McArdle mcardle70
44 Tom Morgan whiskychat
45 Dan O. austerehound
46 Michael Harper harper_datamind
47 Emillia 에밀리아 aemmillia

And now, to leverage the pop method, I'll turn participants into a set:

In [134]:
participants = set(participants)

And we can now picking some winners!

Important: The following users are NOT the final winners. This notebook is just for education purposes. The actual raffle is done with the other code:

In [140]:
for _ in range(5):
    winner = participants.pop()
    print("{}: {}".format(winner.name, winner.screen_name))
Marie McArdle: mcardle70
Totally not jay: jaysupports
Mac Feith: maaac
Yugioh: Yugioh1984
Pat Harris: HarrisPat
RMOTR Inc.
RMOTR Profile20060