How can I get a list of all bots registered with BotFather? - api

My task is to get a list of all user bots, after authorization in the telegram client through the API. I looked in the documentation for a specific method, but did not find it. Can someone tell me how this can be done, and is it possible at all?

I don't think there's a direct API for that unfortunately. But consider automating the interaction with the BotFather to gather the list programmatically.
Here is a sample script in Telethon
from telethon import TelegramClient, events
API_ID = ...
API_HASH = "..."
client = TelegramClient('session', api_id=API_ID, api_hash=API_HASH)
bots_list = []
#client.on(events.MessageEdited(chats="botfather"))
#client.on(events.NewMessage(chats="botfather"))
async def message_handler(event):
if 'Choose a bot from the list below:' in event.message.message:
last_page = True
for row in event.buttons:
for button in row:
if button.text == '»':
last_page = False
await button.click()
elif button.text != '«':
bots_list.append(button.text)
if last_page:
print(bots_list)
await client.disconnect()
exit(0)
async def main():
await client.send_message('botfather', '/mybots')
with client:
client.loop.run_until_complete(main())
client.run_until_disconnected()
a sample run would print all the bots from botfather:
['#xxxxxBot', '#xxxxxBot', … ]

Related

await in a python for loop never finishing

I'm trying a new thing for me, using playwright in google colab.
this combination requires/forces async programming.
I've got a context manager which is able to handle the login and logout called "Login". That works great!
The internal page I'm trying to get to has datasets, with no links, just div's to click on.
the locator (I believe) is working fine and should return multiple elements when combined with .element_handles() I'm assuming.
from playwright.async_api import async_playwright
import asyncio
from IPython.display import Image
import nest_asyncio
nest_asyncio.apply()
# browser is set to webkit in the Login() context manager
...
async def loop_over_datasets(browser=None, page=None):
print("starting")
datasets = page.locator("div.horizontal.clickable")
print("continuing")
datasets = await asyncio.gather(datasets.element_handles())
for ds in datasets:
print(f'inside the loop, ds is {ds}')
print("doesn't get here in tact")
# for each dataset I want to launch a new page where the dataset is clicked but I'll settle for sync programming at this point.
# new_page = await ds.click()
# ds_page = await browser.new_page(new_page)
# ds_page.click()
async def get_all_new_info():
async with Login() as (b,l):
await loop_over_datasets(browser=b,page = l)
asyncio.run(get_all_new_info()) #has to be killed manually or it will run forever.
In the line datasets = await asyncio.gather(datasets.element_handles()) gather() doesn't actually work without await and await never returns
which means I don't get "inside the loop...".
without await I get the "ds" variable but it's not anything I can do something with.
How is this supposed to be used?
Without full code it's a little bit hard to test but wanted to share few things that may help:
datasets = await asyncio.gather(datasets.element_handles())
As far as I can see in Playwright documentation element_handles() returns <List[ElementHandle]> and your are trying to pass this list to asyncio.gather which needs awaitable objects which are coroutines, Tasks, and Futures and probably thats why it's not working, so I would just done
datasets = datasets.element_handles()
Now, I assume you'd like to go through those datasets in an asynchronous manner. You should be able to put the content of the for loop into a coroutine and based on that create tasks that will be executed by gather.
async def process_dataset(ds):
new_page = await ds.click()
ds_page = await browser.new_page(new_page)
ds_page.click()
tasks = []
for ds in datasets:
tasks.append(asyncio.create_task(process_dataset(ds)))
await asyncio.gather(*tasks)

Sensenet: Check Out Documents on Upload

When a user upload a document to a document library is possible to this documents automatically remain in the "Check Out" state?
Check the /Root/System/SystemPlugins/Portlets/IntraUploadDialog.ascx. There's a huge Javascript to handle the upload process. You can add additional functionality after upload in the fileupload's done branch.
$('#sn-upload-fileupload').fileupload({
...
done: function (e, data) {
inProgress = false;
var json = (data.jqXHR.responseText) ? jQuery.parseJSON(data.jqXHR.responseText) : data.result;
$('.sn-upload-bar', data.context).addClass('sn-upload-uploadedbar');
var filename = json.Name;
var url = json.Url;
$('.sn-upload-filetitle', data.context).html('' + filename + '');
SN.Upload.uploadFinished(data.formData.ChunkToken);
**//call an action or add custom functionality**
}
});
There are built-in odata actions in Sense/Net with which you can call actions trough ajax and there's an action for checking-out content.
http://wiki.sensenet.com/Built-in_OData_actions_and_functions#Check_out_action_-_from_version_6.3

What is the right way to post image to REST API and gather data with Falcon library?

I try to post an image to process it through my REST API. I use falcon for the backend but could not figure out how to post and receive the data.
This is how I currently send my file
img = open('img.png', 'rb')
r = requests.post("http://localhost:8000/rec",
files={'file':img},
data = {'apikey' : 'bla'})
However at the Falcon repo they say that Falcon does not support HTML forms to send data instead it aims full scope of POSTed and PUTed data which I do not differentiate POSTed image data and the one sent as above.
So eventually, I like to learn what is the right workaround to send a image and receive it by a REST API which is supposedly written by Falcon. Could you give some pointers?
For this you can use the following approach:
Falcon API Code:
import falcon
import base64
import json
app = falcon.API()
app.add_route("/rec/", GetImage())
class GetImage:
def on_post(self, req, res):
json_data = json.loads(req.stream.read().decode('utf8'))
image_url = json_data['image_name']
base64encoded_image = json_data['image_data']
with open(image_url, "wb") as fh:
fh.write(base64.b64decode(base64encoded_image))
res.status = falcon.HTTP_203
res.body = json.dumps({'status': 1, 'message': 'success'})
For API call:
import requests
import base64
with open("yourfile.png", "rb") as image_file:
encoded_image = base64.b64encode(image_file.read())
r = requests.post("http://localhost:8000/rec/",
data={'image_name':'yourfile.png',
'image_data':encoded_image
}
)
print(r.status_code, r.reason)
I hope this will help.

Get tagged photo without access token

I have some problem on this. Can I get public tagged photo from Instagram api without getting any code or access token?
Please share any link for reading because I cannot found any. I feel it is less knowledge about Instagram api on web.
Thanks!
You can pull public media by tag without authentication.
Take a look at the API documentation for the get /tags/tag-name/media/recent endpoint. Here's the URL: http://instagram.com/developer/endpoints/tags/#get_tags_media_recent
The documentation can be confusing, it shows using an access_token for this endpoint in the example, but it is not required. You will need to register an application and get a client ID.
I use MeteorJS and call a method server side that returns essentially the 'view source' of the instagram page. So if you can run a server side scrape on the tag url you will be able to handle the response with what i have below and it will push all the images into an array.
//server side method
Meteor.methods({
'scrapeInst':function(tag){
return Scrape.url('https://www.instagram.com/explore/tags/'+tag+'/')
}})
//client side logic
Meteor.call('scrapeInst',Session.get('params').tag,function(err,resp){
var theInstResp = resp;
cleanOne = resp.replace(/>|window._sharedData = |;</|;|#47;|<|/g,'').split('script')
var splitter = cleanOne[22].split(',');
var theArr = [];
_.each(splitter,function(e){
var theFinal = {};
var theS = e.split(":");
if(theS[0].replace(/"| |/g,'') === "display_src"){
theFinal[theS[0].replace(/"| |/g,'')] = theS[2].replace(/%22/g,'');
theArr.push(theFinal)
}
});
Session.set('photos',theArr);
setTimeout(function(){
Session.set('loading',false)
},1000)
})

Getting LinkedIn Profile Picture

Is there an easy way to grab a users LinkedIn profile photo?
Ideally similar to how you would with Facebook - http://graph.facebook.com/userid/picture
You can retrieve the original photo size with this call:
http://api.linkedin.com/v1/people/~/picture-urls::(original)
Note that this could be any size, so you'll need to do scaling on your side, but the image is the original one uploaded by the user.
Not as easy... You need to go through OAuth, then on behalf of the member, you ask for:
http://api.linkedin.com/v1/people/{user-id}/picture-url
If you use the 2.0 version of the API (all developers need to migrate by March 1, 2019), you should use projections to expand the profilePicture.displayImage. If you do this, you will have a full JSON element displayImage~ (the '~' is not a typo) inside profilePicture with all the info you may need.
https://api.linkedin.com/v2/me?projection=(id,profilePicture(displayImage~:playableStreams))
You can see more at the Profile Picture API doc to look at the JSON response or the Profile API doc.
Once the Linkedin user authentication using OAuth 2.x is done, make a request to the people URL.
https://api.linkedin.com/v1/people/~:(id,email-address,first-name,last-name,formatted-name,picture-url)?format=json
Where ~ stands for current authenticated user. The response will be something like this ...
{
"id": "KPxRFxLxuX",
"emailAddress": "johndoe#example.com",
"firstName": "John",
"lastName": "Doe",
"formattedName": "John Doe",
"pictureUrl": "https://media.licdn.com/mpr/mprx/0_0QblxThAqcTCt8rrncxxO5JAr...cjSsn6gRQ2b"
}
Hope this helps!
I'm using OWIN in my solution so after the user allows your application to use LinkedIn credentials a simple and plain GET request to URL https://api.linkedin.com/v1/people/~:(picture-URL)?format=json, as explained before with a Bearer authorization in request headers, solved my problems.
My Startup.Auth.cs file
var linkedInOptions = new LinkedInAuthenticationOptions()
{
ClientId = [ClientID],
ClientSecret = [ClientSecret],
Provider = new LinkedInAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
// This is the access token received by your application after user allows use LinkedIn credentials
context.Identity.AddClaim(new Claim(
"urn:linkedin:accesstoken", context.AccessToken));
context.Identity.AddClaim(new Claim(
"urn:linkedin:name", context.Name));
context.Identity.AddClaim(new Claim(
"urn:linkedin:username", context.UserName));
context.Identity.AddClaim(new Claim(
"urn:linkedin:email", context.Email));
context.Identity.AddClaim(new Claim(
"urn:linkedin:id", context.Id));
return Task.FromResult(0);
}
}
};
app.UseLinkedInAuthentication(linkedInOptions);
My method to get the user's profile picture in LinkedIn:
public string GetUserPhotoUrl(string accessToken)
{
string result = string.Empty;
var apiRequestUri = new Uri("https://api.linkedin.com/v1/people/~:(picture-url)?format=json");
using (var webClient = new WebClient())
{
webClient.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + accessToken);
var json = webClient.DownloadString(apiRequestUri);
dynamic x = JsonConvert.DeserializeObject(json);
string userPicture = x.pictureUrl;
result = userPicture;
}
return result;
}
And finally a snippet of my action that consumes the method above:
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
...
var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
string accessToken =
externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == "urn:linkedin:accesstoken").Value;
model.PhotoUrl = GetUserPhotoUrl(accessToken);
...
}
I hope it could help.
Best regards
This works well for me!
Explained -
This is for a thumbnail with all other data-
https://api.linkedin.com/v1/people/~:(id,location,picture-urls::(original),specialties,public-profile-url,email-address,formatted-name)?format=json
This is for original image with all other data -
https://api.linkedin.com/v1/people/~:(id,location,picture-url,specialties,public-profile-url,email-address,formatted-name)?format=json
Just use picture-urls::(original)instead of picture-url !
This is currently being used in Gradbee
When you login to linkedin, you will get accesstoken. Use that access token and you can retrieve users data
LinkedInApiClient client = factory.createLinkedInApiClient(accessToken);
com.google.code.linkedinapi.schema.Person person = client.getProfileForCurrentUser(EnumSet.of(
ProfileField.ID, ProfileField.FIRST_NAME, ProfileField.LAST_NAME, ProfileField.HEADLINE,
ProfileField.INDUSTRY, ProfileField.PICTURE_URL, ProfileField.DATE_OF_BIRTH,
ProfileField.LOCATION_NAME, ProfileField.MAIN_ADDRESS, ProfileField.LOCATION_COUNTRY));
String imgageUrl=person.getPictureUrl();
If your goal is simply to display the photo on your site then the LinkedIn Member Profile Plugin may work out for you. It will display the photo, some additional info, along with LinkedIn branding.
Since the LinkedIn API is designed to be used only on behalf of the current logged in user it does not offer similar functionality as the facebook graph api.
This is my solution and it works very very well:
def callback(self):
self.validate_oauth2callback()
oauth_session = self.service.get_auth_session(
data={'code': request.args['code'],
'grant_type': 'authorization_code',
'redirect_uri': self.get_callback_url()},
decoder=jsondecoder
)
me = oauth_session.get('people/~:(id,first-name,last-name,public-profile-url,email-address,picture-url,picture-urls::(original))?format=json&oauth2_access_token='+str(oauth_session.access_token), data={'x-li-format': 'json'}, bearer_auth=False).json()
social_id = me['id']
name = me['firstName']
surname = me['lastName']
email = me['emailAddress']
url = me['publicProfileUrl']
image_small = me.get('pictureUrl', None)
image_large = me.get('pictureUrls', {}).get('values', [])[0]
return social_id, name, surname, email, url, image_small, image_large, me
This may not be quite what you're asking for, but it's useful for individual investigations.
Call up the page in Firefox, left-click the menu over the background image.
Select Inspect Element(Q).
search for -target-image"
That will be the end of of id attribute in an img element.
The src attribute of that img element, will be the URL of the background image.
For me this works
image= auth.extra.raw_info.pictureUrls.values.last.first
with omniauth-linkedin gem