I've tried to create my first telegram bot hosting the code as an amazon lambda instance, i suppose i should return something to the webhook 'cause it keep saying "Wrong response from the webhook: 502 Bad Gateway".
Here is part of my code:
def msgSend(text, chat_id):
url = URL + "sendMessage?text={}&chat_id={}".format(text, chat_id)
response = requests.get(url)
content = response.content.decode("utf8")
return content
def handle(msg):
sender = msg['from']['username']
id_gruppo = msg['chat']['id']
if sender == NAME:
testo = msg['text']
usernames = [x.replace('#','') for x in rx.findall(text)]
map(foo, usernames)
msgSend(confirm_mess, id_group)
return
def main(event, context):
response = ast.literal_eval(event['body'])
handle(response['message'])
return {
'something': 'something'
}
Actually the process works fine enough, the messages are received by my lambda and everything works like a charm, except for one thing, the confirmation message is sent over and over endlessly and the webhooks never marks the messages as read.
here is the response of getWebHookInfo:
{"ok":true,"result":{"url":"https://t2rt9guj3h.execute-api.us-west-2.amazonaws.com/prod/instabot","has_custom_certificate":false,"pending_update_count":19,"last_error_date":1489331750,"last_error_message":"Wrong response from the webhook: 502 Bad Gateway","max_connections":40}}
According to the bot helper the wh requires a 2XX code response...
Any idea about that?
According to the bot helper the wh requires a 2XX code response...
This is true. Your last statement should be
return {
statusCode: 200
}
If you don't return a successful response code, Telegram won't know what to do with it, which is why you see the HTTP 502 Bad Gateway. I was hitting this for awhile also :)
Related
I'm a noobie at Python and was just messing around, but now I'm really curious why it isn't working. I'm currently trying to build a telegram bot that generates an image based on the text given to the bot. I think there might be a problem with my DeepAI api? When I click this link: https://api.deepai.org/api/text2img i always get the error
{"err": "error processing given inputs from request"}
. The bot is linked but gives me the error as in the code below. My code below:
import requests
import json
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
def text_to_image(update, context):
# Get the text from the user
text = update.message.text
# Set up the DeepAI API request
api_key = "{{ api }}"
headers = {
"api-key": api_key
}
data = {
"text": text
}
# Make the request to the DeepAI API
response = requests.post("https://api.deepai.org/api/text2img", headers=headers, json=data)
if response.status_code != 200:
update.message.reply_text("An error occurred while generating the image. Please try again later.")
return
# Get the generated image from the response
response_json = response.json()
image_url = response_json["output_url"]
# Send the generated image to the user
context.bot.send_photo(chat_id=update.effective_chat.id, photo=image_url)
def main():
# Set up the Telegram bot
updater = Updater(token="{{ api }}", use_context=True)
dispatcher = updater.dispatcher
# Add the text_to_image handler
text_to_image_handler = MessageHandler(Filters.text, text_to_image)
dispatcher.add_handler(text_to_image_handler)
# Start the bot
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()
I've tried changing code and different things but nothing seems to work, i'm really stuck right now
From the looks of it, it's an error on the API side of things. The status code of the API server depends on traffic and account/key.
Things to do:
Check if your API key is valid and wait when server works on google, then try to run your code
I have used the following guide - https://developer.ebay.com/marketplace-account-deletion
So I've created a flask based website on python and uploaded in Heroku,
https://ebay-deletion.herokuapp.com/
If you create a query parameter, for the challenge code like so:
https://ebay-deletion.herokuapp.com/?challenge_code=123
It returns a challenge response and doc type (JSON).
I don't understand but why but I get this error below:
Notification delivery failed with HTTP status code 405 from https://ebay-deletion.herokuapp.com. Please ensure that the marketplace account deletion notification endpoint is ready to receive notifications.
Any thoughts on how to solve this?
Ebay's help page is just so terrible. Their python code examples for hashing in the top link have semi-colons after each line! It's close to completely useless.
Here is the Python Flask code:
#app.route('/')
def index():
args = request.args
args_dict = args.to_dict()
try:
resp_hash = hashlib.sha256(
args_dict['challenge_code'].encode() + verification_token.encode() + endpoint.encode())
resp = {'challengeResponse': resp_hash.hexdigest()}
return jsonify(resp), 200, {'content-type': 'application/json'}
except KeyError:
err = {'status_code': 400, 'message': 'no challenge response in params'}
return jsonify(err), 400, {'content-type': 'application/json'}
I am posting a GET request to this URL with a bearer token:
http://api.viagogo.net/catalog/events?page_size=1000&sort=resource_version&min_resource_version=75939827358
It returns results in Postman as expected.
When i call the same api with same token in code (C#), i get unauthorized 401 response.
This is my code:
var eventsUri = new Uri(eventsUrl);
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
httpClient.DefaultRequestHeaders.Add("User-Agent", "App Name");
var eventResponseFromHttp = await httpClient.GetAsync(eventsUri);
var responseContent = await eventResponseFromHttp.Content.ReadAsStringAsync();
var eventsFromHttps = JsonConvert.DeserializeObject<EventResponse>(responseContent);
But the weird thing is this:
If i call the same api without sort and min_resource_version query string parameters from code, it returns the results with 200:
http://api.viagogo.net/catalog/events?page_size=1000
I have no idea whats going on here. This is happening in a .Net Framework 4.7 application.
Any help is appreciated. Thanks.
UPDATE:
The same url with same token returns 200 and results using Python.
I'm v new to creating chatbots.
import telebot
bot = telebot.TeleBot('123345677789')
def sendMessage(message, text):
bot.send_message(message.chat.id, text)
#bot.message_handler(func=lambda msg: msg.text is not None)
def reply_to_message(message):
if 'hello' in message.text.lower():
sendMessage(message, 'Hello! How are you doing today?')
else:
bot.reply_to(message,'try hi or hello')
#bot.message_handler(func=lambda msg: msg.text is not None)
def getresponse(user_input):
if 'virus' in user_input.text.lower():
url = "https://covid-19-coronavirus-statistics.p.rapidapi.com/v1/stats"
querystring = {"country":"USA"}
headers = {
'x-rapidapi-host': "covid-19-coronavirus-statistics.p.rapidapi.com",
'x-rapidapi-key': "ea33a4fd9cmshd4ead0c7290"}
response = requests.request("GET", url, headers=headers, params=querystring)
bot.reply_to(user_input,response.text)
else:
bot.reply_to(user_input,'type virus')
I've been trying to get the api to return the data. But whenever i try to send the requests, the bot doesnt remind me anything. Any help is appreciated.
Thanks!
The problem is that you have the same filter for both functions, so the first function will always take the priority and answer your messages. Your options would be: fuse both functions, delete the first function, changing from message to command one of your functions or you can try using register_next_step_handler() so you always have to salute the bot before asking for information (sounds like overkill to me).
Ok, lets go with fusing:
import telebot
import requests
bot = telebot.TeleBot(tgtoken)
def sendMessage(message, text):
bot.send_message(message.chat.id, text)
#bot.message_handler(func=lambda msg: msg.text is not None)
def getresponse(user_input):
if user_input.text.lower() in ["hello", "hi"]:
sendMessage(user_input, 'Hello! How are you doing today?')
elif 'virus' in user_input.text.lower():
url = "https://covid-19-coronavirus-statistics.p.rapidapi.com/v1/stats"
querystring = {"country":"Denmark"}
headers = {
'x-rapidapi-host': "covid-19-coronavirus-statistics.p.rapidapi.com",
'x-rapidapi-key': rapidapitoken}
response = requests.request("GET", url, headers=headers, params=querystring)
if not response.json()["error"]:
bot.reply_to(user_input,str(response.json()["data"]))
else:
bot.reply_to(user_input,"Error: {!s} , StatusCode: {!s}, Message: {!s}".format(response.json()["error"], response.json()["statusCode"], response.json()["message"]))
else:
bot.reply_to(user_input,'type hi, hello, or virus')
bot.polling()
And that's it. Ok, I cheated, I used Denmark and not USA because Denmark information is small compared to USA. But that wasn't the question, riiiiight? Well, the best way to solve it is to send the minimum information required because otherwise you will hit two limits: max characters in a message and too many requests if you split the message.
PS: Maybe the code when you show the error you get at retrieving the information from the API isn't perfect, I couldn't test it.
i've just started working with line-bot and followed the tutorial here: https://developers.line.biz/en/docs/messaging-api/building-bot/
However, I still don't understand how I can connect with my line app account, to send messages, and have these messages appear back in python.
The below is the script I copied from line tutorial.
from flask import Flask, request, abort
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage
app = Flask(__name__)
line_bot_api = LineBotApi('foo', timeout=20)
handler = WebhookHandler('bar')
user_profile = 'far'
#app.route("/", methods=['GET'])
def home():
profile = line_bot_api.get_profile(user_profile)
print(profile.display_name)
print(profile.user_id)
print(profile.picture_url)
print(profile.status_message)
return '<div><h1>ok</h1></div>'
#app.route("/callback", methods=['POST'])
def callback():
# get X-Line-Signature header value
signature = request.headers['X-Line-Signature']
# get request body as text
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
# handle webhook body
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
#handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text='hello world'))
if __name__ == "__main__":
app.run(debug=True)
What am I missing, or how can I connect with the line app to send and receive messages?
I followed that tutorial and was able to successfully create a bot that just echoes messages in uppercase:
Your question is how to "connect" your bot's code with the LINE app. The three most important parts of the tutorial are probably:
Adding the bot as a friend, you do this by scanning its QR code with the LINE app
When you create a channel for your bot, you need to enable "Webhooks" and provide an https endpoint which is where LINE will send the interaction events your bot receives. To keep this simple for the purposes of this answer, I created an AWS Lambda function and exposed it via API Gateway as an endpoint that looked something like:
https://asdfasdf.execute-api.us-east-1.amazonaws.com/default/MyLineBotFunction. This is what I entered as the Webhook URL for my bot.
Once you are successfully receiving message events, responding simply requires posting to the LINE API with the unique replyToken that came with the message.
Here is the Lambda function code for my simple yell-back-in-caps bot:
import json
from botocore.vendored import requests
def lambda_handler(event, context):
if 'body' in event:
message_event = json.loads(event['body'])['events'][0]
reply_token = message_event['replyToken']
message_text = message_event['message']['text']
requests.post('https://api.line.me/v2/bot/message/reply',
data=json.dumps({
'replyToken': reply_token,
'messages': [{'type': 'text', 'text': message_text.upper()}]
}),
headers={
# TODO: Put your channel access token in the Authorization header
'Authorization': 'Bearer YOUR_CHANNEL_ACCESS_TOKEN_HERE',
'Content-Type': 'application/json'
}
)
return {
'statusCode': 200
}