Add a photo to an existing message python telebot - python-3.x

For example, I have an existing message created by
bot.send_message(message.chat_id, "Hello, world!")
Then I changed it in callback_query_handler as follows
bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text="Hello, Stackoverflow!", reply_markup=tutors_markup, parse_mode = 'Markdown')
After that I do some manipulations. And then I need to add a photo to the message with "Hello, Stackoverflow!".
How can i do it?
(I use telebot library)
I was trying to edit by
photo = open(f'photo_{result[0]}.jpg', 'rb')
bot.edit_message_media(media=telebot.types.InputMedia(type='photo', media=photo, caption = "noitpac"), chat_id=call.message.chat.id, message_id=call.message.message_id)
But got
telebot.apihelper.ApiTelegramException: A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: there is no media in the message to edit
And I understand this error, but don't what to do.

Related

What's the right way to execute a Twilio Studio conversation flow?

Im learning how to set a twilio studio flow with python, I'm currently testing one of the templates that Twilio provides, and Im communicating with the bot from WhatsApp. However, I can only send the first message of the flow and if I send another message, this message pop up:
Unable to create record: Execution XXXXXXXXXXXXXXXXXXXXX is already active for this contact. End the active Execution before creating a new one
I tried to add .update(status='ended') to my variable, but it just kinda looped every time I sent a message, I know that every time that theres an incoming message it will trigger the conversation. So my question is, how can I continue the conversation flow without creating a new trigger every time that theres an incomming message?
Here's my flow in case it's necessary.
And this is the functions and endpoints that I'm using to trigger the action:
# twilio.route('/incoming_message', methods=['GET', 'POST'])
def incoming_message_data() -> str:
if request.method == 'POST':
response = {}
error, message, code = False, '', ''
message = incoming_message()
response.update({'sucess': True, 'message': message, 'message': f'{message}', 'status_code': 200, 'error': None, 'code': f'{code}'} if message and message != [{}]else {
'sucess': False, 'message': 'Message could not be sent', 'status_code': 400, 'error': f'{error}', 'code': f'{code}'})
return message
def twilio_studio_flow(phone_number: str) -> str:
'''
Twilio Studio Flow
'''
response = request.values.get('Body', '').lower()
execution = twilio_client.studio \
.v2 \
.flows(Config.TWILIO_STUDIO_FLOW_SID) \
.executions \
.create(to=(f'whatsapp:{phone_number}'), from_=Config.TWILIO_PHONE_NUMBER,
parameters={
"appointment_time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
})\
.update(status='ended')
def validate_phone_number(phone_number: str) -> bool:
'''
Validate phone number
'''
try:
phone = phonenumbers.parse(phone_number.strip(), None)
client = Client.query.filter_by(phone=phone_number).first()
return phonenumbers.is_valid_number(phone) and client is not None
except Exception:
return False
def incoming_message() -> str:
'''
Receive incoming messages
'''
# Get the message the user sent our Twilio number
incoming_message = request.values.get('Body', '').lower()
# Get the phone number of the person sending the text message
phone_number = request.values.get('From', None).replace('whatsapp:', '')
resp = MessagingResponse()
if validate_phone_number(phone_number) and incoming_message:
resp.message(twilio_studio_flow(phone_number))
else:
resp.message(
'Lo sentimos, no pudimos validar tu numero de telefono 😟')
return str(resp)
Thanks in advance for helping me :).
As I mentioned previously, I want to know the right way to execute a Twilio Studio. Honestly, I cheked the docs but it's a little bit unclear on how to this.
Based on your answer in the comments, I'd suggest to link the Studio flow directly to the WhatsApp sender in the console (instead of invoking the flow manually via the API).
To connect the Studio Flow to your WhatsApp number ("Sender"). Click on the Trigger (Start) Widget and locate the Webhook URL field in the right-hand menu. Copy that URL to your clipboard.
Next, navigate to your WhatsApp Senders in the Twilio console. Click to select the sender that you want to use with this Studio Flow. Paste the Webhook URL that you copied from your Studio Flow into the field Webhook URL for incoming messages. Don't forget to click Update WhatsApp Sender.
Now, any time you receive an inbound message on your selected WhatsApp-enabled sender (number), it will be routed to your new Studio Flow.
Taken from the documentation.

send message from bot to direct message after typing /slash command

I'm trying to make SlackBot and if I call him in some public channel it works fine but when I call him (type slash-command) in any direct channel I receive "The server responded with: {'ok': False, 'error': 'channel_not_found'}". In public channels where I've invited my bot it works fine, but if I type "/my-command" in any DM-channel I receive response in separate DM-channel with my bot. I expect to receive these responses in that DM-channel where I type the command.
Here is some part of my code:
if slack_command("/command"):
self.open_quick_actions_message(user_id, channel_id)
return Response(status=status.HTTP_200_OK)
def open_quick_actions_message(self, user, channel):
"""
Opens message with quick actions.
"""
slack_template = ActionsMessage()
message = slack_template.get_quick_actions_payload(user=user)
client.chat_postEphemeral(channel=channel, user=user, **message)
Here are my Event Eubscriptions
Here are my Bot Token Scopes
Can anybody help me to solve this?
I've already solved my problem. Maybe it will help someone in the future. I've sent my payload as the immediate response as it was shown in the docs and the response_type by default is set to ephemeral.
The part of my code looks like this now:
if slack_command("/command"):
res = self.slack_template.get_quick_actions_payload(user_id)
return Response(data=res, status=status.HTTP_200_OK)
else:
res = {"text": "Sorry, slash command didn't match. Please try again."}
return Response(data=res, status=status.HTTP_200_OK)
Also I have an action-button and there I need to receive some response too. For this I used the response_url, here are the docs, and the requests library.
Part of this code is here:
if action.get("action_id", None) == "personal_settings_action":
self.open_personal_settings_message(response_url)
def open_personal_settings_message(self, response_url):
"""
Opens message with personal settings.
"""
message = self.slack_template.get_personal_settings_payload()
response = requests.post(f"{response_url}", data=json.dumps(message))
try:
response.raise_for_status()
except Exception as e:
log.error(f"personal settings message error: {e}")
P. S. It was my first question and first answer on StackOverflow, so don't judge me harshly.

Trying to send emails with Gmail API

I've been followning tutorials and reading articles trying to learn how to make sense of the gmail API using python 3.
I've gotten stuck on the messages.send method.
My authentication works but my CreateMessage function is throwing an error.
Here is my code so far:
def CreateMessage(sender, to, subject, message_text):
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.urlsafe_b64encode(message.as_bytes())}
message = CreateMessage('xxxxxxxx#gmail.com','xxxxxxxx#gmail.com','subject','message text')
service = build('gmail', 'v1', credentials=creds)
created_message = service.users().messages().send(userId='me', body=message).execute()
The error it's throwing is "TypeError: Object of type bytes is not JSON serializable"
Any and all contrusctive criticism is welcome. Or any quality tutorials on the subject you can direct me to! Thank you.
base64.urlsafe_b64encode returns a bytes object. You should convert this to a string with .decode("utf-8"), which should fix your error.

Python -GTTS-Twilio - text message mp3

I am attempting to use gtts to generate an audio file of text I am passing in as a variable ( eventually I will be scraping the text to be read, but not in this script, that is why I am using a variable) and I want to text myself the .mp3 file I am generating. It is not working though - here is my code. Any idea how to text message an .mp3 file with twilio?
import twilio
from gtts import gTTS
from twilio.rest import Client
accountSID = '********'
authToken = '****************'
twilioCli = Client(accountSID, authToken)
myTwilioNumber = '*******'
myCellPhone = '*****'
v = 'test'
#add voice
tts = gTTS(v)
y = tts.save('hello.mp3')
message = twilioCli.messages.create(body = y, from_=myTwilioNumber, to=myCellPhone)
this is the error i get, but the link it directs me to does not speak to texting mp3 audio files:
raise self.exception(method, uri, response, 'Unable to create record')
twilio.base.exceptions.TwilioRestException:
[31m[49mHTTP Error[0m [37m[49mYour request was:[0m
[36m[49mPOST /Accounts/********/Messages.json[0m
[37m[49mTwilio returned the following information:[0m
[34m[49mUnable to create record: The requested resource /2010-04-01/Accounts/********/Messages.json was not found[0m
[37m[49mMore information may be available here:[0m
[34m[49mhttps://www.twilio.com/docs/errors/20404[0m
Twilio developer evangelist here.
You can't send an mp3 file as the body of a text message. If you do send a body, it should be a string.
You can deliver mp3 files as media messages in the US and Canada. In this case you need to make the mp3 file available at a URL. Then you set that URL as the media_url for the message, like this:
message = twilioCli.messages.create(
from_=myTwilioNumber,
to=myCellPhone,
media_url="http://example.com/hello.mp3"
)
I recommend reading through the documentation on sending media via MMS and what happens to MIME types like mp3 in MMS.

Usage of a node module to post media on Instagram

I have found this module : https://www.npmjs.com/package/instagram-private-api
I wanted to know if it was legal to post on instagram using an api.
Because the documentation only show GET method and not post
i don't know if it's legal but here is your code ( pip install instabot )
from instabot import Bot
name = input("Image name + extensions : ")
bot = Bot()
bot.login(username = "user_name",
password = "user_password")
bot.upload_photo(name,
#Put the photo in the same directory as this code
caption ="YOURCAPTION")

Resources