Display DM sender's username (Twitter) - python

I've got this code, where it basically authenticates to Twitter and streams Direct Messages directly (as soon as I send/receive, the message sent/received gets printed).
from twitter import *
import os
APP_KEY,APP_SECRET = 'appkey123', 'appsecret123'
MY_TWITTER_CREDS = os.path.expanduser('my_app_credentials')
if not os.path.exists(MY_TWITTER_CREDS):
oauth_dance("crypto sentiments", APP_KEY, APP_SECRET,
MY_TWITTER_CREDS)
oauth_token, oauth_secret = read_token_file(MY_TWITTER_CREDS)
auth = OAuth(
consumer_key=APP_KEY,
consumer_secret=APP_SECRET,
token=oauth_token,
token_secret=oauth_secret
)
twitter_userstream = TwitterStream(auth=auth, domain='userstream.twitter.com')
for msg in twitter_userstream.user():
print(msg)
if 'direct_message' in msg:
print (msg['direct_message']['text'])
My question: How can I modify this code so it displays the username of the sender? Like so: #Jack: Hey there!

Simple and dirty way (you could do something far nicer with the string formatting) would be something like
for msg in twitter_userstream.user():
print(msg)
if 'direct_message' in msg:
print ('#' + msg['direct_message']['screen_name'] + ': ' + msg['direct_message']['text'])
It is worth noting that Twitter's user streams will be going away in June, so you should look at the new Account Activity API instead. More details in this announcement.

Related

The bot for VK answers in a private messages, and not in a conversation

I am creating a reference bot for chatting in VK in Python using the Callback Api. The bot works correctly if you write to the group messages. However, if you write to a conversation (to which the bot is added), it replies to private messages. All rights to read, etc. issued. As I understand it (studying information on the internet), I use user_id, not chat_id. But I didn't understand how to fix it correctly (
p.s. It is advisable that the bot write both in private messages and in a conversation, depending on where they ask.
p.p.s perhaps the question seems ridiculous, but I just started to study this area, and I did not find the answer on the net :-)
The bot itself:
import vk
import random
import messageHandler
# app.route ('/', methods = ['POST'])
def processing ():
data = json.loads (request.data)
if 'type' not in data.keys ():
return 'not vk'
if data ['type'] == 'confirmation':
return confirmation_token
elif data ['type'] == 'message_new':
messageHandler.create_answer (data ['object'] ['message'], token)
return 'ok'
"Responder":
import importlib
from command_system import command_list
def load_modules ():
# path from the working directory, it can be changed in the application settings
files = os.listdir ("mysite / commands")
modules = filter (lambda x: x.endswith ('. py'), files)
for m in modules:
importlib.import_module ("commands." + m [0: -3])
def get_answer (body):
# Default message if unrecognizable
message = "Sorry, I don't understand you. Write '/ help' to see my commands."
attachment = ''
for c in command_list:
if body in c.keys:
message, attachment = c.process ()
return message, attachment
def create_answer (data, token):
load_modules ()
user_id = data ['from_id']
message, attachment = get_answer (data ['text']. lower ())
vkapi.send_message (user_id, token, message, attachment)
I don't speak English well, so I apologize for the crooked translation)
Use Peer_id, instead of from_id. (data->object->peer_id)
(i used php, but i had a similar problem. this is the solution)
probably something like this:
def create_answer (data, token):
load_modules ()
user_id = data ['peer_id'] # id source edited
message, attachment = get_answer (data ['text']. lower ())
vkapi.send_message (user_id, token, message, attachment)
from_id - person who sent the message
peer_id - in which dealogue message was received. (for groups it looks like 20000005)
So, you will send the message to conversation (does not matter is this PM or conversation with a lot of people)

Gmail API error when access token expires (Python, Django): HttpAccessTokenRefreshError invalid_client: The OAuth client was not found

i'm building a Django project. I need to send emails through Gmail's API, so i created a project, got API keys, oauth credentials, etc.
I managed to do the "authorization" part, where the user signs in, gives you permission to read + send emails (with access_type=offline, as far as I know) and you get an access_token. I save the "access_token", the "expires_in" and the "refresh_token" fields for the user in a database.
Then, i can read the labels of the user's emails, send emails in his name, etc. No problem.
The problem arises once the access_token expires (so, after an hour of the user giving permission).
When trying to send an email, the error i get is:
HttpAccessTokenRefreshError at /test_gmail_api3/
invalid_client: The OAuth client was not found.
I browsed a lot of related stackoverflow questions and tried changing a lot of different things but nothing works. The only thing that works is manually revoking access from my test gmail account, giving access again, and then it works perfectly... until the access_token expires again.
This is the error:
And these are the relevant parts of the code (t ):
This are the relevant parts of the code:
View used to ask user for consent/permission (works well, redirects to test_gmail_api2 with a code:
def test_gmail_api(request):
flow = OAuth2WebServerFlow(client_id='<< edited to keep secret >>.apps.googleusercontent.com',
client_secret='<< edited to keep secret >>MpNLDa',
scope=('https://www.googleapis.com/auth/gmail.readonly ' + 'https://www.googleapis.com/auth/gmail.send'),
redirect_uri='http://localhost:8000/test_gmail_api2/')
auth_uri = flow.step1_get_authorize_url()
return redirect(auth_uri)
view used to use the google code to get access_token and refresh_token (works well, i get the tokens and save them as strings):
def test_gmail_api2(request):
flow = OAuth2WebServerFlow(client_id='<< edited to keep secret >>.apps.googleusercontent.com',
client_secret='<< edited to keep secret >>MpNLDa',
scope=('https://www.googleapis.com/auth/gmail.readonly ' + 'https://www.googleapis.com/auth/gmail.send'),
redirect_uri='http://localhost:8000/test_gmail_api2/')
credentials = flow.step2_exchange(request.GET.get('code', ''))
current_profile = Profile.objects.get(email_address='none#test.com')
current_profile.access_token = credentials.get_access_token(http=None).access_token
current_profile.access_token_expiration = credentials.get_access_token(http=None).expires_in
string_credentials = credentials.to_json()
json_credentials = json.loads(string_credentials)
current_profile.refresh_token = json_credentials['refresh_token']
current_profile.save()
service = build('gmail', 'v1', http=credentials.authorize(Http()))
# Call the Gmail API
test_response = ""
results = service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
if not labels:
test_response += 'No labels found.'
else:
test_response += 'Labels:'
for label in labels:
test_response += label['name'] + "<br>"
response = service.users().messages().list(userId='me',
q='has:attachment').execute()
messages = []
if 'messages' in response:
messages.extend(response['messages'])
test_response += string_credentials
return HttpResponse(test_response)
Finally, the view that reads all labels and sends an email:
def test_gmail_api3(request):
client_id='<< edited to keep secret >>.apps.googleusercontent.com',
client_secret='<< edited to keep secret >>MpNLDa'
current_profile = Profile.objects.get(email_address='none#test.com')
refresh_token = current_profile.refresh_token
access_token = current_profile.access_token
expires_at = current_profile.access_token_expiration
some_user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.517 Safari/537.36'
cred = oauth2client.client.GoogleCredentials(access_token,client_id,client_secret,
refresh_token,expires_at,"https://accounts.google.com/o/oauth2/token",some_user_agent) # tried access_token=None and token_expiry=None but it doesn't work
http = cred.authorize(httplib2.Http())
service = build('gmail', 'v1', http=cred.authorize(Http()))
# Call the Gmail API
test_response = ""
string_credentials = cred.to_json()
json_credentials = json.loads(string_credentials)
test_response += string_credentials + '<br>'
results = service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
if not labels:
test_response += 'No labels found.'
else:
test_response += 'Labels:'
for label in labels:
test_response += label['name'] + "<br>"
response = service.users().messages().list(userId='me',
q='has:attachment').execute()
messages = []
if 'messages' in response:
messages.extend(response['messages'])
test_response += cred.to_json() + '<br>'
user_id='me'
threads = service.users().threads().list(userId=user_id).execute().get('threads', [])
for thread in threads:
tdata = service.users().threads().get(userId=user_id, id=thread['id']).execute()
nmsgs = len(tdata['messages'])
if nmsgs > 2: # skip if <3 msgs in thread
msg = tdata['messages'][0]['payload']
subject = ''
for header in msg['headers']:
if header['name'] == 'Subject':
subject = header['value']
break
if subject: # skip if no Subject line
test_response += subject + ' has num of mssgs: ' + str(nmsgs) + '<br>'
message = MIMEText('blah blah blah')
message['to'] = 'my_personal_email#gmail.com'
message['from'] = 'me'
message['subject'] = 'it seems to be working'
final_mssg = {'raw': base64.urlsafe_b64encode(message.as_string().encode()).decode()}
try:
message = (service.users().messages().send(userId='me', body=final_mssg).execute())
test_response += 'WE JUST SENT A MESSAGE WITH ID ' + message['id']
except Exception as e:
test_response += "we couldn't send the message. Error: " + str(e)
return HttpResponse(test_response)
I don't know what's the problem. I've tried changing a lot of things in the code, but can't get away from this error. I've been battling with this for 2 days know and i'm going crazy. Can somebody help me please?
Thanks!
PS: this is the database entry where the tokens are correctly saved:
django database entry with token strings
My god, I just found the solution.
I went through the error log again and noticed that the variable "client_id" was a list instead of a string:
local vars in error log
Went back to the code an saw that there was an extra comma were there shouldn't be (hence, making "client_id" a list instead of a string like it should):
extra comma in the code causing the error
And this is what triggered the error. I guess it only triggered it when it needed to refresh the token.
Removed the comma and works nicely now. Silly me. 🤦
Sorry about the question, it was very specific to me and i guess it won't ever help anyone.
I know that the code needs a lot of redoing and tidyng up (for example, i do cred.authorize() 2 times!), it was just for testing purposes and i got stuck in it.

Creating Slackbot with Google Sheets integration using python and git

My name is Ken. I am trying to create a Slack Bot first one message every Monday at 9:00 am and asks for a input (goal number of sales for the week). Then responds with user input in new message saying (great your weekly sales goal is (#). Then it takes this number and adds it to Google sheets. Then asks user to enter daily goal for the day. And responds with (daily goal set as). Then at 9:00 pm asks user to input the number of deals written and keeps track of all data in Google sheets and provides graphs. I have been thinking maybe MySQL would work for that too.
Here is some of the code I have so far:
starterbot.py
import os
import time
from slackclient import slackclient
# starterbot's ID as an environment variable
BOT_ID = os.environ.get("BOT_ID")
# contasts
AT_BOT = "<#" + BOT_ID + ">"
EXAMPLE_COMMAND = "do"
#instantiate Slack & Twilio clients
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
def handle_command (command, channel)
"""
Receives commnds directed at the bot and determines if they
are valid commands. if so, then acts on the commands. if not,
returns back what it needs for clarification.
"""
response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \
"* command with numbers, delimited by spaces."
if command.startswitch(EXAMPLE_COMMAND):
response = "Sure ... wire some more c ie then I can do
that!"
slack_client.api_call("chat.postMessage", channel=channel,
text=response, as_user=True)
def parse_slack_output(slack_messages):
"""
The Slack Real Time Messaging API is an event firehose.
this parsing function returns None unless a message is
directed at the Bot, based on its ID.
"""
if slack_messages and len(slack_messages) > 0;
for message in slack_messages:
if message and 'text' in message and AT_BOT in message['text']:
command = message['text'].split(AT_BOT)[1].strip().lower()
channel = message['channel']
# return text after the # mention, white space removed
return command, channel
return None, None
if __name__ == "__main__":
READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
if slack_client.rtm_connect():
print("starterbot connected and running!")
while True:
command, channel = parse_slack_output(slack_client.rtm_read())
if command and channel:
handle_command(command, channel)
time.sleep(READ_WEBSOCKET_DELAY)
else:
print("Connection failed. Invalid Slack token or bot ID?")
bot_id_py
import os
from slackclient import SlackClient
import pdb
BOT_NAME = 'pilot4u'
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
if __name__ == "__main__":
api_call = slack_client.api_call("users.list")
if api_call.get('members'):
pdb.set_trace()
# Retrieve all users so we can find our bot
users = api_call.get('members')
for user in users:
if 'name' in user and user.get('name') == BOT_NAME:
print("Bot ID for '" + user ['name'] + "'is " +
user.get('id'))
else:
print("could not find bot user with the name " + BOT_NAME)

Receiving GChat Messages using sleekXMPP or another client in python?

I have sleekXMPP for python and I have used the API to create functions to send messages, although when I researched into receiving them I can't find anything, can someone please help me to work this out, or disprove the possibility. Thanks.
Below is the code I used to send Messages, If its any help.
to = config.get('usermap', to[4:])
gmail_from_user = config.get('auth', 'email')
gmail_from_secret = config.get('auth', 'secret')
sys.stdout = stdouttmp
sys.stderr = stderrtmp
print "Sending chat message to " + to
xmpp = SendMsgBot(gmail_from_user, gmail_from_secret, to, message)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0199') # XMPP Ping
sys.stdout = stdouttmp
if xmpp.connect(('talk.google.com', 5222)):
xmpp.process(block=True)
else:
sys.stdout = stdouttmp
print("Unable to connect.")
sys.stdout = stdouttmp
sys.stderr = stderrtmp
btw I'm using a .cfg text file for the users email and password, along with some contacts, which is then parsed in
I see that you're using the send_client.py example. The intent of that example is how to reliably log in, send a single message, and then log out. Your use case is to both send and receive messages, so you would be better served looking at the echo_client.py example.
Notably, in order to receive a message you would do:
# in your __init__ method:
def __init__(...):
# ...
self.add_event_handler('message', self.recv_message)
def recv_message(self, msg):
# You'll probably want to ignore error and headline messages.
# If you want to handle group chat messages, add 'groupchat' to the list.
if msg['type'] in ('chat', 'normal'):
print "%s says: %s" % (msg['from'], msg['body'])
Again, you will need to switch from using the SendMsgBot example because it automatically disconnects after sending its message.
Don't forget that there is the sleek#conference.jabber.org chat room if you need any help.
-- Lance

How can I retrieve a Google Talk users Status Message

I'd like to be able to retrieve a users Google Talk Status Message with Python, it's really hard to find documentation on how to use some of the libraries out there.
I don't have anything to hand with xmpp installed, but here's some old code I had lying around that might help you. You'll want to update the USERNAME/PASSWORD to your own values for test purposes.
Things to note: users logged in to Google Talk get a random presence string on their userid: that doesn't matter if you are trying to get the status of some other user, but if you want to write some code so want to communicate with yourself you need to distinguish the user logged in from GMail or a GTalk client from the test program. Hence the code searches through the userids.
Also, if you read the status immediately after logging in you probably won't get anything. There's a delay in the code because it takes a little while for the status to become available.
"""Send a single GTalk message to myself"""
import xmpp
import time
_SERVER = 'talk.google.com', 5223
USERNAME = 'someuser#gmail.com'
PASSWORD = 'whatever'
def sendMessage(tojid, text, username=USERNAME, password=PASSWORD):
jid = xmpp.protocol.JID(username)
client = xmpp.Client(jid.getDomain(), debug=[])
#self.client.RegisterHandler('message', self.message_cb)
if not client:
print 'Connection failed!'
return
con = client.connect(server=_SERVER)
print 'connected with', con
auth = client.auth(jid.getNode(), password, 'botty')
if not auth:
print 'Authentication failed!'
return
client.RegisterHandler('message', message_cb)
roster = client.getRoster()
client.sendInitPresence()
if '/' in tojid:
tail = tojid.split('/')[-1]
t = time.time() + 1
while time.time() < t:
client.Process(1)
time.sleep(0.1)
if [ res for res in roster.getResources(tojid) if res.startswith(tail) ]:
break
for res in roster.getResources(tojid):
if res.startswith(tail):
tojid = tojid.split('/', 1)[0] + '/' + res
print "sending to", tojid
id = client.send(xmpp.protocol.Message(tojid, text))
t = time.time() + 1
while time.time() < t:
client.Process(1)
time.sleep(0.1)
print "status", roster.getStatus(tojid)
print "show", roster.getShow(tojid)
print "resources", roster.getResources(tojid)
client.disconnect()
def message_cb(session, message):
print ">", message
sendMessage(USERNAME + '/Talk', "This is an automatically generated gtalk message: did you get it?")

Categories

Resources