Twython 401 Error for Raspberry Pi Tweetbot - twitter

In order to tweet both a photo (taken from the picamera) and a status update, I ran the following code on my raspberry pi:
!/usr/bin/env python
import sys
from twython import Twython
import os
import pygame
import pygame.camera
from pygame.locals import *
pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(640,480))
cam.start()
image = cam.get_image()
pygame.image.save(image,'webcam.jpg')
CONSUMER_KEY = 'X'
CONSUMER_SECRET = 'X'
ACCESS_KEY = 'X'
ACCESS_SECRET = 'X'
photo = open('webcam.jpg','rb')
api = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)
api.update_status_with_media(media=photo, status='Hello There!')
With correctly filled in access and token keys I received the following error:
'Twitter API returned a 401 (unauthorised), Timestamp out of bounds'
After configuring both my raspberry pi and Twitter account to the same timezone, the problem persisted.
Does anybody have a solution?
Thanks!

From here:
"It means that your server time is off by more than 30 seconds (actual
time not including time-zone differences). Look at the response header
to see what Twitter's time is."
So, you have to set the time of your server to match the Twitter time. Inspect the header of a Twitter response, look up the time in the Date field and compare it with your raspberry pi os time (and change this accordingly).

Related

How to get the full text in Tweepy v2 search

I'm trying yo get the full text in twitter search using Tweepy v2. I used search_recent_tweets(), but it returns only truncated tweets.
import tweepy
import credentials
client = tweepy.Client(credentials.bearer_token)
query = 'policy'
response = client.search_recent_tweets(query, tweet_fields = ["created_at", "text", "source"], max_results=10)
tweets = response.data
tweets[0]['text']
The output is:
"RT #saletan: I wasn't aware of this policy till it happened to my
son. I told the story below.\n\nSix weeks after they locked his
account, he…"

Twilio - Quick question (Unable to update record)

hope you are doing it right these days.
To summarize my problem, I think this is not working becuase I am using a free Twilio account instead of a paid one. But that's just my beginner theory. Now, the issue:
I have tried an official Twilio tutorial (https://www.twilio.com/blog/automating-ngrok-python-twilio-applications-pyngrok, I shared the link in case someone finds it interesting or needs it), which allows us to automate SMS webhook (sms_url) configuration by using Client (twilio) and pyngrok (ngrok).
def start_ngrok():
from twilio.rest import Client
from pyngrok import ngrok
url = ngrok.connect(5000)
print(' * Tunnel URL:', url)
client = Client()
client.incoming_phone_numbers.list(
phone_number=os.environ.get('TWILIO_PHONE_NUMBER'))[0].update(
sms_url=url + '/bot')
I can't explain all the things that I tried in the last 4 days, with no success. I keep getting the same error:
client.incoming_phone_numbers.list(phone_number=os.environ.get('TWILIO_PHONE_NUMBER'))[0].update(sms_url=url + '/bot')
IndexError: list index out of range
Something is not working with the list, it comes empty, although environment variables are working properly. I will work with just one phone_number, so there no need for list, indeed, so I started to change that line to avoid different errors and ended up with this:
def start_ngrok():
from twilio.rest import Client
from pyngrok import ngrok
url = ngrok.connect(5000)
print(' * Tunnel URL:', url)
client = Client()
client.incoming_phone_numbers("my_number").update(sms_url=str(url) + '/bot')
Then I got the final error that I can't solve by my self:
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/__init__.py", line 442, in update
payload = self._version.update(method='POST', uri=self._uri, data=data, )
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/twilio/base/version.py", line 106, in update
raise self.exception(method, uri, response, 'Unable to update record')
twilio.base.exceptions.TwilioRestException:
HTTP Error Your request was:
POST /Accounts/my_account_SID/IncomingPhoneNumbers/+my_number.json
Twilio returned the following information:
Unable to update record: The requested resource /2010-04-01/Accounts/my_account_SID/IncomingPhoneNumbers/+my_number.json was not found
More information may be available here:
https://www.twilio.com/docs/errors/20404
I tried all different phone numbers combinations/formats: nothing works.
Thanks for your time reading all this!
Looks like something changed since the blog was written or there was a mistake.
Try the below:
The only difference is adding .public_url to the url object. Also allowed a GET to /bot for testing.
from dotenv import load_dotenv
from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
load_dotenv()
app = Flask(__name__)
#app.route('/bot', methods=['POST','GET'])
def bot():
user = request.values.get('From', '')
resp = MessagingResponse()
resp.message(f'Hello, {user}, thank you for your message!')
return str(resp)
def start_ngrok():
from twilio.rest import Client
from pyngrok import ngrok
url = ngrok.connect(5000)
print('This is',url)
print(' * Tunnel URL:', url)
client = Client()
client.incoming_phone_numbers.list(
phone_number=os.environ.get('TWILIO_PHONE_NUMBER'))[0].update(
sms_url=url.public_url + '/bot')
if __name__ == '__main__':
if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
start_ngrok()
app.run(debug=True)

Tweepy user_search api is very slow

After two days of unsuccessful attempt to use twitter gem I have decided to use tweepy of python for a task. (My original attempt was with ruby and I posted the question here)
My task is to collect all those actresses who have a verified account on twitter. I have taken the list of actresses from wikipedia.
Everything looks fine till now. I have started hitting twitter REST api with each name and I check whether it is a verified account or not.
The only problem I have is that the response is very slow. It takes about 12-15 seconds for every request. Am I doing something wrong here or is it how it is suppose to be.
Below is my code in its entirety :
import tweepy
consumer_key = 'xxx'
consumer_secret = 'xxx'
access_token_key = 'xx-xx'
access_token_secret = 'xxx'
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token_key, access_token_secret)
api = tweepy.API(auth)
actresses = []
f = open('final','r')
for line in f:
actresses.append(line)
f.close()
print actresses
for actress in actresses:
print actress
users = api.search_users(actress)
for u in users:
if u.verified == True and u.name == actress:
print u.name + " === https://twitter.com/" + u.screen_name
Also is there any better way to extract the verified actresses using that list?
Unfortunately, there is no faster way to do it, given that you only know the actresses' full names, and not their screen names. Each request will take a long time, as Twitter needs to return the results of users matching the query (there may be quite a few). Each one needs to be loaded and examined, which can take a while, depending on how many results were returned.

List youtube channels as a back-end process without prompting for username and password using python

I want run a back-end process to get the list of channels from youtube without prompting for username password.I tried to do so with the following python code.
#!/usr/bin/python
from apiclient.discovery import build
from optparse import OptionParser
DEVELOPER_KEY = "MY API KEY"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,developerKey=DEVELOPER_KEY)
channels_response = youtube.channels().list(
part="contentDetails",
managedByMe="true",
onBehalfOfContentOwner=ownerdetail
).execute()
for channel in channels_response["items"]:
channel_id = channel["id"]
channel_title = channel["snippet"]["title"]
print "Channel details: %s - %s" % channel_id % channel_title
print "Done"
When I try to run this code I'm getting "Access Not Configured"> error in console.
My requirement is to run this successfully without prompting for username and password(since i want it as a back-end process). Any help is this would be really helpful since I'm new to this.
You can do so by getting a refresh token from OAuth2 Playground and setting it in your youtube object.
Here it explains a little more.
And a step by step video.

How to get twitter server time?

So I'm trying to build a real time monitoring tool for twitter key words using tweet sharp. I'm using the search API to collect queries every 10-15 seconds. When I make the calls, I only want to collect tweets that have appeared since the pervious update.
var twitter = FluentTwitter.CreateRequest().AuthenticateAs("username", "password").Search().Query().Containing("key word").Take(1000);
var response = twitter.Request();
currentResponseDateTime= Convert.ToDateTime(response.ResponseDate);
var messages = from m in response.AsSearchResult().Statuses
where m.CreatedDate > lastUpdateDateTime
select m;
lastUpdateDateTime = currentResponseDateTime;
My issue is that the twitter server time is different from the client times by a few seconds. I looked around and tried to get the datetime I recieved the response from the Response.ResponseDate property, but it looks like that is set based on the local computer time. I.e currentResponseDateTime is a few seconds ahead of the Twitter Server time. So I end up not collecting a few of the tweets.
Does anyone know how I can get the current server time from twitter search or REST API?
Thanks
I'm not sure how you would get the local server time of the twitter service, but one approach you could take is to store the date of the most recent twitter update seen in the "lastUpdateDateTime" field. That way, you're guaranteed to get all the messages since the last one you saw, regardless of the offset of the twitter server.
var twitter = FluentTwitter.CreateRequest().AuthenticateAs("username", "password").Search().Query().Containing("key word").Take(1000);
var response = twitter.Request();
currentResponseDateTime= Convert.ToDateTime(response.ResponseDate);
var messages = from m in response.AsSearchResult().Statuses
where m.CreatedDate > lastUpdateDateTime
select m;
lastUpdateDateTime = messages.Select(m => m.CreatedDate).Max();
Another approach (and one that Twitter recommends) is to pull the Date header from their API server's response, which provides Twitter's notion of time in GMT. This assumes that you can access the server response headers, and that depends on the method you're using to access the API.
For example, hitting https://api.twitter.com/1/help/test.json
$ lynx --dump --head https://api.twitter.com/1/help/test.json
HTTP/1.0 200 OK
Date: Tue, 22 Jan 2013 13:30:36 GMT
...
Reference: how to get the twitter server time (synchronize)? on dev.twitter.com support site.
Quoting Taylor Singletary:
The current time that Twitter "thinks" it is is returned in the "Date" HTTP header of every response to an API call you make. You can also issue a simple HTTP HEAD request to GET help/test to get the header as an initial syncing step for your app.

Resources