I am using InstagramApiSharp
Here is my code :
public static async void CreateAccount()
{
var _instaApi = InstaApiBuilder.CreateBuilder().Build();
var email = "ramtinaaka#live.com";
var username = "rmt40306";
var password = "rmt122345678";
var firstName = "Ramtiinnn";
var checkEmail = await _instaApi.CheckEmailAsync(email);
if(checkEmail.Succeeded && checkEmail.Value.Available)
{
var create = await _instaApi.CreateNewAccountAsync(username, password, email, firstName);
if (create.Succeeded)
{
Console.WriteLine("Success");
return;
}
Console.WriteLine("Error");
}
return;
}
I get Error printed on console when I call CreateAccount method as well as no account created.
Create Account Wiki
I believe I gave all needed info, I don't think there is anything else to add.
Related
This API is intended for a mobile application. The goal is to let the user confirm the email upon registration. When the user registers, a confirmation link is generated and sent over the email. I've done it the same way in a MVC project, it worked fine, but in a Web API project looks like it ain't gonna cut.
Now when the user clicks that link, the respective action method should be hit and do the job.
The only problem is, the ConfirmEmail action method is just not getting triggered when clicking the confirmation link although it looked fine.
Here are the main configurations which might help
MVC service configuration
services.AddMvc(options =>
{
options.EnableEndpointRouting = true;
options.Filters.Add<ValidationFilter>();
})
.AddFluentValidation(mvcConfiguration => mvcConfiguration.RegisterValidatorsFromAssemblyContaining<Startup>())
.SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);
Identity Service
public async Task<AuthenticationResult> RegisterAsync(string email, string password)
{
var existingUser = await _userManager.FindByEmailAsync(email);
if(existingUser != null)
{
return new AuthenticationResult { Errors = new[] { "User with this email address exists" } };
}
// generate user
var newUser = new AppUser
{
Email = email,
UserName = email
};
// register user in system
var result = await _userManager.CreateAsync(newUser, password);
if (!result.Succeeded)
{
return new AuthenticationResult
{
Errors = result.Errors.Select(x => x.Description)
};
}
// when registering user, assign him user role, also need to be added in the JWT!!!
await _userManager.AddToRoleAsync(newUser, "User");
// force user to confirm email, generate token
var token = await _userManager.GenerateEmailConfirmationTokenAsync(newUser);
// generate url
var confirmationLink = _urlHelper.Action("ConfirmEmail", "IdentityController",
new { userId = newUser.Id, token = token }, _httpRequest.HttpContext.Request.Scheme);
// send it per email
var mailresult =
await _emailService.SendEmail(newUser.Email, "BingoApp Email Confirmation",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(confirmationLink)}'>clicking here</a>.");
if (mailresult)
return new AuthenticationResult { Success = true };
else
return new AuthenticationResult { Success = false, Errors = new List<string> { "Invalid Email Address"} };
}
Controller
[HttpPost(ApiRoutes.Identity.Register)]
public async Task<IActionResult> Register([FromBody] UserRegistrationRequest request)
{
if (!ModelState.IsValid)
{
return BadRequest(new AuthFailedResponse
{
Errors = ModelState.Values.SelectMany(x => x.Errors.Select(xx => xx.ErrorMessage))
});
}
// register the incoming user data with identity service
var authResponse = await _identityService.RegisterAsync(request.Email, request.Password);
if (!authResponse.Success)
{
return BadRequest(new AuthFailedResponse
{
Errors = authResponse.Errors
});
}
// confirm registration
return Ok();
}
[HttpGet]
public async Task<IActionResult> ConfirmEmail(string userId, string token)
{
if (userId == null || token == null)
{
return null;
}
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
return null;
}
var result = await _userManager.ConfirmEmailAsync(user, token);
if (result.Succeeded)
{
await _emailService.SendEmail(user.Email, "BingoApp - Successfully Registered", "Congratulations,\n You have successfully activated your account!\n " +
"Welcome to the dark side.");
}
return null;
}
Your _urlHelper.Action(..) looks a bit suspicious to me.
I'm not sure you should pass the full controller name, that is, including the actual word controller.
Try _urlHelper.Action("ConfirmEmail", "Identity", instead.
As a tip: I try to avoid magic strings like these by using nameof(IdentityController) because it will return the controller name without the controller postfix.
I am trying to learn how to use InstaSharper but I've got a problem. Everytime when I run my code to see the new code working, I have to login, but if I do this too many times, I will be blocked by Instagram. I was blocked on two accounts allready. So I need a solution not to always have to login like a token or something.
My login:
public static async void Login()
{
api = InstaApiBuilder.CreateBuilder()
.SetUser(user)
.UseLogger(new DebugLogger(LogLevel.Exceptions))
.SetRequestDelay(RequestDelay.FromSeconds(5, 10))
.Build();
var loginRequest = await api.LoginAsync();
if (loginRequest.Succeeded)
{
Console.WriteLine("Login In Success!");
Follow("artofbokeh");
}
else
{
Console.WriteLine("Login Failed");
}
}
Yes you can save your state in a a file and load it again.
Please give this piece of code a try, it is taken form the official github repo which can be found under this link: Github repo
// create user session data and provide login details
var userSession = new UserSessionData
{
UserName = "username",
Password = "password"
};
// create new InstaApi instance using Builder
_instaApi = InstaApiBuilder.CreateBuilder()
.SetUser(userSession)
.UseLogger(new DebugLogger(LogLevel.Exceptions)) // use logger for requests and debug messages
.SetRequestDelay(TimeSpan.FromSeconds(2))
.Build();
const string stateFile = "state.bin";
try
{
if (File.Exists(stateFile))
{
Console.WriteLine("Loading state from file");
Stream fs = File.OpenRead(stateFile);
fs.Seek(0, SeekOrigin.Begin);
_instaApi.LoadStateDataFromStream(fs);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
if (!_instaApi.IsUserAuthenticated)
{
// login
Console.WriteLine($"Logging in as {userSession.UserName}");
var logInResult = await _instaApi.LoginAsync();
if (!logInResult.Succeeded)
{
Console.WriteLine($"Unable to login: {logInResult.Info.Message}");
return false;
}
}
var state = _instaApi.GetStateDataAsStream();
using (var fileStream = File.Create(stateFile))
{
state.Seek(0, SeekOrigin.Begin);
state.CopyTo(fileStream);
}
Edit the function to get the state data does the following:
public Stream GetStateDataAsStream()
{
var state = new StateData
{
DeviceInfo = _deviceInfo,
IsAuthenticated = IsUserAuthenticated,
UserSession = _user,
Cookies = _httpRequestProcessor.HttpHandler.CookieContainer
};
return SerializationHelper.SerializeToStream(state);
}
So yes you save all needed information to not login everytime. If this doesnt work for you you are doing something wrong. Please post your code where you load / save the state file.
I'm trying to send a message with TLSharp but cant,i dont get errors,it just execute the code and do nothing;
This is my method.
public virtual async Task SendMessageTest()
{
string NumberToSendMessage = "+55199999999";
if (string.IsNullOrWhiteSpace(NumberToSendMessage))
throw new Exception("TESTE");
// this is because the contacts in the address come without the "+" prefix
var normalizedNumber = NumberToSendMessage.StartsWith("+") ?
NumberToSendMessage.Substring(1, NumberToSendMessage.Length - 1) :
NumberToSendMessage;
var client = NewClient();
var tsk = client.ConnectAsync();
await client.ConnectAsync();
var result = await client.GetContactsAsync();
var user = result.users.lists
.OfType<TLUser>()
.FirstOrDefault(x => x.phone == normalizedNumber);
if (user == null)
{
throw new System.Exception("Number was not found in Contacts List of user: " + NumberToSendMessage);
}
await client.SendTypingAsync(new TLInputPeerUser() { user_id = user.id });
Thread.Sleep(3000);
await client.SendMessageAsync(new TLInputPeerUser() { user_id = user.id }, "TEST");
}
This is my code,is says is wait for activation,what should i do?
I'm trying to use this method also,but it doenst return nothing too.
I'm new to TelegramApi,what i'm doing wrong?
await client.ConnectAsync();
You should authorize first! And only after that you can call other methods. Look at the examples here.
In general you should write something like this:
var hash = await client.SendCodeRequestAsync(NotRegisteredNumberToSignUp);
var code = Console.ReadLine(); //Input the code, that was sent to your phone
var loggedInUser = await client.MakeAuthAsync(NotRegisteredNumberToSignUp, hash, code);
I am trying to create a login method and I need to get a password from the corresponding user. This is my database layer code:
public int loginUser(string userName, string pass)
{
int result = 0;
var credentials = MongoCredential.CreateMongoCRCredential("SearchForKnowledge", userName, pass);
var settings = new MongoClientSettings
{
Credentials = new[] { credentials }
};
try
{
var mongoClient = new MongoClient(settings);
var database = mongoClient.GetDatabase("SearchForKnowledge");
var coll = database.GetCollection<BsonDocument>("Users");
var filter = Builders<BsonDocument>.Filter.Eq("userName", userName);
var query = coll.Find(filter);
//??????????
}
catch (Exception ex) {
result = 0;
}
return result;
}
as you can see if the login is success im trying to return 1 and if it fails, 0 (for redirecting purposes). I am struggling to check if the username matches password set to it. At the moment I just made a filter, passed it to the method Find and im dead stuck at this point. How do I return that user's password from mongodb and compare it to the one passed as a parameter?
Try something like this:
public int loginUser(string userName, string pass)
{
int result = 0;
//Here you use credentials for the connection, not the one passed
//to the method:
var credentials = MongoCredential.CreateMongoCRCredential("SearchForKnowledge", connectionUsername, connectionPass);
var settings = new MongoClientSettings
{
Credentials = new[] { credentials }
};
try
{
var mongoClient = new MongoClient(settings);
var database = mongoClient.GetDatabase("SearchForKnowledge");
var coll = database.GetCollection<BsonDocument>("Users");
var filter = Builders<BsonDocument>.Filter.Eq("userName", userName);
var result = await coll.Find(filter).ToListAsync().First();
if(result["Password"] == pass)
{
result = 1;
}
}
catch (Exception ex) {
result = 0;
}
return result;
I need some help regarding mvc 5 using the google login provider and getting some youtube data. right now i think i get things a little mixed up. i'm not new to mvc but to version 5's owin middleware features. well, and not experienced in implementing oauth 2.0.
What i want:
Login to my MVC5 Application via Google.
Read some Youtube information from the logged in user.
What i have done so far:
Followed this Google OAuth 2.0 tutorial: Web applications (ASP.NET MVC).
Installed Google.Apis.Auth.MVC via NuGet.
Implemented AppFlowMetadata and AuthCallbackController as described.
Configured the redirect uri to "/AuthCallback/IndexAsync" as described.
Implemented a YoutubeController with the following action just to dump out some data:
public async Task<ActionResult> IndexAsync()
{
var result =
await new AuthorizationCodeMvcApp(this, new AppFlowMetadata())
.AuthorizeAsync(cancellationToken);
if (result.Credential == null)
{
return new RedirectResult(result.RedirectUri);
}
else
{
var service = new YouTubeService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "MyYoutubeApplication"
});
var playlists = service.Playlists.List("contentDetails, snippet");
playlists.Mine = true;
var list = await playlists.ExecuteAsync();
var json = new JavaScriptSerializer().Serialize(list);
ViewBag.Message = json;
return View();
}
}
So what this does, when trying to access /Youtube/IndexAsync is redirecting me to google, asking for my credentials.
when entered, i'm asked if i'm ok with the permission asked by the application. after confirming, i get redirected to my page, showing my /Youtube/IndexAsync page with the requested data. so far so good, but that's not quite what i want.
what (i think) i have done here is that i completely bypassed the asp.net identity system. the user is not logged in to my application let alone registered.
i want the user to log in with google, register in my application and provide access to his youtube data. then, when on a specific page, retrieve data from the user's youtube account.
What i also have tried:
Following this ASP.Net MVC5 Tutorial
This tutorial does not mention the NuGet package "Google.Apis.Auth.MVC" and talks something about a magic "/signin-google" redirect uri".
This also works, but breaks the solution above, complaining about a wrong redirect uri.
When using this approach, it seems not right to me call AuthorizeAsync in YoutubeController again, since i should already be authorized.
So i'm looking for some light in the dark, telling me what i'm mixing all together :) I hope the question is not as confused as i am right now.
I managed to do this using GooglePlus, haven't tried Google. Here's what I did:
Install the nugets:
> Install-Package Owin.Security.Providers
> Install-Package Google.Apis.Youtube.v3
Add this to Startup.auth.cs:
var g = new GooglePlusAuthenticationOptions();
g.ClientId = Constants.GoogleClientId;
g.ClientSecret = Constants.GoogleClientSecret;
g.RequestOfflineAccess = true; // for refresh token
g.Provider = new GooglePlusAuthenticationProvider
{
OnAuthenticated = context =>
{
context.Identity.AddClaim(new Claim(Constants.GoogleAccessToken, context.AccessToken));
if (!String.IsNullOrEmpty(context.RefreshToken))
{
context.Identity.AddClaim(new Claim(Constants.GoogleRefreshToken, context.RefreshToken));
}
return Task.FromResult<object>(null);
}
};
g.Scope.Add(Google.Apis.YouTube.v3.YouTubeService.Scope.YoutubeReadonly);
g.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
app.UseGooglePlusAuthentication(g);
The above code does two things:
Enable authentication via. Google+
Requests for the access token and the refresh token. The tokens are then added as a claim in the GooglePlus middleware.
Create a method that will store the claims containing the token to the database. I have this in the AccountController.cs file
private async Task StoreGooglePlusAuthToken(ApplicationUser user)
{
var claimsIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
if (claimsIdentity != null)
{
// Retrieve the existing claims for the user and add the google plus access token
var currentClaims = await UserManager.GetClaimsAsync(user.Id);
var ci = claimsIdentity.FindAll(Constants.GoogleAccessToken);
if (ci != null && ci.Count() != 0)
{
var accessToken = ci.First();
if (currentClaims.Count() <= 0)
{
await UserManager.AddClaimAsync(user.Id, accessToken);
}
}
ci = claimsIdentity.FindAll(Constants.GoogleRefreshToken);
if (ci != null && ci.Count() != 0)
{
var refreshToken = ci.First();
if (currentClaims.Count() <= 1)
{
await UserManager.AddClaimAsync(user.Id, refreshToken);
}
}
}
You'll need to call it in 2 places in the AccountController.cs: Once in ExternalLoginCallback:
case SignInStatus.Success:
var currentUser = await UserManager.FindAsync(loginInfo.Login);
if (currentUser != null)
{
await StoreGooglePlusAuthToken(currentUser);
}
return RedirectToLocal(returnUrl);
and once in ExternalLoginConfirmation:
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user);
if (result.Succeeded)
{
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (result.Succeeded)
{
await StoreGooglePlusAuthToken(user);
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToLocal(returnUrl);
}
}
Now that we've got the users access token and refresh token we can use this to authenticate the user.
I tried a simple search I saw in the examples and it worked:
private async Task<Models.YouTubeViewModel> Search(string searchTerm)
{
var user = (ClaimsPrincipal)Thread.CurrentPrincipal;
var at = user.Claims.FirstOrDefault(x => x.Type == Constants.GoogleAccessToken);
var rt = user.Claims.FirstOrDefault(x => x.Type == Constants.GoogleRefreshToken);
if (at == null || rt == null)
throw new HttpUnhandledException("Access / Refresh Token missing");
TokenResponse token = new TokenResponse
{
AccessToken = at.Value,
RefreshToken = rt.Value
};
var cred = new UserCredential(new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer()
{
ClientSecrets = new ClientSecrets()
{
ClientId = Constants.GoogleClientId,
ClientSecret = Constants.GoogleClientSecret
}
}
),
User.Identity.GetApplicationUser().UserName,
token
);
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApplicationName = this.GetType().ToString(),
HttpClientInitializer = cred,
});
var searchListRequest = youtubeService.Search.List("snippet");
searchListRequest.Q = searchTerm;
searchListRequest.MaxResults = 50;
// Call the search.list method to retrieve results matching the specified query term.
var searchListResponse = await searchListRequest.ExecuteAsync();
Models.YouTubeViewModel vm = new Models.YouTubeViewModel(searchTerm);
foreach (var searchResult in searchListResponse.Items)
{
switch (searchResult.Id.Kind)
{
case "youtube#video":
vm.Videos.Add(new Models.Result(searchResult.Snippet.Title, searchResult.Id.VideoId));
break;
case "youtube#channel":
vm.Channels.Add(new Models.Result(searchResult.Snippet.Title, searchResult.Id.ChannelId));
break;
case "youtube#playlist":
vm.Playlists.Add(new Models.Result(searchResult.Snippet.Title, searchResult.Id.PlaylistId));
break;
}
}
return vm;
}
Model Classes
public class Result
{
public string Title { get; set; }
public string Id { get; set; }
public Result() { }
public Result(string title, string id)
{
this.Title = title;
this.Id = id;
}
}
public class YouTubeViewModel
{
public string SearchTerm { get; set; }
public List<Result> Videos { get; set; }
public List<Result> Playlists { get; set; }
public List<Result> Channels { get; set; }
public YouTubeViewModel()
{
Videos = new List<Result>();
Playlists = new List<Result>();
Channels = new List<Result>();
}
public YouTubeViewModel(string searchTerm)
:this()
{
SearchTerm = searchTerm;
}
}
Reference: http://blogs.msdn.com/b/webdev/archive/2013/10/16/get-more-information-from-social-providers-used-in-the-vs-2013-project-templates.aspx