Get user's recent media with account username instead of user ID - instagram

So I want to use the Instagram API to get a specific user's (NOT MY USER) recent media. Instagram has the following endpoint for doing so:
(GET) https://api.instagram.com/v1/users/{user-id}/media/recent/?access_token=ACCESS-TOKEN
This is a problem because I do not have the user's ID (why would I, Instagram?). What I do have is the account username (as most people would), e.g. #thisisauser.
I've been reading the API docs and I can't find an endpoint that will give me the user ID for a specific account username. I mean, yes, there is:
(GET) https://api.instagram.com/v1/users/search?q=jack&access_token=ACCESS-TOKEN
...but it doesn't do what I need it to do, which is to search for an exact match.
I've also checked out other threads on Stack Overflow and other websites. However, the alternative solutions offered are, at best, questionable.
The fact that this whole thing is an actual issue surprises me. I mean, SURELY there's a legitimate, Instagram-approved, precise and straightforward way of either:
obtaining a user's recent media by providing the account username (which is what people know you by... not a sequence of numbers)
OR
obtaining a user's ID via an exact match search, with no chance of multiple possible results
FYI: I'm doing this server-side, using PHP and cURL.
Side note: If I have to make a separate request to the API in order to convert an account username to a user ID, that's just a waste of a request, one more for the hourly limit. Just an observation, in case any member of the Instagram team happens to see this.

You can get all of a user's information (including the id) by requesting this URL:
https://www.instagram.com/{username}/?__a=1
For example, this gets you all of the information related to the account taylorswift:
https://www.instagram.com/taylorswift/?__a=1

I couldn't find anything in the API that gets a username's media. However, by using the search endpoint, you can come up with a solution to get a user's media.
Since you're using PHP cURL, you could do something like this:
//this is what was returned by cURL
$response = /*what was returned by the API - see below*/
{
"data": [{
"username": "jack",
"first_name": "Jack",
"profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_66_75sq.jpg",
"id": "66",
"last_name": "Dorsey"
},
{
"username": "sammyjack",
"first_name": "Sammy",
"profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_29648_75sq_1294520029.jpg",
"id": "29648",
"last_name": "Jack"
},
{
"username": "jacktiddy",
"first_name": "Jack",
"profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_13096_75sq_1286441317.jpg",
"id": "13096",
"last_name": "Tiddy"
}]
}
//username I am looking for
$user = 'jack';
//filter array response to find exact username you are looking for
$filter = array_filter($response,function($userdata) use ($user){
if($userdata['username'] == $user){
return $userdata;
}
});
//now use ID from filtered array to get media
$url = 'https://api.instagram.com/v1/users/' . $filter['id'] . '/media/recent/?access_token=ACCESS-TOKEN';

you can find user id !!!
like this :
<html>
<head>
<script src="jquery.js" type="text/javascript" ></script>
<script type="text/javascript">
$(document).ready(function(){
$.ajax({
type: 'GET',
url: 'https://api.instagram.com/v1/users/self/?access_token=' + window.location.hash.substring(14),
dataType: 'jsonp'}).done(function(response){
var userid = response.data.id;
});
});
</script>
</head>
<body>
</body>
</html>
and save in to your data base .then when need find it and use that way to find recent media of user :
https://api.instagram.com/v1/users/{user-id}/media/recent/?access_token=ACCESS-TOKEN
this way i think is beter.
you can send a json with php too.

Related

Meteor.loginWithPassword not working with username with # character

I have a user in database with following credentials:
{
"_id": "zTHv8yqPSm3pmi4So",
"emails": [{"address": "someemail#example.com", "verified": true}],
"services" : {
"password" : {
"bcrypt" : "$2b$10$L6HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo1IjZEx6.PBxfOeQHqS."
},
"resume" : {
"loginTokens" : [ ]
}
},
"username": "some#username",
"profile": {
"firstName": "Example",
"lastName": "User",
}
}
When I try to login user with username it says user not found:
Meteor.loginWithPassword("some#username", "123456", function(error) {
console.log(error.reason);
});
It works fine for email but not for username.
I want flexibility to login user with either of email or username
The API Meteor.loginWithPassword actually takes a "selector" as first argument:
https://docs.meteor.com/api/accounts.html#Meteor-loginWithPassword
Meteor.loginWithPassword(selector, password, [callback])
ARGUMENTS
selector Object or String
Either a string interpreted as a username or an email; or an object with a single key: email, username or id.
In your case you use the string form, and let Meteor try to guess whether it is a username or an email.
But since your username contains an "#" character, this misleads Meteor into interpreting it as an email:
https://github.com/meteor/meteor/blob/release/METEOR%401.12.1/packages/accounts-password/password_client.js#L33-L38
Meteor.loginWithPassword = (selector, password, callback) => {
if (typeof selector === 'string')
if (!selector.includes('#'))
selector = {username: selector};
else
selector = {email: selector};
That is why when you try with the email it works fine, but fails for the username containg the "#".
And the simple solution is to explicitly tell Meteor that you target the username (and not an email, despite the "#"):
Meteor.loginWithPassword({
username: "some#username"
},
"123456",
function(error) {
console.log(error.reason);
}
);
Now, if I am trying to guess further your objective, you want your user to be able to provide either their email or username as login identifier, without explicitly telling which it is? (Like a kind of "omni" login id input)
In that case, unfortunately you will have to detect yourself whether it is an email or username. If the latter really follows a pattern like "some#username", you can try to detect that the domain is incomplete (no extension).
But if any of your user did register a username which really looks like an email (e.g. "some#user.name"), then you may not be able to differentiate them.
Even worse, some user may choose a username that is exactly the email address of another user! In that case, how to tell which one is trying to log in?
IMHO, this then becomes much trouble for marginally improved UX. Either prevent usernames containing "#", i.e. enforce a rule that enables you telling the difference, or provide a way for the user to explicitly tell if it is an email or username when it is ambiguous (e.g. it can be some radios to tell which type it is; it can still contain an "auto" mode for when the login id is unambiguous).
BTW we could also imagine performing a 2 steps login attempt: first as is, then if username contains an "#", explicitly as a username as described above. But we may still fall into the above described worst case scenario...

Microsoft Teams bot finding message sender id

We have built a teams app that can be used in the group chat. So, basically any user can do
#
At the server side, we want to get the sending user and respond to the sent text based on who sent it. The code to get users in the conversation looks like below:
const connector = context.adapter.createConnectorClient(context.activity.serviceUrl);
const response = await connector.conversations.getConversationMembers(context.activity.conversation.id);
functions.logger.log("conversation members are:", response)
The response returns an array of all the users in the conversation with below structure
[
{
"id": "29:1a-Xb7uPrMwC2XqjMEHCC7ytV2xb2VUCqTA-n_s-k5ZyMCTKIL-ku2XkgbE167D_5ZbmVaqQxJGIQ13vypSqu-A",
"name": "Neeti Sharma",
"objectId": "718ab805-860c-43ec-8d4e-4af0c543df75",
"givenName": "Neeti",
"surname": "Sharma",
"email": "xxx#xxxx.xxx",
"userPrincipalName": "xxxx#xxxx.xxx",
"tenantId": "xxx-xx-xx-xxxxxx-x",
"userRole": "user"
},
{
...
}
]
The above response does not indicate who is the sender of the message in the group chat. How do we find that?
I'm not sure the exact syntax for Node (I work mostly in C#), but basically on the context.activity object there is a from property (i.e. context.activity.from), which is of type ChannelAccount (DotNet reference here, but it's very similar for Node). That will give you, at least, Name and AadObjectId. What you're using right now is getConversationMembers, which gives you everyone in the entire Channel, not just that particular message/thread.
turnContext.Activity.From.Id is also unique to each user. You can use that property too. Email is tough to get in any other events than the MembersAdded event.

Creating view to check a document fields for specific values (For a simple login)

I'm very new to cloudant , so pardon me for this question. I am creating a simple mobile game login system which only checks for username(email) and password.
I have several simple docs that are in this format
{
"_id": "xxx",
"_rev": "xxx",
"password": "3O+k+O8bxsxu0KUlSBUiww==", --encrypted by application beforehand
"type": "User",
"email": "asd#asd.com"
}
Right now I can't seem to get the correct 'Formula' for creating this view (map function) whereby I would do a network request and pass it both the email and password. If there is a doc that matches the email, then check the doc.password against the passed value. If it matches, the function should return a simple "YES".
For now my map function is as follows, but this just returns all the docs .
function(doc) {
if (doc.email){
index("password", doc.password, { store : true });
if (doc.password){
emit("YES");
}
}
}
It may be my request format is also wrong. Right now it is as follows. Values are not real, only for format checking
https:/etcetc/_design/app/_view/viewCheckLogin?q=email:"asd#asd.com"&password:"asd"
It looks like you have misunderstood how views are supposed to work. In general you cannot perform logic to return a different result based on the request. Query parameters in a view request can only be used to limit the result set of view entries returned or to return grouped information from the reduce function.
To determine if there is a match for a given username and password you could emit those values as keys and then query for them. This would return the view entry for those keys or an empty list if there was no match. However I'd be very cautious about the security here. Anyone with access to the view would be able to see all the view entries, i.e. all the usernames and passwords.

Instagram: get photos by tag without limit

Hello im working on a instagram api, i don't know how to solve a problem. You can see my problem here down:
I want to get all photos by a tag. by now, i just can get recent photos (no more than 19 results)
$api = "https://api.instagram.com/v1/tags/".$hashtag."/media/recent?client_id=".$client;
how can i make it work?
Instagram API will not return all photos with a single API call, each call I think returns a maximum of 20 photos. After making the first API call, you have to use the "next_url" in "pagination" of JSON response to make another API call to get the next set of 20 images, for example you may have to implement a "show more" button which will load the next set and so on.
Below is a typical response you get from a instagram API, then making a request to API url at pagination.next_url will return you the next set of photos.
{
"meta": {
"code": 200
},
"data": {
...
},
"pagination": {
"next_url": "...",
"next_max_id": "13872296"
}
}

Balanced Payments API call.meteor.js

Hi I am currently using balanced payments in my meteor application. I can create cards and customers just fine and I can associate the cards to the customers just fine. I run into a problem though when I try to create a debit. Here is the code that I have written which is pretty much taken directly from the balanced docs.
var customer = balanced.Customers.get(user.customer.uri, function (err, customer) {
console.error(err);
console.log(customer);
var customerContext = balanced.Customers.nbalanced(customer);
var debitInfo = {
amount: amount,
appears_on_statement_as: "Statement text",
description: "Some descriptive text for the debit in the dashboard"
};
customerContext.Debits.create(debitInfo, function(err, result) {
console.error(err);
console.log(result);
});
});
I get the error "The requested URL was not found on the server" whenever the above code runs. I found the problem but I'm not entirely sure how to solve it. I went to the balanced dashboard to check the logs and what I found was this.
Date: Fri, 27 Sep 2013, 6:46 AM
Method: POST
URI: /v1/marketplaces/TEST-MPFj4MYWjZc9xt2IjTIni7/v1/customers/CU6jgv9FlavhPyYQ6ObZKDny/debits
Status: 404 NOT FOUND
The request body is here:
{
"appears_on_statement_as": "Statement text",
"amount": 1200,
"description": "Some descriptive text for the debit in the dashboard"
}
Here is the response body:
{
"status": "Not Found",
"category_code": "not-found",
"description": "<p>The requested URL was not found on the server.</p><p>If you entered the URL manually please check your spelling and try again.</p> Your request id is OHM38291020277b11e38b38026ba7cac9da.",
"status_code": 404,
"category_type": "request",
"_uris": {},
"request_id": "OHM38291020277b11e38b38026ba7cac9da"
}
I see that the URI has the marketplace and customer url but I don't know why or what could have caused that to happen because like I said the customer creation, card creation and card association calls all work perfectly.
Any advice would be appreciated.
The balanced api documentation over at https://docs.balancedpayments.com/current/api#create-a-new-debit suggests there is an issue with the requested URL.
The URL in the api module you're using requests
/v1/marketplaces/TEST-MPFj4MYWjZc9xt2IjTIni7/v1/customers/CU6jgv9FlavhPyYQ6ObZKDny/debits
when it should be
/v1/customers/CU6jgv9FlavhPyYQ6ObZKDny/debits
It could also be that it needs the marketplaces uri in there, but there isn't a specification in the docs that matches this type of pattern, plus the '/v1/` suggests its being appended unnecessarily
You haven't given details on the type of package you're using but the issue for this lies in the package in the portion that creates the request URI, or if its not validated perhaps in one of the parameters you've provided.

Resources