I have a Twitter bot which is working great. However, I have encountered an issue when it comes to following users which have a private Twitter account.
The bot will send a follow request, and then keep sending the follow request even though a request has already been sent.
Is it possible to skip following back accounts that are private?
Here's the code:
#!/usr/bin/env python3.8
#followback.py
import tweepy
import logging
from config import create_api
import time
def get_friends():
# gets a list of your followers and following
followers = api.followers_ids(screen_name)
following = api.friends_ids(screen_name)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()
def follow_followers(api):
logger.info("Retrieving and following followers...")
for follower in tweepy.Cursor(api.followers).items():
if not follower.following:
try:
logger.info("Now following "+ (follower.screen_name))
follower.follow()
except tweepy.TweepError as error:
if error.api_code == 160:
logger.info("Already sent a follow request to " + (follower.screen_name) + ". Attempting to skip.")
def main():
api = create_api()
while True:
follow_followers(api)
logger.info("Waiting...")
time.sleep(120)
if __name__ == "__main__":
main()
I have now added some code:
if error.api_code == 160:
logger.info("Already sent a follow request to " + (follower.screen_name) + ".
Which catches the error and looks neater in the log, but it is filling the log up with:
INFO:root:Retrieving and following followers...
INFO:root:Now following "user a"
INFO:root:Already sent a follow request to "user a". Attempting to skip.
INFO:root:Now following "user b"
INFO:root:Already sent a follow request to "user b". Attempting to skip.
INFO:root:Waiting...
INFO:root:Retrieving and following followers...
INFO:root:Now following "user a"
INFO:root:Already sent a follow request to "user a". Attempting to skip.
INFO:root:Now following "user b"
INFO:root:Already sent a follow request to "user b". Attempting to skip.
INFO:root:Waiting...
Both user a and user b in this example are private accounts.
Let me know if you require any further information, thanks.
You can check the protected attribute of each User object, e.g. if not follower.protected:.
Related
The issue is that the third function never seems to respond.
I haven't been able to find a reason why this happens in the telegram documentation.
Please let me know if you have this issue or seen it and know the solution.
Even a post that references an issue like this would work.
Thank you so much for the assistance.
from email import message
import os
import re
import html
import json
import telebot
import requests
import http.client
from pytube import *
from dotenv import load_dotenv
load_dotenv()
# Creating hiding, and using API Keys
API_KEY = os.getenv("API_KEY")
RAPID_KEY = os.getenv("RAPID_API")
bot = telebot.TeleBot(API_KEY)
#bot.message_handler(commands="start")
# Creating a help message for guidance on how to use bot.
def help(message):
# Trying to send help message, if unable to send, throw an error message for the user.
try:
bot.send_message(message.chat.id, "Use \"Youtube\" and the video name to search for a video.\n")
except:
bot.send_message(message.chat.id, "There was an error fetching help, the bot may be offline.\n")
# Checking data and seeing if the word "YouTube" was used in order to start the search
def data_validation(message):
query = message.text.split()
if("youtube" not in query[0].lower()): # Set flag false if regular text
return False
else:
return True
#bot.message_handler(func=data_validation)
# Searching for youtube videos
# using RAPID API
def search(message):
query = message.text.split()
# Check if data is valid, and change variable to be lowercase for easy use.
if(data_validation(message) == True and query[0].lower() == "youtube"):
try:
if(data_validation(message) == True and query[1].lower() != "-d"):
# Removing the word "YouTube" and sending the results to the YouTube search engine.
for item in query[:]:
if(item.lower() == "youtube"):
query.remove(item)
search_query = ' '.join(query)
else:
pass #If it's not term we're looking to convert, ignore it.
# RAPID API for Youtube
try:
url = "https://youtube-search-results.p.rapidapi.com/youtube-search/"
querystring = {"q":search_query}
headers = {
"X-RapidAPI-Key": RAPID_KEY,
"X-RapidAPI-Host": "youtube-search-results.p.rapidapi.com"
}
response = requests.request("GET", url, headers=headers, params=querystring) # Grabbing response information from URL
request = json.loads(response.text) # Parsing json string for python use
# Testing to see if the RAPID API service responds and is online.
if(response.status_code == 503):
# If the service is not online, let the user know.
bot.send_message(message.chat.id, f"The RAPID API service appears to be offline try back later.\n")
if(response.status_code == 429):
# If the service has reached max quota for the day, let the user know.
bot.send_message(message.chat.id, f"Max quota reached, try back in 24 hours.\n")
# Grabbing first link from json text and sending direct url and title.
first_link = str((request["items"][0]["url"]))
bot.send_message(message.chat.id, f"{first_link}\n") # Sending first link that was queried.
# If there are no results found for the requested video, sending an error message to alert the user.
except:
bot.send_message(message.chat.id, "Unable to load video.\n")
except:
pass #ignoring if not the phrase we're looking for.
def test(message):
string = message.text.split()
print(string)
if(string[0] == "test" and data_validation(message) == True):
print("This is a test and i should be printed")
bot.send_message(message.chat.id, "Test message")
# Stay alive function for bot pinging / communication
bot.infinity_polling(1440)
The first problem in your code is your first line
from email import message
You import the message from email and also pass a parameter to the data_validation function with the same name, then return False in the data_validation function. If you return false, the function never will be executed.
first give an alias to first line you imported
Try This
from email import message as msg
import os
import re
import html
import json
import telebot
import requests
import http.client
from pytube import *
from dotenv import load_dotenv
load_dotenv()
# Creating hiding, and using API Keys
API_KEY = os.getenv("API_KEY")
RAPID_KEY = os.getenv("RAPID_API")
bot = telebot.TeleBot(API_KEY)
# Creating a help message for guidance on how to use bot.
#bot.message_handler(commands=["start"])
def help(message):
# Trying to send help message, if unable to send, throw an error message for the user.
try:
bot.send_message(message.chat.id, "Use \"Youtube\" and the video name to search for a video.\n")
except:
bot.send_message(message.chat.id, "There was an error fetching help, the bot may be offline.\n")
# Checking data and seeing if the word "YouTube" was used in order to start the search
def data_validation(message):
query = message.text.split()
print(query)
if("youtube" not in query[0].lower()): # Set flag false if regular text
return False # if you return false, the function never will be executed
else:
return True
# Searching for youtube videos
# using RAPID API
#bot.message_handler(func=data_validation)
def search(message):
query = message.text.split()
print(query) # if function executed you see the query result
# Check if data is valid, and change variable to be lowercase for easy use.
if(data_validation(message) == True and query[0].lower() == "youtube"):
try:
if(data_validation(message) == True and query[1].lower() != "-d"):
# Removing the word "YouTube" and sending the results to the YouTube search engine.
for item in query[:]:
if(item.lower() == "youtube"):
query.remove(item)
search_query = ' '.join(query)
else:
pass #If it's not term we're looking to convert, ignore it.
# RAPID API for Youtube
try:
url = "https://youtube-search-results.p.rapidapi.com/youtube-search/"
querystring = {"q":search_query}
headers = {
"X-RapidAPI-Key": RAPID_KEY,
"X-RapidAPI-Host": "youtube-search-results.p.rapidapi.com"
}
response = requests.request("GET", url, headers=headers, params=querystring) # Grabbing response information from URL
request = json.loads(response.text) # Parsing json string for python use
# Testing to see if the RAPID API service responds and is online.
if(response.status_code == 503):
# If the service is not online, let the user know.
bot.send_message(message.chat.id, f"The RAPID API service appears to be offline try back later.\n")
if(response.status_code == 429):
# If the service has reached max quota for the day, let the user know.
bot.send_message(message.chat.id, f"Max quota reached, try back in 24 hours.\n")
# Grabbing first link from json text and sending direct url and title.
first_link = str((request["items"][0]["url"]))
bot.send_message(message.chat.id, f"{first_link}\n") # Sending first link that was queried.
# If there are no results found for the requested video, sending an error message to alert the user.
except:
bot.send_message(message.chat.id, "Unable to load video.\n")
except:
pass #ignoring if not the phrase we're looking for.
def test(message):
string = message.text.split()
print(string)
if(string[0] == "test" and data_validation(message) == True):
print("This is a test and i should be printed")
bot.send_message(message.chat.id, "Test message")
# Stay alive function for bot pinging / communication
bot.infinity_polling(1440)
I found that using "if name == 'main':" and keeping all the functions in "main():" as a function handler everything ran smoothly.
I'm still trying to figure out why this works.
I am trying to build a slackbot for my group , I tried sample codes and some other things but its not sending message to the group.
first i tried via terminal
export SLACK_API_TOKEN="my_token_id"
Then
from slackclient import SlackClient
import os
slack_token = os.environ["SLACK_API_TOKEN"]
sc = SlackClient(slack_token)
sc.api_call(
"chat.postMessage",
channel="#random",
text="Hello from Python! :tada:",
thread_ts="283.5127(dummy_id)",
reply_broadcast=False
)
print(sc)
#<slackclient.client.SlackClient object at 0x109b77ba8>
But there is no message in slack group.
I tried with this code:
from slackclient import SlackClient
import os
slack_token = os.environ['SLACK_API_TOKEN']
sc = SlackClient(slack_token)
print(sc.api_call("channels.list"))
its retuning :
{'error': 'invalid_auth', 'ok': False}
I am not getting what i am doing wrong , Access token is correct , i want to post some messages via a bot , so how i can create a bot on slack and using that bot i can send messages via python ?
I had similar issues when I implemented a slack bot with php & symfony.
It's not that simple to create and configure the slack app, bot and OAuth permissions properly.
I explained all these configurations in this blog post if you need it: https://blog.eleven-labs.com/en/en/replace-erp-by-slack-bot-with-dialogflow-and-symfony/
Also my code in PHP is very similar to what you need to parse Slack requests and post to its API.
Summary, TL;DR:
Go to https://api.slack.com/apps and click on 'Create New App'.
In this app configuration, go to the left menu 'Bot Users' or from 'Basic Information' > 'Add features and functionality' > 'Bots'.
Still in this app config, go to the menu 'OAuth & Permissions' and allow the scope 'chat:write:bot' and copy the value of 'OAuth Access Token'
From your code, call 'chat.postMessage' API method with an 'Authorization' header using previous token value.
built this from some examples found on the web: liza daly - brobot : github.com
and
How to Build Your First Slack Bot with Python : fullstackpython.com
certainly not the best implementation but it functions as an appropriate answer to (i think)
import random
import time
import re
from slackclient import SlackClient
bot_id = None
slack_token = 'xoxb-no.more.mister.nice.gui'
sc = SlackClient(slack_token)
# constants
RTM_READ_DELAY = 1 # 1 second delay between reading from RTM
DEFAULT_RESPONSE = "greetings: 'hello', 'hi', 'greetings', 'sup', 'what's up' / commands: 'do'"
DEFAULT_COMMAND = "do"
MENTION_REGEX = "^<#(|[WU].+?)>(.*)"
def parse_bot_commands(slack_events):
"""
parses a list of events coming from the slack rtm api to find bot commands
:param slack_events:
:return:
"""
for event in slack_events:
if event["type"] == "message" and not "subtype" in event:
user_id, message = parse_direct_mention(event["text"])
if user_id == bot_id:
return message, event["channel"]
return None, None
def parse_direct_mention(message_text):
"""
finds direct message and returns user id
:param message_text:
:return:
"""
matches = re.search(MENTION_REGEX, message_text)
# the first group contains the user name, the second group contains
# the remaining message
return (matches.group(1), matches.group(2).strip()) if matches else (None, None)
def handle_command(command, channel):
"""
executes bot command if the command is known
:param command:
:param channel:
:return:
"""
GREETING_KEYWORDS = ("hello", "hi", "greetings", "sup", "what's up",)
GREETING_RESPONSES = ["'sup brah", "hey", "*headnod*", "didjageddathingahsencha?"]
# default response is help text for the user
default_response = "Not sure what you mean. Try *{}*.".format(DEFAULT_RESPONSE)
# finds and executes the given command, filling the response
response = None
#implement more commands below this line
if command in GREETING_KEYWORDS:
response = random.choice(GREETING_RESPONSES)
else:
if command.startswith(DEFAULT_COMMAND):
response = "Sure...write some more code and I'll do that"
# Sends the response back to the channel
sc.api_call(
"chat.postMessage",
channel="#the_danger_room",
as_user="true:",
text=response or default_response)
if __name__ == "__main__":
if sc.rtm_connect(with_team_state=False):
print("Connected and running!")
#call web api method auth.test to get bot usre id
bot_id = sc.api_call("auth.test")["user_id"]
while True:
command, channel = parse_bot_commands(sc.rtm_read())
if command:
handle_command(command, channel)
time.sleep(RTM_READ_DELAY)
else:
print("Connection failed. Exception traceback printed above.")
I have some questions based on automated trading via IB using python.
I can access to TWS, but when I am request for account summary I can't put them into constant variables to use it, I only received them as an printing output.
Here my code:
from ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.opt import Connection, message
def error_handler(msg):
"""Handles the capturing of error messages"""
print "Server Error: %s" % msg
def reply_handler(msg):
"""Handles of server replies"""
print "Server Response: %s, %s" % (msg.typeName, msg)
if __name__ == "__main__":
tws_conn = Connection.create(port=4096, clientId=150)
tws_conn.connect()
tws_conn.registerAll(reply_handler)
tws_conn.reqAccountSummary(119, "All", "TotalCashValue")
time.sleep(4)
The output on the screen(cmd):
Server Response: accountSummary, <accountSummary reqId=119,
account=DU860294, tag=TotalCashValue, value=980232.77, currency=USD>
Server Response: accountSummary, <accountSummary reqId=119,
account=DUC00074, tag=TotalCashValue, value=610528.18, currency=USD>
Server Response: accountSummaryEnd, <accountSummaryEnd reqId=119>
My needed is to put all these informations into variables to use it in my program.
Thanks in advance.
You can obtain this information via updateAccountValue event too. Subscribe for this event using tws_conn.reqAccountUpdates() and you'll receive account related informations in
updateAccountValue(string key, string value, string currency, string accountName)
Then you can filter the messages like key=="TotalCashValue" and convert the value string into a double variable.
I'm working on a webhook that sends Telegrams messages to Slack and Slack messages to Telegram; right now I can send Telegram messages to Slack but I can't send from Slack to Telegram because I don't know how to get the data. As the Slack documentation states, the data sent on the POST request is like this:
token=XXXXXXXXXXXXXXXXXX
team_id=T0001
team_domain=example
channel_id=C2147483705
channel_name=test
timestamp=1355517523.000005
user_id=U2147483697
user_name=Steve
text=googlebot: What is the air-speed velocity of an unladen swallow?
trigger_word=googlebot:
The content type is application/x-www-form-urlencoded
From that data I want to get the user_name and text
On my Flask code I don't have nothing because I don't know how to receive that data or how can I see it on the console so I could try to extract it and send it to Telegram, this is the only thing that I have for the Slack webhook just because I wanted to see if it was working, I think that these lines of code are not relevant right now:
#app.route("/" + SLACK, methods=['POST'])
def slack_handler():
if request.method == "POST":
return "POST"
And that's my problem; how can I receive, store that data? if I should explain more my issue please let me know and thanks for any help.
As long as your slack webhook is configured appropriately you should be able to treat it like a form. The following should work-
from flask import Flask, request
slack_webhook = your_webhook_here
#app.route('/slack', methods=['POST'])
def slack():
if request.form.get('token') == slack_webhook:
channel = request.form.get('channel')
username = request.form.get('username')
return "Channel: " + channel + "Username: " + username
else:
return "None found"
Read this post for more on this-
realpython.com
I was trying out a Gtalk bot using python and XMPP.
When I ping the bot using iChat application, I could receive the response back.
But when I ping using Hangouts, I am not able to receive the response message. But still I could see my message at server side logs.
# -- coding: utf-8 -
import xmpp
user="BOTUSERNAME#gmail.com"
password="PASSWORD"
server=('talk.google.com', 5223)
def message_handler(connect_object, message_node):
us = str(message_node.getFrom()).split('/')[0]
if us == 'REALUSERNAME#gmail.com':
us = us[0:4]
print str(message_node)
message = "Welcome to my first Gtalk Bot :) " + us
s= str(message_node.getBody()).replace("\n", "\t")
if s <> 'None' :
print "MESSAGE: " + s
connect_object.send(xmpp.Message( message_node.getFrom() ,message))
jid = xmpp.JID(user)
connection = xmpp.Client(jid.getDomain())
connection.connect(server)
result = connection.auth(jid.getNode(), password )
connection.RegisterHandler('message', message_handler)
connection.sendInitPresence()
while connection.Process(1):
pass
Is this something to do with gtalk moving out of XMPP support?
My Bot is still able to receive message but my Hangouts Application is not receiving response
I was able to fix the issue.
You need to add typ = 'chat' attribute to xmpp.Message
connect_object.send(xmpp.Message( message_node.getFrom() ,message, typ='chat' ))
Now my gTalkBot reponds to my message from hangouts & ichat client.
Many thanks to this stack overflow answer
If you have extended sleekxmpp.ClientXMPP, then you can ensure messages are sent to hangouts by added mtype='chat' to send_message()
bot = MyBot([...])
bot.send_message(mto=JID,mbody=MSG,mtype='chat')