Send text message via python to the Telegram Bot - python

I have been trying since the morning but earlier there were errors, so i had the direction but now there is no error and even not a warning too..
How code looks like :
import requests
def send_msg(text):
token = "TOKEN"
chat_id = "CHATID"
url_req = "https://api.telegram.org/bot" + token + "/sendMessage" + "?chat_id=" + chat_id + "&text=" + text
results = requests.get(url_req)
print(results.json())
send_msg("hi there 1234")
What is expected output :
It should send a text message
What is the current output :
It prints nothing
It would be great help is someone helps, Thank you all
Edit : 2
As the below dependancies were not installed, it was not capable of sending the text .
$ pip install flask
$ pip install python-telegram-bot
$ pip install requests
Now can somebody help me with sendPhoto please? I think it is not capable of sending image via URL, Thank you all
**Edit 3 **
I found a image or video sharing url from here but mine image is local one and not from the remote server

There is nothing wrong with your code. All you need to do is proper indentation.
This error primarily occurs because there are space or tab errors in
your code. Since Python uses procedural language, you may experience
this error if you have not placed the tabs/spaces correctly.
Run the below code. It will work fine :
import requests
def send_msg(text):
token = "your_token"
chat_id = "your_chatId"
url_req = "https://api.telegram.org/bot" + token + "/sendMessage" + "?chat_id=" + chat_id + "&text=" + text
results = requests.get(url_req)
print(results.json())
send_msg("Hello there!")
To send a picture might be easier using bot library : bot.sendPhoto(chat_id, 'URL')
Note : It's a good idea to configure your editor to make tabs and spaces visible to avoid such errors.

This works for me:
import telegram
#token that can be generated talking with #BotFather on telegram
my_token = ''
def send(msg, chat_id, token=my_token):
"""
Send a mensage to a telegram user specified on chatId
chat_id must be a number!
"""
bot = telegram.Bot(token=token)
bot.sendMessage(chat_id=chat_id, text=msg)

Here is an example that correctly encoded URL parameters using the popular requests library. This is a simple method if you simply want to send out plain-text or Markdown-formatted alert messages.
import requests
def send_message(text):
token = config.TELEGRAM_API_KEY
chat_id = config.TELEGRAM_CHAT_ID
url = f"https://api.telegram.org/bot{token}/sendMessage"
params = {
"chat_id": chat_id,
"text": text,
}
resp = requests.get(url, params=params)
# Throw an exception if Telegram API fails
resp.raise_for_status()
For full example and more information on how to set up a Telegram bot for a group chat, see README here.
Below is also the same using asyncio and aiohttp client, with throttling the messages by catching HTTP code 429. Telegram will kick out the bot if you do not throttle correctly.
import asyncio
import logging
import aiohttp
from order_book_recorder import config
logger = logging.getLogger(__name__)
def is_enabled() -> bool:
return config.TELEGRAM_CHAT_ID and config.TELEGRAM_API_KEY
async def send_message(text, throttle_delay=3.0):
token = config.TELEGRAM_API_KEY
chat_id = config.TELEGRAM_CHAT_ID
url = f"https://api.telegram.org/bot{token}/sendMessage"
params = {
"chat_id": chat_id,
"text": text,
}
attempts = 10
while attempts >= 0:
async with aiohttp.ClientSession() as session:
async with session.get(url, params=params) as resp:
if resp.status == 200:
return
elif resp.status == 429:
logger.warning("Throttling Telegram, attempts %d", attempts)
attempts -= 1
await asyncio.sleep(throttle_delay)
continue
else:
logger.error("Got Telegram response: %s", resp)
raise RuntimeError(f"Bad HTTP response: {resp}")

Related

Python Telegram Bot answer

How can I get response from Telegram bot and get some information to answer from local file? I wrote code below, but part with current_status doesn't work.
Could you please tell me why it doesn't work?
import telebot
import requests
url = "https://link.com"
bot = telebot.TeleBot('TOKEN')
#bot.message_handler(content_types=['text'])
def get_text_messages(message):
if message.text == "Status" or "status":
bot.send_message(message.from_user.id, curl_request())
def current_status():
with open('current_status.log') as file:
status = str(file.readline())
return status
def curl_request():
resp = requests.get(url)
if resp.status_code == 200:
return("Available \n", current_status())
else:
return("Isn't available \n", current_status())
bot.polling(none_stop=True, interval=0)
I mean, I getting answer from bot in Telegram just Available or Isn't available without text from my file which I open in current_status function.
bot.send_message() takes text as its second parameter, but your function curl_request() returns tuple.
Can you try make it return "Available \n" + current_status()?

Telegram Bot not responding after 3rd function call

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.

Webhook status code 400: {"embeds": ["Must be 10 or fewer in length."]}

I´m developing a bot that sends messages to the discord channel every second, however when I run the program and only sent 10 messages and after only print [1/1] Webhook status code 400: {"embeds": ["Must be 10 or fewer in length."]}. I don't find why is this happening, I'm using discord_webhook library and python to do this. Here is my code
async def __scrape_api(session, pid):
async with session.get(API_URL + pid) as response:
data = await response.json()
print(f"scrape {data}")
if not __search_product(pid):
name = data["name"]
image_url = data['skus'][0]['image']
for size in data['skus']:
if size['available']:
print("sent")
message = DiscordEmbed(title=f'{name}', url=f'{PRODUCT_URL_0}{size["sku"]}{PRODUCT_URL_1}',
description=f'talla: {size["dimensions"]["Tallas Calzado"]}\nPrecio: {size["bestPriceFormated"]}')
message.set_thumbnail(url=image_url)
message.set_timestamp()
webhook.add_embed(message)
response = webhook.execute()
time.sleep(1)
# save to database
__insert_new_product(pid, name, image_url, data['available'])
I found the solution for this after few minutes of taking a deeper look inside it's code. Basically each embed you send over is being held in the webhook object, once you made 10 requests with embeds then it gives you that error. All you have to do is:
webhook.execute(remove_embeds=True)

Discord - Send messages from a channel to my website in real time

I currently have a python/django platform and a discord community. On my discord server there is a channel "announcements". I would just like that when a message is published in this channel, it goes up to my website in real time. This is in order to convert it into a notification.
Currently I managed to upload the messages from the channel to my site in a simple way but not in real time:
def discord_get_last_message_id():
message_id = 0
try:
message_id = Notification.objects.latest('id').discord_message_id
except:
pass
return message_id
def get_channel_messages():
#load last id discord message in DB
last_message_id = discord_get_last_message_id()
#Base route
route = "/channels/"+ DISCORD_CHANNEL_ANNONCES_ID +"/messages"
#if first time to DB, load just one item
if last_message_id == 0:
add = "?limit=1"
else:
add = "?after="+last_message_id
route = route + add
data,error_message = request_discord('GET',route)
print(data)
def request_discord(method,url_access,body={}):
data =''
#Call token
error_message = ''
access_token = discord_get_token()
#Call request
headers = {'Authorization': access_token}
body = body
if method=="GET":
result = requests.get(DISCORD_BASE_URI + url_access, headers=headers)
else:
result = requests.post(DISCORD_BASE_URI + url_access, headers=headers,data=body)
#Check result
if result.status_code != 200 and result.status_code != 201:
error_message = "Impossible de d'obtenir un resultat erreur: " + str(result.status_code)
else:
data = result.json()
return data,error_message
def discord_get_token():
return DISCORD_ANNONCES_CHANNEL_TOKEN
I'm trying to understand how discord websockets work but I have the impression that it's made to communicate with a bot only.
My question is, which way should I go to get the messages from my discord channel to my website in real time? Do I have to go through a bot?
NOTE: the goal is to get his messages to make notifications on my platform.
Thanks for your answers !
To answer your question:
My question is, which way should I go to get the messages from my discord channel to my website in real time? Do I have to go through a bot?
The best way would be to use a bot. This is the simplest, yet best way to do accomplish what you want. You could use a on_message event to get messages when they are sent. Then you could use that message and update your website. An example of how to do this is:
#bot.event
async def on_message(message):
message_content = message.content
return
You can do whatever you want with message_content. For your purpose you might want to store it in a database.
For the website side, you could use JavaScript to get the messages from the DB and update the HTML accordingly.

How to work with slackbot in python?

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.")

Categories