social networks

How Steemit changed the way I use traditional social networks

How Steemit changed the way I use traditional social networks

What the h*** is Steemit?

Steemit is a social network that (might) pay you for using it. You can earn rewards for posting quality posts, for commenting on others posts and also for curation (voting on other people’s posts).

There is a learning process (which I am still in, even if I advanced already a little), but you can also use some bots to get some attention and make money. Better and also more sustainable than (only) using those bots, however, is to participate in the community itself by commenting and voting as well as taking part in one of several challenges on Steemit. Take a look at the extensive FAQ on Steemit to learn more.

I was following Steemit ever since I stumbled upon it, and after two days of exploring, I created my account (which took around one week back then). There were several reasons for doing that, the most important ones are

  • the community activity I saw and liked
  • my general interest in real life, average joe usable blockchain projects
  • being tired of Facebook, Twitter and the likes
  • earning some bucks (of course)

First steps on Steemit

As soon as my account was created, I started to explore Steemit more deeply. A major part of this exploration included apps I can use on my PC and my phone. After some research, I found my combo of apps/frontends for Steemit:

Being on Steemit also includes promoting it on my other existing social network accounts. And of course, I do share my posts on Facebook and Twitter, using the proper hashtags to make people (hopefully) curious.

Changes…

Yesterday, I took the time to review my last month activity on those popular and established networks. My former daily social media routine included Twitter, Facebook, and Instagram to explore new stuff and things that interest me, besides following certain RSS-Feeds (using Inoreader).

Over time, one follows a lot of accounts because of a few posts they made, but once they are no longer interesting, we do not remove them. So there is a whole lot of bullsh*t in our timelines, and it takes a lot of time to get rid of them. Also, the networks themselves do promote posts we might be interested in, which (at least for me) often miss their targets. The result is, that I avoid using these networks in my daily routine and even stop interacting with them. They are “stealing” my time, literally, if I use them.

Steemit has a few interfaces and apps that make it a bit easier for me to see the stuff I am interested in. Not so much on my developer interests, but on all other interest I have (sadly, there is very little activity of the .NET community on Steemit). So in my daily routine, Steemit took already over Twitter, Facebook, and Instagram. I do check the later ones only occasionally or when I get a notification that someone interacted with one of my accounts. This is the first time this happens within just a month.

I am posting a lot of stuff I would normally post directly to the established ones on Steemit, just to share a link to my Steemit account on those after that. I could also stop that, but I do hope that I can help to promote Steemit to the outer world by doing so.

Conclusion

Steemit is a blockchain based social network rewarding its users. The beginning of my Steemit journey was comparable with the one I had when I joined Twitter or Facebook years ago. You need to find out how everything works, build some connections, interact with others. The Steemit community (at least the parts I am interacting with) still has its spirit, which I am missing on the established networks for a long time. I will continue to focus my social activity on Steemit and to improve my interactions. I hope some of you will join and follow along.

 

image credits:

Steemit Logo

Background

 

Posted by msicc in Archive, 0 comments

How to shorten an url with Bitly asynchronously on Windows Phone

bitly_logo

It was only yesterday when I decided to shorten shared links in UniShare. The reason is not Twitter as suggested by some of my users, but other networks like LinkedIn, that have text length limits as well.

After digging into the Bitly API, I created a little helper that returns the a shorten Bitly-url. In case this is not possible for whatever reason, it returns the long url that was tried to be shortened.

Before we can start to write some code, we need to get our generic access token for the Bitly API. Log in to your Bitly account, and click on ‘Settings’, and choose the ‘Advanced’ tab. If you already verified your mail address, you are nearly done. Enter your password and click on the ‘Generate Token’ Button:

Screenshot (388)

This is one of the constants we need soon. In your project, generate a new class called BitlyHelper. Declare the following constant strings:

private const string bitlyGenericAccessToken = "your_generic_access_token";
private const string base_url = "https://api-ssl.bitly.com/v3/shorten?access_token={0}&longUrl={1}&format=txt";

The base_url string contains the url we are calling, setting our generic access token as well as the long url we want to share. As we are only interested in getting the shortened url, we need to add the ‘format=txt’ part at the end.

The next step is to create an async Task that returns the HttpResponseMessage:

        /// <summary>
        /// Task that starts the async request for the HttpResponseMessage
        /// </summary>
        /// <param name="longUrl">the url to shorten</param>
        /// <returns>the HttpResponseMessage that contains the shortened url</returns>
        private async Task<HttpResponseMessage> getShortUrl(string longUrl)
        {
            //do not forget to UrlEncode the longUrl!
            string request_url = string.Format(base_url, bitlyGenericAccessToken, System.Web.HttpUtility.UrlEncode(longUrl));

            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.IfModifiedSince = DateTime.Now;

            //get the response from the Bitly API
            return await client.GetAsync(new Uri(request_url));
        }

The only important thing we think of here is to UrlEncode our long url, using the System.Web.HttpUtility.UrlEncode() method. If we would not do that, we would get an error on some links from the Bitly API. The rest is pretty straight forward to any other HttpClient usage.

To get our BitlyHelper to be helpful, we are creating another Task that detects the HttpStatusCode of our HttpResponseMessage and returns the shortened url:

        /// <summary>
        /// gets the shortened url out of the HttpResponseMessage
        /// </summary>
        /// <param name="longUrl">the url to shorten</param>
        /// <returns>the shortened url as string</returns>
        public async Task<string> GetShortenedUrl(string longUrl)
        {
            string short_url = string.Empty;

            //using try/catch to avoid Exceptions
            try
            {
                var response = await getShortUrl(longUrl);

                if (response.StatusCode == HttpStatusCode.Ok)
                {
                    short_url = await response.Content.ReadAsStringAsync();
                }
                //on error StatusCodes, just return the longUrl
                else
                {
                    short_url = longUrl;
                }
            }
            catch
            {
                short_url = longUrl;
            }

            return short_url;            
        }

In case the HttpStatusCode is not OK (200), we are simply returning the long url. To avoid any Exceptions, we are doing the same in case there is one. This way, we are keeping it as simple as possible while keeping our desired functionality.

The usage is very simple:

BitlyHelper bitly = new BitlyHelper();
var shorturl = await bitly.GetShortenedUrl("https://yourlongurl.com");

If you want more advanced features, you can perform the whole oAuth dance with your users and get some more features into your app (read more in the API docs). If you just need to shorten the url, this BitlyHelper is all you need.

As always, I hope this is helpful for some of you.

Happy coding!

Posted by msicc in Archive, 0 comments

How to connect your Windows Phone 8 & 8.1 app to Yammer

In my recent project UniShare I also added Yammer, because some of users asked for it and we use it also at Telefónica.

This post is all about how to connect you Yammer. First, we need to prepare our app. Five steps are needed for preparation.

First, we need an uri scheme to launch our app. To add an uri scheme, right click on the WMAppManifest.xml and click on ‘Open With…’ and select ‘XML (Text) Editor with Encoding’. After the ‘Tokens’ section, add your custom uri scheme within the ‘Extensions’ tag, for example:

      <Protocol Name="yourapp-yammercallback" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />

Next step is to add a proper UriMapper:

public class UriMapper : UriMapperBase
{
    public override Uri MapUri(Uri uri)
    {
        if (uri.ToString().Contains("yourapp-yammercallback"))
        {
            string decodedUri = HttpUtility.UrlDecode(uri.ToString());

            int redirectUriIndex = decodedUri.IndexOf("yourapp-yammercallback");
            string redirectParams = new Uri(decodedUri.Substring(redirectUriIndex)).Query;
            // Map the OAuth response to the app page
            return new Uri("/MainPage.xaml" + redirectParams, UriKind.Relative);
        }

        else return uri;
    }
}

If you want to learn more about uri schemes, you can read my blog post here.

The third step is to generate your app on Yammer to get your Tokens. Open https://www.yammer.com/client_applications, click on ‘Register New App’ and fill in the form:

Screenshot (354)

After clicking on continue, click on ‘Basic Info’ and add your uri scheme in the field ‘Redirect Uri’ and click on ‘Save’.

Screenshot (356)

The fourth step starts with downloading the Yammer oAuth SDK for Windows Phone from Github. Open the solution and built all projects. After that, you can close the solution. Go back into your project, and right click on ‘References’, followed by ‘Add Reference’. Browse to the folder ‘\WPYammer-oauth-sdk-demo-master\windows-phone-oauth-sdk-demo-master\Yammer.OAuthSDK\Bin\Release’ and add the file with the name ‘Yammer.OAuthSDK.dll’.

The last step is to add your keys and the redirect uri in your app’s resource dictionary:

<model:OAuthClientInfo xmlns:model="clr-namespace:Yammer.OAuthSDK.Model;assembly=Yammer.OAuthSDK" x:Key="MyOAuthClientInfo"
    ClientId="your client id" 
    ClientSecret="your client secret" 
    RedirectUri="yourapp-yammercallback" />

Now that our app is prepared, we can finally launch the oAuth process. First, we need to read our values from our app’s resource dictionary. Add this to the constructor to do so:

YammerClientId = App.MyOAuthClientInfo.ClientId;
YammerClientSecret = App.MyOAuthClientInfo.ClientSecret;
YammerCallbackUri = App.MyOAuthClientInfo.RedirectUri;

To kick the user out to the oAuth process, which happens in the phone’s browser, just add these two lines to your starting event (for example a button click event).

OAuthUtils.LaunchSignIn(YammerClientId, YammerCallbackUri);
App.Current.Terminate();

You might notice the app gets terminated. We have to do this because only this way, the uri scheme we added earlier can do its work. If the app is not terminated, the values cannot be passed into our app. Technically, it would also be possible to use the WebAuthenticationBroker on 8.1 for this. Sadly, the Yammer authorization pages do not work well with the WAB. The best way to use it with this library, is to kick the user to the browser.

Once we are receiving the values of the authentication, we can continue the authentication process to get the final access token. Add this code to your OnNavigatedTo event:

ShowProgressIndicator("connecting to Yammer...");

if (NavigationContext.QueryString.ContainsKey(Constants.OAuthParameters.Code) && NavigationContext.QueryString.ContainsKey(Constants.OAuthParameters.State) && e.NavigationMode != NavigationMode.Back)
{
    OAuthUtils.HandleApprove(
        YammerClientId,
        YammerClientSecret,
        NavigationContext.QueryString[Constants.OAuthParameters.Code],
        NavigationContext.QueryString[Constants.OAuthParameters.State],
        onSuccess: () =>
        {
            GetYammerCurrentUserData();
        }, onCSRF: () =>
        {
            MessageBox.Show("Please contact us via the 'help & support' page.", "Invalid redirect", MessageBoxButton.OK);
        }, onErrorResponse: errorResponse =>
        {
            Dispatcher.BeginInvoke(() => MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK));
            HideProgressIndicator();
        }, onException: ex =>
        {
            Dispatcher.BeginInvoke(() => MessageBox.Show(ex.ToString(), "Unexpected error", MessageBoxButton.OK));
            HideProgressIndicator();
        }
    );
}
// "Deny"
else if (NavigationContext.QueryString.ContainsKey(Constants.OAuthParameters.Error) && e.NavigationMode != NavigationMode.Back)
{
    string error, errorDescription;
    error = NavigationContext.QueryString[Constants.OAuthParameters.Error];
    NavigationContext.QueryString.TryGetValue(Constants.OAuthParameters.ErrorDescription, out errorDescription);

    string msg = string.Format("error: {0}\nerror_description:{1}", error, errorDescription);
    MessageBox.Show(msg, "Error", MessageBoxButton.OK);

    if (NavigationContext.QueryString != null)
    {
        string[] NavigationKeys = NavigationContext.QueryString.Keys.ToArray();
        ClearNavigationContext(NavigationKeys);
    }

    OAuthUtils.DeleteStoredToken();

}

With this, you are handling all errors and events properly. If the call ends successfully, we are finally able to get our user’s data:

public void GetYammerCurrentUserData()
{
    ShowProgressIndicator("connecting to Yammer...");

    var baseUrl = new Uri("https://www.yammer.com/api/v1/users/current.json", UriKind.Absolute);

    OAuthUtils.GetJsonFromApi(baseUrl,
        onSuccess: response =>
        {
            //do something with the result (json string)

            HideProgressIndicator();

        }, onErrorResponse: errorResponse =>
        {
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                HideProgressIndicator();

            });
        }, onException: ex =>
        {
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(ex.ToString(), "Unexpected error", MessageBoxButton.OK);
                HideProgressIndicator();

            });
        }
    );
}

As you can see above, the result is a json string that contains the current user’s data. You can either create a class/model to deserialize the values or use anonymous deserialization methods.

One important point: you cannot publish your app outside your home network until it got approved as a global app by Yammer. I am waiting for nearly two weeks now for UniShare to get approved and hope it will become available for all soon.

As always, I hope this post is helpful for some of you.

Happy coding!

Posted by msicc in Archive, 1 comment

How to use the WebAuthenticationBroker in a Windows Phone 8.1 Silverlight app

oAuthDance

I already wrote how to use the WebAuthenticationBroker (WAB) in a Windows Phone Runtime app. With the need for me to switch back to Silverlight for UniShare, I needed to perform some rewriting of the WAB code.

The WAB needs some other code to work properly in a Silverlight project, and this post will got through all steps that are needed for this. I will reference to the above blog post where the methods itself are the same. I am just highlighting the changes that are needed in an 8.1 Silverlight project.

Preparing our App

First, we need to set up the proper continuation event in App.xaml.cs. We are doing this by adding this line of code in the App class:

public WebAuthenticationBrokerContinuationEventArgs WABContinuationArgs { get; set; }

This event is used when we are coming back to our app after the WAB logged the user in. The next step we need to do, is to tell our app that we have performed an authentication, and pass the values back to our main code. Unlike in the Runtime project, we are using the Application_ContractActivated event for this:

        private void Application_ContractActivated(object sender, Windows.ApplicationModel.Activation.IActivatedEventArgs e)
        {
            var _WABContinuationArgs = e as WebAuthenticationBrokerContinuationEventArgs;
            if (_WABContinuationArgs != null)
            {
                this.WABContinuationArgs = _WABContinuationArgs;
            }
        }

If you are upgrading from a WP8 project, you might have to add this event manually. Our app is now prepared to get results from the WAB.

Preparing oAuth

I am going to show you the oAuth process of Twitter to demonstrate the usage of the WAB. First, we need again the GetNonce(), GetTimeStamp () and GetSignature(string sigBaseString, string consumerSecretKey, stringoAuthTokenSecret=null) methods from my former blog post.

Performing the oAuth process

In the oAuth authentication flow, we need to obtain a so called Request Token, which allows our app to communicate with the API (in this case Twitter’s API).

Add the following code to your “connect to Twitter”- Button event:

                        string oAuth_Token = await GetTwitterRequestTokenAsync(TwitterCallBackUri, TwitterConsumerKey);
                        string TwitterUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oAuth_Token;

                        WebAuthenticationBroker.AuthenticateAndContinue(new Uri(TwitterUrl), new Uri(TwitterCallBackUri));

Like in a Runtime app, we are getting the request token first (code is also in my former blog post), once we obtained the request token, we are able to get the oAuth token that enables us to get the final user access tokens.

Once the user has authenticated our app, we’ll receive the above mentioned oAuth tokens. To use them, add the following code to your OnNavigatedTo event:

                var appObject = Application.Current as App;

                if (appObject.WABContinuationArgs != null)
                {
                    WebAuthenticationResult result = appObject.WABContinuationArgs.WebAuthenticationResult;

                    if (result.ResponseStatus == WebAuthenticationStatus.Success)
                    {
                        await GetTwitterUserNameAsync(result.ResponseData.ToString());
                    }
                    else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
                    {
                        MessageBox.Show(string.Format("There was an error connecting to Twitter: \n {0}", result.ResponseErrorDetail.ToString()), "Sorry", MessageBoxButton.OK);

                    }
                    else
                    {
                        MessageBox.Show(string.Format("Error returned: \n{0}", result.ResponseStatus.ToString()), "Sorry", MessageBoxButton.OK);
                        HideProgressIndicator();
                    }
                }

The WebAuthenticationResult now holds all values that we need to perform the final actions. To complete the oAuth process on Twitter, you can use the GetTwitterUserNameAsync(string webAuthResultResponseData) method from my former blog post. If you are not using other methods to control the result of the WAB, don’t forget to set appObject.WABContinuationArgs to null after you finished obtaining all tokens and data from Twitter (or other services).

As you can see, there are some structural differences in using the WAB when creating a Silverlight app, but we are also able to use a lot of code from my Runtime project. I hope this post is helpful for some of you to get the oAuth dance going.

In my next post, I will show you how to authenticate your app with Yammer (Microsoft’s enterprise social network).

Until then, happy coding!

Posted by msicc in Archive, 3 comments