Telegram Bot receive video from user - python

i want my bot to receive videos thats been sent by users. Previously, i did this coding to receive images from users but i still cant use my bot to receive videos from them. Can any of you help me solve this problem?
coding:
file = update.message.photo[-1].file_id

At first place telegram can recieve two types of videos: simple videofile, that was sent by user as attachment and "video_note" - video that was created directly in the telegram.
Recieving both these types are pretty similar:
At first we need to obtain file_id:
def GetVideoNoteId(update):
if update['message'].get('video_note') != None:
return update['message']['video_note']['file_id']
else:
return 'not videonote'
second step - getting filepath of that file on telegram servers - from where we should download that file:
def GetVideoNoteFileSource(FileId):
url = 'https://api.telegram.org/bot' + TOKEN + '/' + 'getFile'
jsn = {'file_id': FileId}
r = requests.get(url,json=jsn).json()
fileSource = r['result']['file_path']
return fileSource
And third - finally - getting this file:
def GetFile(fileSource):
url = 'https://api.telegram.org/file/bot' + TOKEN + '/' + fileSource
r = requests.get(url)
filename = 'Video.mp4'
try:
with open(filename, 'wb') as file:
file.write(r.content)
return 'file dowloaded'
except:
return 'there are something wrong'
With videofile as attachments similar, but
return update['message']['video_note']['file_id'] - would be looks different (i do not remmember)

Related

Get Spotify access token with spotipy on Django and Python

I'm new to Django and I'm trying to link Spotify to my webapp. I'm using Spotify to do it and it correctly access to Spotify.
To do it I have a button that opens the view below
views.py
#authenticated_user
def spotify_login(request):
sp_auth = SpotifyOAuth(client_id=str(os.getenv('SPOTIPY_CLIENT_ID')),
client_secret=str(os.getenv('SPOTIPY_CLIENT_SECRET')),
redirect_uri="http://127.0.0.1:8000/",
scope="user-library-read")
redirect_url = sp_auth.get_authorize_url()
auth_token = sp_auth.get_access_token()
print(auth_token)
print("----- this is the AUTH_TOKEN url -------", auth_token)
return HttpResponseRedirect(redirect_url)
If I don't use auth_token = sp_auth.get_access_token() everything works fine and I got redirected to the correct. Unfortunately, if I add that line of code to access the access token, instead of staying on the same page, it opens another tab on the browser with the Spotify auth_code and lets the original page load forever.
Is there a way to retrieve the access token in the background without making my view reload or open another tab in the browser?
You are being redirected to exactly where you are telling django to go.
redirect_url is just a spotify api redirect containing a code, which is captured and used to get the access token.
Set your expected response as return value.
By the way, keep in mind:
redirect_uri="http://127.0.0.1:8000/", should be added in spotify app (usually as http://127.0.0.1:8000/callback",)
auth_token is a json, you can find token in auth_token['access_token']
The solution was to create a new view to access the URL
views.py
from .utils import is_user_already_auth_spotify, spotify_oauth2
#authenticated_user
def spotify_login(request):
if is_user_already_auth_spotify(request.user.username):
messages.error(request, "You have already linked your Spotify account")
return HttpResponseRedirect('account/' + str(request.user.username))
sp_auth = spotify_oauth2()
redirect_url = sp_auth.get_authorize_url()
return HttpResponseRedirect(redirect_url)
#authenticated_user
def spotify_callback(request):
full_path = request.get_full_path()
parsed_url = urlparse(full_path)
spotify_code = parse_qs(parsed_url.query)['code'][0]
sp_auth = spotify_oauth2()
token = sp_auth.get_access_token(spotify_code)
data = {
str(request.user.username): token
}
with open('spotify_auth.json', 'w') as f:
json.dump(data, f)
messages.success(request, "You have correctly linked your Spotify account")
return HttpResponseRedirect('account/' + str(request.user.username))
urls.py
urlpatterns = [
path('account/<str:username>/', views.account_user, name="account"),
path('spotify_login', views.spotify_login, name="spotify_login"),
path('spotify_callback', views.spotify_callback, name="spotify_callback"),
]
utils.py
import json
from spotipy import oauth2
import os
def is_user_already_auth_spotify(username):
my_loaded_dict = {}
with open('spotify_auth.json', 'r') as f:
try:
my_loaded_dict = json.load(f)
except:
# file vuoto
pass
if str(username) in my_loaded_dict:
# controllare scadenza token ed in caso rinnovarlo
return True
else:
return False
def spotify_oauth2():
sp_auth = oauth2.SpotifyOAuth(client_id=str(os.getenv('SPOTIPY_CLIENT_ID')),
client_secret=str(os.getenv('SPOTIPY_CLIENT_SECRET')),
redirect_uri="http://127.0.0.1:8000/members/spotify_callback",
scope="user-library-read")
return sp_auth
The code also saves the token in a JSON and search for it if it has already been saved

Unable to send file to Telegram Channel

Error below:
Failed to convert James Blake - Never Dreamed.mp4 to media. Not an existing file, an HTTP URL or a valid bot-API-like file ID
Function that I am running is here.
async def gramain():
# Getting information about yourself
me = await bott.get_me()
print(me.stringify())
filesww = os.listdir('media').pop()
now = os.getcwd()
mediadir = now + "/media/"
vid = open(mediadir+filesww, 'r')
# await bot.send_message(chat, 'Hello, friend!')
await bott.send_file(chat, filesww, video_note=True)
I trying to use this function from the library Telethon.
https://docs.telethon.dev/en/latest/modules/client.html#telethon.client.uploads.UploadMethods.send_file
I am unable to find out what the issue is. Please help!

How to send photo on telegram bot

i'm just implementing a simple bot who should send some photos and videos to my chat_id.
Well, i'm using python, this is the script
import sys
import time
import random
import datetime
import telepot
def handle(msg):
chat_id = msg['chat']['id']
command = msg['text']
print 'Got command: %s' % command
if command == 'command1':
bot.sendMessage(chat_id, *******)
elif command == 'command2':
bot.sendMessage(chat_id, ******)
elif command == 'photo':
bot.sendPhoto(...)
bot = telepot.Bot('*** INSERT TOKEN ***')
bot.message_loop(handle)
print 'I am listening ...'
while 1:
time.sleep(10)
In the line bot.sendphoto I would insert the path and the chat_id of my image but nothing happens.
Where am I wrong?
thanks
If you have local image path:
bot.send_photo(chat_id, photo=open('path', 'rb'))
If you have url of image from internet:
bot.send_photo(chat_id, 'your URl')
Just using the Requests lib you can do it:
def send_photo(chat_id, file_opened):
method = "sendPhoto"
params = {'chat_id': chat_id}
files = {'photo': file_opened}
resp = requests.post(api_url + method, params, files=files)
return resp
send_photo(chat_id, open(file_path, 'rb'))
I have used the following command while using python-telegram-bot to send the image along with a caption:
context.bot.sendPhoto(chat_id=chat_id, photo=
"url_of_image", caption="This is the test photo caption")
I've tried also sending from python using requests. Maybe it's late answer, but leaving this here for others like me.. maybe it'll come to use..
I succeded with subprocess like so:
def send_image(botToken, imageFile, chat_id):
command = 'curl -s -X POST https://api.telegram.org/bot' + botToken + '/sendPhoto -F chat_id=' + chat_id + " -F photo=#" + imageFile
subprocess.call(command.split(' '))
return
This is complete code to send a photo in telegram:
import telepot
bot = telepot.Bot('______ YOUR TOKEN ________')
# here replace chat_id and test.jpg with real things
bot.sendPhoto(chat_id, photo=open('test.jpg', 'rb'))
You need to pass 2 params
bot.sendPhoto(chat_id, 'URL')
sendPhoto requires at least two parameters; first one is target chat_id, and for second one photo you have three options:
Pass file_id if the photo is already uploaded to telegram servers (recommended because you don't need to reupload it).
If the photo is uploaded somewhere else, pass the full http url and telegram will download it (max photo size is 5MB atm).
Post the file using multipart/form-data like you want to upload it via a browser (10MB max photo size this way).

Is there any way of getting instagram User _ID without using the instagram API?

My task is NOT to generate any application or website but just to write a PYTHON script which gives usernames as an input and retrieve User ID as a result.
As instagram asks for Application name, website, URI and all other stuff to be able to receive a client ID and other things to be able to use their API and I don't have an application as such, I don't qualify for it.
So is there any way we can do it without the Instagram API?
If there is no other way, how to work for it?
Also I am new to python programming and connecting with API and all. It would be really helpful if someone would help me with a code to do so.
Thanks!
Well the answer to the question is we can use the Instagram API itself. As #Selcuk said, we can register using placeholders in the Instagram site. So then we will get the client_id and client_secret from it and also if we are registered instagram user, we will get the access token too.
The access token if hard to find, can be achieved by going to https://apigee.com/console/instagram
and then in the authentication option on the top, select OAuth which will take you to the login page of instagram. After sending the query it will show you what request you made and can find the access token too.
In the python console just type:-
import urllib.request
import urllib.parse
from instagram.client import InstagramAPI
access_token="YOUR ACCESS TOKEN&q"
api=InstagramAPI(client_id= 'YOUR CLIENT ID', client_secret='YOUR CLIENT SECRET')
scope='public_content'
url='https://api.instagram.com/v1/users/search?q=USERNAME TO SEARCH&access_token=YOUR ACCESS TOKEN'
a=urllib.request.urlopen(url)
print(a.read())
This will give you the details about the user.
I put this code together below (python 3.5.2) only using urllib and it works like a dream!
from six.moves.urllib.request import urlopen
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
id_loop = True
while id_loop == True:
username = input('Please enter the Instagram username that you would like to find the User ID for: ')
link = 'http://www.instagram.com/' + username
response = urlopen(link)
content = str(response.read());
start_index = (content.index('"owner": {"id": "')) + len('"owner": {"id": "')
test_string = ''
for collect in range(14):
test_string = test_string + content[start_index]
start_index = start_index + 1
edit_string = ''
for char in test_string:
if is_number(char) == True:
edit_string = edit_string + char
else:
edit_string = edit_string + ''
print(username + "'s Instagram ID = " + edit_string)
As you can see, the only module that you need is urllib. This code essentially finds the Instagram page of the username that you input and sets the variable content equal to a single string consisting of the entire html code of the webpage. This string is then searched by the code to find the users Instagram ID. Hope this helps!
Guess things in code change but life's challenges stay...
here we go.... some neat python code to make things easier!
python function username to id
from six.moves.urllib.request import urlopen
def get_insta_id(username):
link = 'http://www.instagram.com/' + username
response = urlopen(link)
content = str(response.read())
start_pos = content.find('"owner":{"id":"') + len('"owner":{"id":"')
end_pos = content[start_pos:].find('"')
insta_id = content[start_pos:start_pos+end_pos]
return insta_id
print(get_insta_id("username"))

uploading file contents in python takes a long time

I'm trying to upload files with the following code:
url = "/folder/sub/interface?"
connection = httplib.HTTPConnection('www.mydomain.com')
def sendUpload(self):
fields = []
file1 = ['file1', '/home/me/Desktop/sometextfile.txt']
f = open(file1[1], 'r')
file1.append(f.read())
files = [file1]
content_type, body = self.encode_multipart_formdata(fields, files)
myheaders['content-type'] = content_type
myheaders['content-length'] = str(len(body))
upload_data = urllib.urlencode({'command':'upload'})
self.connection.request("POST", self.url + upload_data, {}, myheaders)
response = self.connection.getresponse()
if response.status == 200:
data = response.read()
self.connection.close()
print data
The encode_multipart_formdata() comes from http://code.activestate.com/recipes/146306/
When I execute the method it takes a long time to complete. In fact, I don't think it will end.. On the network monitor I see that data is transferred, but the method doesn't end...
Why is that? Should I set a timeout somewhere?
You don't seem to be sending the body of your request to the server, so it's probably stuck waiting for content-length bytes to arrive, which they never do.
Are you sure that
self.connection.request("POST", self.url + upload_data, {}, myheaders)
shouldn't read
self.connection.request("POST", self.url + upload_data, body, myheaders)
?

Categories

Resources