TweetInvi - Cannot Unfollow Users - c#

I have the following code that is intended to find the users you are following, and the users that you have requested to follow. It then unfollows the one's that are not following you. However it never actually seem's to work, however the AuthenticatedUser_UnFollowUser returns true. Any ideas? Thanks.
private void AuthenticateUser()
{
CheckRateLimits();
Auth.SetUserCredentials(_consumerKey, _consumerSecret, _userAccessToken, _userAccessSecret);
authenticatedUser = User.GetAuthenticatedUser();
}
private void CheckRateLimits()
{
// Enable RateLimit Tracking
RateLimit.RateLimitTrackerMode = RateLimitTrackerMode.TrackAndAwait;
TweetinviEvents.QueryBeforeExecute += (sender, args) =>
{
var queryRateLimits = RateLimit.GetQueryRateLimit(args.QueryURL);
// Some methods are not RateLimited. Invoking such a method will result in the queryRateLimits to be null
if (queryRateLimits != null)
{
if (queryRateLimits.Remaining > 0)
{
AppendProgress("RateLimits Available : " + queryRateLimits.Remaining.ToString());
// We have enough resource to execute the query
return;
}
// Strategy #1 : Wait for RateLimits to be available
AppendProgress("Waiting for RateLimits until : " + queryRateLimits.ResetDateTime.ToLongTimeString() + "For " + queryRateLimits.ToString());
MessageBox.Show("Waiting for " + queryRateLimits.ResetDateTime.ToLongTimeString());
Thread.Sleep((int)queryRateLimits.ResetDateTimeInMilliseconds);
// Strategy #2 : Use different credentials
//var alternateCredentials = TwitterCredentials.CreateCredentials("", "", "", "");
//var twitterQuery = args.TwitterQuery;
//twitterQuery.OAuthCredentials = alternateCredentials;
// Strategy #3 : Cancel Query
//args.Cancel = true;
}
};
}
private void UnfollowUsersNotFollowingYou()
{
AuthenticateUser();
var toUnfollow = Examples.Friendship_GetUsersNotFollowingYou();
toUnfollow.ForEach(x =>
{
if (Examples.AuthenticatedUser_UnFollowUser(x.ScreenName))
{
AppendProgress("You have unfollowed " + x.ScreenName);
SaveUnfollowedUserIdToTextFile(x.ScreenName);
}
});
}
//From Examples Static Class
public static bool AuthenticatedUser_UnFollowUser(string userName)
{
var authenticatedUser = User.GetAuthenticatedUser();
var userToFollow = User.GetUserFromScreenName(userName);
bool unfollowed = authenticatedUser.UnFollowUser(userToFollow);
return unfollowed;
}
//Users Not Following You
public static IEnumerable<IUser> Friendship_GetUsersNotFollowingYou()
{
var currentuser = Examples.User_GetCurrentUserScreenname();
var followers = Examples.User_GetFriendIds(currentuser);
var following = Examples.Friendship_GetUsersYouRequestedToFollow();
var toUnfollow = following.Where(x => followers != x.FriendIds);
return toUnfollow;
}

I am the developer of Tweetinvi. I have just verified and unfollow like follow seems to work properly. Could you please verify that you are using the latest version of Tweetinvi (0.9.13.0)?
Also please note that Unfollow will return success even if the user was not followed. This is what Twitter is returning and there is nothing I can do about that.
EDIT :
The problem came from the fact that #david-beamont was not retrieving the users properly.
Here is the code to get the following users :
var authenticatedUser = User.GetAuthenticatedUser();
var friends = authenticatedUser.GetFriends();

Related

How do I use the returned variable from a method in another class in c#?

I have a method that returns a long and I want to be able to use it outside said method but I can't seem to figure this out... A little help?
Here's the method:
using System;
using System.IdentityModel.Tokens.Jwt;
namespace API
{
public class UserIDClass
{
protected string responseHeader = "";
protected long id = 0;
public long idMethod(string responseHeader, long id)
{
string[] bearerToken = responseHeader.Split(" ");
var txtJwtIn = bearerToken[1];
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(txtJwtIn);
var decodedToken = handler.ReadToken(txtJwtIn) as JwtSecurityToken;
var sub = decodedToken.Subject;
string[] subSplit = sub.Split("|");
long goodId = Int64.Parse(subSplit[1]);
if (goodId == id)
{
Console.WriteLine("goodId "+ goodId + " = id " + id);
}
else {
Console.WriteLine("goodId = " + goodId + " but the id you searched was " + id);
return goodId;
}
}}
and here's the code I'm instantiating the method in:
[HttpGet("{id}")]
[Authorize]
public async Task<ActionResult<User>> Get(long id)
{
var responseHeader = Request.Headers["Authorization"].FirstOrDefault();
UserIDClass useridclass = new UserIDClass();
useridclass.idMethod(responseHeader, id);
var User = await _context.Users.FindAsync(id);
Console.WriteLine(goodId);
return Ok(User);
}
I want to be able to use the goodId long outside of that method but when I try to write it to the console in the get method I get "the name does not exist in your current context". I feel Like I'm missing something super simple here. I'm still learning so be ever so gentle :)
From what I can gather with your code, it looks like when you instantiating the method, you should create a long variable that holds the output of the method idMethod. What it looks like is you are trying to access the long variable "goodId" but it's out of scope. I would try something like this.
long id = useridclass.idMethod(responseHeader, id);

Removing from the List and the use of API

I am trying to make a program where permit's needs to be deleted from the user account. API's are used to pull up the user account and the permits. After the permits and restrictions are removed an event is created to confirm the deletion. Right now it's not giving me any output what so ever.
String User;
String License;
List<String> Permit;
public RemovePermit(String User, String license, List<String> Permit)
{
this.User = user;
this.License = license;
this.Permit = Permit;
}
public void Run()
{
List<PPermitGroups> permitGroupAdd = new List<PPermitGroups>();
using (var apiUser = new ApiUser())
{
var user = apiGetPerson(User);
var userPermit = apiGetPermitGroup(user.ID);
String license = License;
var deletePermitResult = userPermit.Where(x => Permit.Any(l => x.PermitGroup.Equals(l)|(!String.IsNullOrEmpty(x.Company)&& x.Company.Equals(l))));
foreach (PPermitGroups p in deletePermitResult)
{
apiDeletePermitAndRestrictions(p);
if(p.PermitGroupType == PPermitGroupsPermitGroupTypeEnum.ApplicationPermit)
if (p.LicenseType.Equals("Not Fixed") || p.LicenseType.Equals("Fixed"))
if (p.PermitGroup.StartsWith("Framework") || p.PermitGroup.StartsWith("Release"))
{
var temp = new UserEvent
EventType= " Delete"
License= ""
Permit = ""
}
api.CreateEvent(temp)

Epicor 10.1.5 SessionModSvcContractClient logout

Has anybody ever had an issue where the SessionModSvcContractClient Logout function throws an Exception: Additional information:
Object reference not set to an instance of an object.
When I tried LogoutAsync and Close methods they worked fine.
Can anybody help me figure out why that's happening or the difference between the 3.
I'm basically trying to use create the test from the WCF guide
static void Main(string[] args)
{
//use a self-signed certificate in IIS, be sure to include the following code. This code speeds up calls to the services and prevents the method from trying to validate the certificate with the known authorities.
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => { return true; };
//You can toggle the value assigned to this variable to test the two bindings: SOAPHttp or BasicHttp
EndpointBindingType bindingType = EndpointBindingType.SOAPHttp;
//Epicor credentials:
string epicorUserID = "XXX";
string epiorUserPassword = "XXX";
string scheme = "http";
if (bindingType == EndpointBindingType.BasicHttp)
{
scheme = "https";
}
UriBuilder builder = new UriBuilder(scheme, "localhost");
string webServicesLink = "XXX/";
builder.Path = webServicesLink + "Ice/Lib/SessionMod.svc";
SessionModSvcContractClient sessionModClient = GetClient < SessionModSvcContractClient, SessionModSvcContract > (builder.Uri.ToString(), epicorUserID, epiorUserPassword, bindingType);
builder.Path = webServicesLink + "Erp/BO/AbcCode.svc";
ABCCodeSvcContractClient abcCodeClient = GetClient<ABCCodeSvcContractClient, ABCCodeSvcContract>(builder.Uri.ToString(), epicorUserID, epiorUserPassword, bindingType);
Guid sessionId = Guid.Empty;
sessionId = sessionModClient.Login();
//Create a new instance of the SessionModSvc. Do this because when you call any method on the service
//client class, you cannot modify its Endpointbehaviors.
builder.Path = webServicesLink + "Ice/Lib/SessionMod.svc";
sessionModClient = GetClient < SessionModSvcContractClient, SessionModSvcContract > (builder.Uri.ToString(),epicorUserID,epiorUserPassword,bindingType);
sessionModClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID));
abcCodeClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID));
var ts = new ABCCodeTableset();
abcCodeClient.GetNewABCCode(ref ts);
var newRow = ts.ABCCode.Where(n => n.RowMod.Equals("A", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
if (newRow != null)
{
newRow.ABCCode = "G";
newRow.CountFreq = 30;
newRow.StockValPcnt = 100;
abcCodeClient.Update(ref ts);
ts = null;
ts = abcCodeClient.GetByID("G");
if (ts != null && ts.ABCCode.Any())
{
ABCCodeRow backupRow = new ABCCodeRow();
var fields = backupRow.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var field in fields)
{
if (field.PropertyType == typeof(System.Runtime.Serialization.ExtensionDataObject))
{
continue;
}
var fieldValue = field.GetValue(ts.ABCCode[0]);
field.SetValue(backupRow, fieldValue);
}
ts.ABCCode.Add(backupRow);
ts.ABCCode[0].CountFreq = 45;
ts.ABCCode[0].RowMod = "U";
abcCodeClient.Update(ref ts);
ts = null;
ts = abcCodeClient.GetByID("G");
if (ts != null && ts.ABCCode.Any())
{
Console.WriteLine("CountFreq = {0}", ts.ABCCode[0].CountFreq);
ts.ABCCode[0].RowMod = "D";
abcCodeClient.Update(ref ts);
try
{
ts = abcCodeClient.GetByID("G");
}
catch (FaultException<Epicor.AbcCodeSvc.EpicorFaultDetail> ex)
{
if (ex.Detail.ExceptionKindValue.Equals("RecordNotFound", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("Record deleted.");
}
else
{
Console.WriteLine(ex.Message);
}
}
}
}
}
if (sessionId != Guid.Empty)
{
sessionModClient.Logout();
}
Console.ReadLine();
}
Your code worked fine for me after I changed the config to suit my environment.
It looks like you followed the step 7 on page 15 of the Epicor10_techrefWCFServices_101400.pdf guide and correctly created a new instance of the SessionModSvc after Login(). However, if you copied the full code for the Main method from page 18 then this is missing and I can replicate your issue.
Check the code that you are compiling has created a new instance of the SessionModSvc after the call to .Login().
See my other answer, but as an alternative you may want to consider this method of accessing the services.
If you have access to the client DLLs then this code might be easier:
static void Main(string[] args)
{
// Hard-coded LogOn method
// Reference: Ice.Core.Session.dll
Ice.Core.Session session = new Ice.Core.Session("manager", "manager", "net.tcp://AppServer/MyCustomerAppserver-99999-10.0.700.2");
// References: Epicor.ServiceModel.dll, Erp.Contracts.BO.ABCCode.dll
var abcCodeBO = Ice.Lib.Framework.WCFServiceSupport.CreateImpl<Erp.Proxy.BO.ABCCodeImpl>(session, Erp.Proxy.BO.ABCCodeImpl.UriPath);
// Call the BO methods
var ds = abcCodeBO.GetByID("A");
var row = ds.ABCCode[0];
System.Console.WriteLine("CountFreq is {0}", row.CountFreq);
System.Console.ReadKey();
}
Just add references to:
Ice.Core.Session.dll
Epicor.ServiceModel.dll
Erp.Contracts.BO.ABCCode.dll

How to get Bitcoin value for corresponding USD value in ASP.NET C#?

I want to get Bitcoin value for corresponding USD value and store it in table or variable. I got this URL from which I can get a Bitcoin value for USK amount. I searched on blockchain and I found this URL.
For example:
500usd = 0.76105818 btc
I tried:
https://blockchain.info/tobtc?currency=USD&value=500
at the end, its USD value which we want to convert in Bitcoin.
I want to get the result in the variable in C# (backend).
How can I accomplish this?
You need to just make call to server and parse the response.
var uri = String.Format("https://blockchain.info/tobtc?currency=USD&value={0}", 500);
WebClient client = new WebClient();
client.UseDefaultCredentials = true;
var data = client.DownloadString(uri);
var result = Convert.ToDouble(data);
Install-Package CoinMarketCapClient
using CoinMarketCap;
public static async Task<double> GetBitcoinInUsd(double usd){
//https://api.coinmarketcap.com/v1/ticker/bitcoin/
CoinMarketCapClient client = CoinMarketCapClient.GetInstance();
var entity = await client.GetTickerAsync("bitcoin");
return entity.PriceUsd * usd;
}
var uri = String.Format(#"https://blockchain.info/tobtc?currency=USD&value={0}",1);
WebClient client = new WebClient();
client.UseDefaultCredentials = true;
var data = client.DownloadString(uri);
var result = 1/Convert.ToDouble(data.Replace('.',',')); //you will receive 1 btc = result;
There are several APIs out there that will allow you to request the prices for a list of crypto currencies, and/or fiat currencies. The problem is that all the APIs do it in a disparate way. The follow on from that is that any one could be down at any given time, so you need to have some failure tolerance built in. I.e. the code should attempt to use one API, and if that fails, move to the next. Of course, this is further complicated by the fact that price is subjective and localised to a given country, exchange and so on. So, getting an accurate value is very difficult.
Here is example Crypto Compare client from CryptoCurrency.Net (https://github.com/MelbourneDeveloper/CryptoCurrency.Net/blob/master/src/CryptoCurrency.Net/APIClients/PriceEstimationClients/CryptoCompareClient.cs):
public class CryptoCompareClient : PriceEstimationClientBase, IPriceEstimationClient
{
public CryptoCompareClient(IRestClientFactory restClientFactory) : base(restClientFactory)
{
RESTClient = restClientFactory.CreateRESTClient(new Uri("https://min-api.cryptocompare.com"));
}
protected override Func<GetPricesArgs, Task<EstimatedPricesModel>> GetPricesFunc { get; } = async a =>
{
var retVal = new EstimatedPricesModel();
if (a.Currencies.ToList().Count == 0)
{
return retVal;
}
retVal.LastUpdate = DateTime.Now;
var symbolsPart = string.Join(",", a.Currencies.Select(c => c.Name));
var priceJson = await a.RESTClient.GetAsync<string>($"data/pricemultifull?fsyms={symbolsPart}&tsyms={a.FiatCurrency}");
var jObject = (JObject)JsonConvert.DeserializeObject(priceJson);
var rawNode = (JObject)jObject.First.First;
foreach (JProperty coinNode in rawNode.Children())
{
var fiatNode = (JProperty)coinNode.First().First;
var allProperties = fiatNode.First.Children().Cast<JProperty>().ToList();
var change24HourProperty = allProperties.FirstOrDefault(p => string.Compare(p.Name, "CHANGEPCT24HOUR", true) == 0);
var priceProperty = allProperties.FirstOrDefault(p => string.Compare(p.Name, "PRICE", true) == 0);
var price = (decimal)priceProperty.Value;
var change24Hour = (decimal)change24HourProperty.Value;
retVal.Result.Add(new CoinEstimate { CurrencySymbol = new CurrencySymbol(coinNode.Name), ChangePercentage24Hour = change24Hour, FiatEstimate = price, LastUpdate = DateTime.Now });
}
//Extreme hack. It's better to show zero than nothing at all and get the coins stuck
foreach (var currency in a.Currencies)
{
if (retVal.Result.FirstOrDefault(ce => ce.CurrencySymbol.Equals(currency)) == null)
{
retVal.Result.Add(new CoinEstimate { ChangePercentage24Hour = 0, CurrencySymbol = currency, FiatEstimate = 0, LastUpdate = DateTime.Now });
}
}
return retVal;
};
}
The PriceEstimationManager will flick through APIs until it finds one that works (https://github.com/MelbourneDeveloper/CryptoCurrency.Net/blob/master/src/CryptoCurrency.Net/APIClients/PriceEstimationClients/PriceEstimationManager.cs):
public class PriceEstimationManager
{
#region Fields
private readonly Collection<IPriceEstimationClient> _Clients = new Collection<IPriceEstimationClient>();
#endregion
#region Constructor
public PriceEstimationManager(IRestClientFactory restClientFactory)
{
foreach (var typeInfo in typeof(PriceEstimationManager).GetTypeInfo().Assembly.DefinedTypes)
{
var type = typeInfo.AsType();
if (typeInfo.ImplementedInterfaces.Contains(typeof(IPriceEstimationClient)))
{
_Clients.Add((IPriceEstimationClient)Activator.CreateInstance(type, restClientFactory));
}
}
}
#endregion
#region Public Methods
/// <summary>
/// TODO: This needs to be averaged. The two current clients give wildly different values. Need to include some Australian exchanges etc.
/// </summary>
public async Task<EstimatedPricesModel> GetPrices(IEnumerable<CurrencySymbol> currencySymbols, string fiatCurrency)
{
//Lets try a client that hasn't been used before if there is one
var client = _Clients.FirstOrDefault(c => c.AverageCallTimespan.TotalMilliseconds == 0);
var currencies = currencySymbols.ToList();
if (client != null)
{
try
{
return await client.GetPrices(currencies, fiatCurrency);
}
catch
{
//Do nothing
}
}
foreach (var client2 in _Clients.OrderBy(c => c.SuccessRate).ThenBy(c => c.AverageCallTimespan).ToList())
{
try
{
return await client2.GetPrices(currencies, fiatCurrency);
}
catch (Exception ex)
{
Logger.Log("Error Getting Prices", ex, nameof(PriceEstimationManager));
}
}
throw new Exception("Can't get prices");
}
#endregion
}
At a higher level, you can use the code like this (https://github.com/MelbourneDeveloper/CryptoCurrency.Net/blob/master/src/CryptoCurrency.Net.UnitTests/PricingTests.cs):
public async Task GetUSDBitcoinPrice()
{
var priceEstimationManager = new PriceEstimationManager(new RESTClientFactory());
var estimatedPrice = await priceEstimationManager.GetPrices(new List<CurrencySymbol> { CurrencySymbol.Bitcoin }, "USD");
Console.WriteLine($"Estimate: {estimatedPrice.Result.First().FiatEstimate}");
}
As more pricing clients are added, it will get more and more reliable.

Get all followings using LINQ to Twitter

I've just started a Windows Phone app, and I need to get all the user's followings.
I tried this :
SharedState.Authorizer = pinAuth;
ITwitterAuthorizer auth = SharedState.Authorizer;
TwitterContext twitterCtx = new TwitterContext(auth);
var friendList =
(from friend in twitterCtx.SocialGraph
where friend.Type == SocialGraphType.Friends && friend.ScreenName == "_TDK"
select friend)
.SingleOrDefault();
List<String> Followings;
foreach (var id in friendList.ScreenName)
{
Followings.Add(id.ToString());
}
But friendlist is always null and, obviously, the foreach does not like that and throws an exception.
Could someone help me ?
Thanks.
I think you need to iterate over the IDs collection, like this:
foreach (var id in friendList.IDs)
{
Followings.Add(id.ToString());
}
You need to make async calls with Silverlight-based apps, including Windows Phone. Here's an example of how you can refactor the query:
var twitterCtx = new TwitterContext(auth);
(from social in twitterCtx.SocialGraph
where social.Type == SocialGraphType.Followers &&
social.ScreenName == "JoeMayo"
select social)
.MaterializedAsyncCallback(asyncResponse =>
Dispatcher.BeginInvoke(() =>
{
if (asyncResponse.Status != TwitterErrorStatus.Success)
{
MessageBox.Show(
"Error during query: " +
asyncResponse.Exception.Message);
return;
}
SocialGraph social = asyncResponse.State.SingleOrDefault();
SocialListBox.ItemsSource = social.IDs;
}));
The MaterializedAsyncCallback manages the callback from Twitter. Notice how I use Dispatcher.BeginInvoke to marshal the call back onto the UI thread as the callback is on a worker thread. On the asyncResponse callback parameter, use Status to see if there is an error and use State to get the data if the query is successful.
I had the same problem, I solved this way (I know it's not the best way)
public void getProfile(MyProgressBar myprogressbar)
{
var auth = new SingleUserAuthorizer
{
Credentials = new InMemoryCredentials
{
ConsumerKey = GlobalVariables.ConsumerKey,
ConsumerSecret = GlobalVariables.ConsumerSecret,
AccessToken = GlobalVariables.AccessToken,
OAuthToken = GlobalVariables.AccessTokenSecret
}
};
using (var twitterCtx = new TwitterContext(auth, "https://api.twitter.com/1/", "https://search.twitter.com/"))
{
//Log
twitterCtx.Log = Console.Out;
var queryResponse = (from tweet in twitterCtx.Status
where tweet.Type == StatusType.User && tweet.ScreenName == GlobalVariables.ScreenName
select tweet);
queryResponse.AsyncCallback(tweets =>
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
var publicTweets = (from tweet in tweets
select tweet).FirstOrDefault();
s.TwitterName = publicTweets.User.Name.ToString();
s.TwitterScreenName = "#" + GlobalVariables.ScreenName;
s.TwitterDescription = publicTweets.User.Description.ToString();
s.TwitterStatus = publicTweets.User.StatusesCount.ToString() + " Tweets / " + publicTweets.User.FriendsCount.ToString() + " Following / " + publicTweets.User.FollowersCount.ToString() + " Followers";
s.TwitterImage = publicTweets.User.ProfileImageUrl.ToString();
myprogressbar.ShowProgressBar = false;
})).SingleOrDefault();
}
}

Categories