This content originally appeared on DEV Community and was authored by Choudhry
I will explain how I built this Twitter bot freenftbot, but first allow me to have to floor to tell you how I got here. Like all good internet stories it started with a meme.
After seeing this meme I went down the rabbit hole and in a shocking turn of events. These scammy influencers got people on Twitter attacking people for using jpgs they don't own the NFT of.
So I thought it's time to take a stand against the cringe mining, pixelated dildo jpg having, virtual hypebeasts. It's time to use my unique set of skills and terrible prioritization of time and build a Twitter bot.
So you might be asking what does the bot do?
It's simple you follow the instructions here: (I have screenshots of people failing this)
And Profit xD:
How I did it and you can too
To be clear I'm going going to give tips around places I got stuck and skip the straight forward parts or easy to google parts.
Perquisites
- Some python skills
- Twitter developer access for the API get it and apply for ELEVATED access so you get access to the V1 API because V2 doesn't have media upload yet. here (I create a separate account for my bot. I would say do that too, but live your life Queen)
- Set up Google cloud project if you haven't used your free tier look into it. I'll explain parts of it, but google is your friend.
- Some NFT images I grabed this kaggle dataset
To kick off these are my global scope variables
import tweepy
import config # I put secrets and tokens here
# client is the V2 API
client = tweepy.Client(
bearer_token=config.BEARER_TOKEN,
consumer_key=config.KEY,
consumer_secret=config.SECRET,
access_token=config.ACCESS_TOKEN,
access_token_secret=config.ACCESS_TOKEN_SECRET,
)
# api is the V1 API
auth = tweepy.OAuthHandler(config.KEY, config.SECRET)
auth.set_access_token(config.ACCESS_TOKEN, config.ACCESS_TOKEN_SECRET)
api = tweepy.API(auth)
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "<google service account key json>"
storage_client = storage.Client("<google cloud project>")
bucket = storage_client.bucket("<google storage bucket>") # where all the NFT images are
The documentation is actually really good here
One neat thing about google cloud functions, if the environment hasn't been deleted it'll reuse this variables so they won't be re-assigned every run. Smaller carbon footprint. #OurPlanet
Now how do you get all mentions from the last 5 minutes?
client.get_users_mentions(id=ID, start_time=<time 5 mins ago>)
now do it again, but handle pagination
def get_nft_mentions(start_time, max=100):
nft_tweets = set() # avoid duplicates
response = client.get_users_mentions(id=ID, max_results=max, start_time=start_time)
next_token = True
while next_token:
tweets = response.data
if tweets != None:
for tweet in tweets:
if does_text_have_hashtag(tweet.text) and is_following(tweet.author_id):
nft_tweets.add(tweet)
if "next_token" in response.meta:
response = response = client.get_users_mentions(
id=ID,
max_results=max,
tweet_fields=["author_id"],
start_time=start_time,
pagination_token=response.meta["next_token"],
)
else:
next_token = False
return nft_tweets
We have a set of tweets to loop over. We just need to grab a random NFT from our bucket that's easy using our neatfy csv file of all of our NFTs we got with the images and some pandas:
def download_file(file_name):
destination_file = "/tmp/" + file_name # You can use tmp in cloud function for tmp files just like the NFT images for this
blob = bucket.blob(file_name)
blob.download_to_filename(destination_file)
return destination_file
def pick_nft(nft_frame):
nft_row = nft_frame.sample(n=1)
nft_hash = nft_row["IPFS HASH"].iloc[0]
nft_file = download_file(f"{nft_hash}.jpg")
return nft_file, nft_row["INITIAL SEQUENCE INDEX"].iloc[0]
def get_media_id(nft):
return api.simple_upload(nft).media_id_string # Remember api. uses the V1 API client. uses the V2 API. V2 doesn't have media upload (yet)
So we have a tweet to reply to and a image uploaded ready to reply with.
(dead meme lol)
def reply_with_nft(tweet, media_id):
return client.create_tweet(in_reply_to_tweet_id=tweet.id, media_ids=[media_id])
put it all together in a main function
def main(request): # Need a parameter for cloud functions
csv_file = download_file("hashes.csv")
nft_frame = pd.read_csv(csv_file)
tweets = get_nft_mentions(get_time_five_mins_ago())
errors = []
for tweet in tweets:
# chosen NFT and upload it
nft_path, nft_index = pick_nft(nft_frame)
media_id = get_media_id(nft_path)
# reply to tweet
response = reply_with_nft(tweet, media_id)
# if response is clean all user to cd file and remove nft
if len(response.errors) == 0:
nft_frame.drop(nft_index, axis=0, inplace=True)
else:
print(response.errors)
errors.append(response.errors)
nft_frame.to_csv(csv_file, index=False)
upload_file(csv_file)
if len(errors) >= 0:
return "There's some problems boss" # you need a return statement for cloud functions
else:
return "all good"
AND THERE YOU HAVE IT! it's not the prettiest cloud function, but it's a valid cloud function. We set the bar at "it works kinda" around here. Now the one I have in production had a few extra bells and whistles, but let's not get caught up with the devil in the details.
The Power of the cloud
First we need a cloud function. You can work it out! I believe in you. Well I don't know you, so I don't, but try anyways. There's a few things I can give you tips on.
Cloud Function Tips:
- uncheck "Require HTTPS" is just causes issues I couldn't get it work, but good luck if you want it.
- If you choose to upload your project through zip the main file needs to be in the root of the zip file.
- Under "Runtime, build, connections and security settings" the time out is defaulted to 60 seconds there's a max of 540 seconds.
- Error messages are found under the details tab.
If all goes well and you have a green tick. We now have:
But how do we use it? For this case I used Cloud Scheduler!
Pick a time frequency. Under "Configure the execution" Target Type is HTTP URL you get that from the cloud function then add a "OIDC TOKEN" under Auth Header for the Audience use the HTTP URL again (I don't get it either) and hit the blue button and hope for the best.
Tips if it fails:
- If the error is "internal" check your cloud function logs.
- If the error is "Permission Denied" your service account permissions are fried. - Confucius (art of war)
Thanks you for reading I hope I made you laugh because God help you if you found me helpful. If you have nothing else better to do go follow me on twitter @itsChoudhry
Lastly I would like to give credit to a Twitter friend who said "Building a twitter bots is fun" - Talal check out his bots FriendCircleBot and WordCloudBot
This content originally appeared on DEV Community and was authored by Choudhry
Choudhry | Sciencx (2022-01-22T23:15:28+00:00) I found out the NFT police is real, so I made a bot and I’ll tell you how to. Retrieved from https://www.scien.cx/2022/01/22/i-found-out-the-nft-police-is-real-so-i-made-a-bot-and-ill-tell-you-how-to/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.