How to run a code when a given user tweets something?

Dec 7, 2013 at 11:52 PM
Hi!
I am new to using this API so I could really use an example code.
I'd like to know how to run a piece of code when a given user Tweets something.
If some one could give me an example program, something really small so I can understand how it works, It will be much appreciated.

I want to make a little program that gives you notification when a select user tweets something without having to log in.
Dec 8, 2013 at 1:47 AM
Hi there,

If you download the source code, you will find a project named Examplinvi.
In this project you will have an example for all the functions provided within the API.

In your case, you want to use the UserStream.
IToken token = new Token("xxx", "xxx", "xxx", "xxx"); // Set your credentials here.
IUserStream us = new UserStream();
us.TweetCreatedByAnyone += (sender, args) =>
{
    Console.WriteLine("Tweet '{0}' created!", args.Value.Text);
};
us.StartStream(token);
This piece of code will write in the console the text of all the tweets created by a user that is related to you.

Hope this helps you.
Kind Regards,
Linvi
Dec 8, 2013 at 7:20 AM
Edited Dec 8, 2013 at 7:20 AM
Hey, thanks for the reply!
But I am a bit confused.
Can I specify which user to fetch tweets from?
And can I just use Twitter Application Credentials (consumer key, access token etc.) instead of user credentials?
Dec 8, 2013 at 7:20 PM
Hi,

Can I specify which user to fetch tweets from?

Tweetinvi does not provide this feature by default because it is not provided by Twitter.
All depends on what you want to do. If you wish to receive the tweets from users that you are following, you need to use the UserStream and use the code above.
If you want to limit the scope of users you want to follow, just create a list of users you want to follow and check if they sent a message or not.

Here is the updated code :
IToken token = new Token("xxx", "xxx", "xxx", "xxx"); // Set your credentials here.
List<IUser> myFriendsToUpdate = new List<IUser>
{
    new User("myFriend1"),
    new User("myFriend2")
};

IUserStream us = new UserStream();
us.TweetCreatedByAnyone += (sender, args) =>
{
    var senderScreenName = args.Value.Creator.ScreenName;
    if (myFriendsToUpdate.Select(x => x.ScreenName).Contains(senderScreenName))
    {
        Console.WriteLine("Tweet '{0}' created!", args.Value.Text);
    }
};
us.StartStream(token);
I think this is a good suggestion and will implement this feature for the future version of the UserStream (but not in the nearby future).
I have consequently added a feature to the list of work items that you can find here : https://tweetinvi.codeplex.com/workitem/1936.

And can I just use Twitter Application Credentials (consumer key, access token etc.) instead of user credentials?

No you can't and never will be able to because Twitter requires the user to provide both the Application and the User credential. There is now way to only provide the application credentials for this kind of feature.

Hope this helps.
Kind Regards,
Linvi
Dec 8, 2013 at 8:45 PM
Thanks for the Reply again, I am beginning to understand things now.
But I just have a few more questions and a little problem (below)

From what I understood so far I prepared this code:
            IToken token = new Token("My Access token", "My Access token secret", "My Consumer key", "My Consumer secret"); // Set your credentials here.
            List<IUser> myFriendsToUpdate = new List<IUser>
            {
                new User("someoneimportant"),
            };

            IUserStream us = new UserStream();
            us.TweetCreatedByAnyone += (sender, args) =>
            {
                var senderScreenName = args.Value.Creator.ScreenName;
                if (myFriendsToUpdate.Select(x => x.ScreenName).Contains(senderScreenName))
                {
                    Console.WriteLine("someoneimportant just tweeted something!");
                }
            };
            us.StartStream(token);
This is the code I tried.
But it did not work.

Problems:
  • Problem 1 - A local variable named 'sender' cannot be declared in this scope because it would give a different meaning to 'sender', which is already used in a 'parent or current' scope to denote something else.
  • Problem 2 - The program would freeze once I run the command above.
Questions:
  • Question 1 - Is my way of writing the tokens and keys wrong? If so Did I mess up the order or what I had to write?
  • Question 2 - Do I need to run the code once or do I need to keep refreshing it. I would imagine that I would have to run it once since it constantly fetches data from the stream.
  • Question 3 - Is it normal that my Program Freezes? Can I run the code above and still maintain functionality for the rest of the form? (I am using Windows Forms)
PS - Currently I am trying to Bind the code above to a button.
PSS - I used Console Write Line above to keep it simple.
Dec 9, 2013 at 12:36 AM
Hi again,

Problem 1 - A local variable named 'sender' cannot be declared in this scope because it would give a different meaning to 'sender', which is already used in a 'parent or current' scope to denote something else.
sender already existing here us.TweetCreatedByAnyone += (sender, args) => it is in fact the sender of the event not the sender of the tweet. The sender of the tweet can be retrieved like that args.Value.Creator.

Problem 2 - The program would freeze once I run the command above.
The program does not freeze. It basically waits a reply for the stream to close. While the stream is open you are receiving information from Twitter.
You can make the stream run in another thread if you wish a program to run at the same time.

Question 1 - Is my way of writing the tokens and keys wrong? If so Did I mess up the order or what I had to write?
No it seems perfectly alright.

Question 2 - Do I need to run the code once or do I need to keep refreshing it. I would imagine that I would have to run it once since it constantly fetches data from the stream.
Yes as it is a stream you just have to run it once. Also you can pause or stop the stream. In which case you will have to resume/restart it.

Question 3 - Is it normal that my Program Freezes? Can I run the code above and still maintain functionality for the rest of the form? (I am using Windows Forms)
As I said before, you need to run your code in a separate thread. Consequently if you are using Windows Forms, simply put this code in a BackgroundWorker.

PS - Currently I am trying to Bind the code above to a button.
There should not be any relation. If your code is bound to a button. Create a command calling a function that uses a background worker containing your code.

PSS - I used Console Write Line above to keep it simple.
In that case, a new thread would be more appropriate than a Background worker.

Here is an example with a thread (infinite).
List<IUser> myFriendsToUpdate = new List<IUser>
    {
        new User("myFriend1"),
        new User("myFriend2")
    };

IUserStream us = new UserStream();
us.TweetCreatedByAnyone += (sender, args) =>
{
    var senderScreenName = args.Value.Creator.ScreenName;
    if (myFriendsToUpdate.Select(x => x.ScreenName).Contains(senderScreenName))
    {
        Console.WriteLine("Tweet '{0}' created!", args.Value.Text);
    }
};

Thread t = new Thread(() =>
{
    us.StartStream(token);
});

t.Start();
Dec 9, 2013 at 9:01 AM
Okay so I finally set everything up and this is quote from my final code which compiles but doesnt do what it is supposed to.

        private void button1_Click(object sender, EventArgs e)
        {

            IToken token = new Token("My Access token", "My Access token secret", "My Consumer key", "My Consumer secret"); // Set your credentials here.
            List<IUser> myFriendsToUpdate = new List<IUser>
            {
                new User("USERX"),
                new User("USERY")
            };

            IUserStream us = new UserStream();
            us.TweetCreatedByAnyone += (s, args) =>
            {
                var senderScreenName = args.Value.Creator.ScreenName;
                if (myFriendsToUpdate.Select(x => x.ScreenName).Contains(senderScreenName))
                {
                    web_main.Navigate("http://google.com");
                }
            };

            Thread t = new Thread(() =>
            {
                us.StartStream(token);
            });

            t.Start();
        }
I tweeted from the USERY account and the program was supposed to navigate the built in web browser to google.com
It didnt.

So I have 2 questions (sorry I know I am getting annoying):
1 - How long does it take for the API to Fetch data
2 - Did I (again) borked something up in my code?
Dec 9, 2013 at 10:13 AM
Edited Dec 9, 2013 at 10:34 AM
Don't worry the forum is here to respond to the developer's questions :)

1 - How long does it take for the API to Fetch data
It should take approximately less than a second to receive the information from the stream.

2 - Did I (again) borked something up in my code?
No you did not and the code you wrote is good.
By looking at the code I can see 2 things going wrong
  • The user screenName you provided is incorrect. Twitter differentiate the ScreenName from the UserName. The username is what you see on twitter. The screenName is a unique identifier of a specific user. They can be different. So please verify that you are using the ScreenName.
  • By writing the code I did not thought about case sensitivity. It implies that if the user screenName does not match the casing provided in the list, it will fail. Here is the updated code.
IToken token = new Token("My Access token", "My Access token secret", "My Consumer key", "My Consumer secret"); // Set your credentials here.
List<IUser> myFriendsToUpdate = new List<IUser>
{
    new User("USERX"),
    new User("USERY")
};

IUserStream us = new UserStream();
us.TweetCreatedByAnyone += (s, args) =>
{
    var senderScreenName = args.Value.Creator.ScreenName;
    if (myFriendsToUpdate.Select(x => x.ScreenName.ToLower()).Contains(senderScreenName.ToLower()))
    {
        Console.WriteLine("message!");
    }
};

Thread t = new Thread(() =>
{
    us.StartStream(token);
});

t.Start();
Please feel free to ask any other question. I do not mind helping developers ;)
Kind Regards,
Linvi
Marked as answer by linvi on 12/20/2013 at 9:12 AM
Dec 9, 2013 at 3:55 PM
Edited Dec 9, 2013 at 4:32 PM
Okay, so I tried and tried and changes stuff around to get it to work, but I just wont do anything.
I am going to post my entire code here and only rename tokens and twitter user and I will use a celebrity twitter screenName.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using oAuthConnection;
using Streaminvi;
using TweetinCore.Enum;
using TweetinCore.Events;
using TweetinCore.Interfaces;
using TweetinCore.Interfaces.oAuth;
using TweetinCore.Interfaces.StreamInvi;
using TweetinCore.Interfaces.TwitterToken;
using Tweetinvi;
using Tweetinvi.Model;
using TwitterToken;
using UILibrary;



namespace MyProgramName
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            
        }

        protected override void OnResize(EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.ShowInTaskbar = false;
            }
        }

        private void button_tw1_Click(object sender, EventArgs e)
        {
            web_main.Navigate("http://Bing.coml");
            notifyIconMain.BalloonTipText = "Loading Bing";
            notifyIconMain.BalloonTipIcon = ToolTipIcon.Info;
            notifyIconMain.ShowBalloonTip(3000);
        }

        private void button_tw2_Click(object sender, EventArgs e)
        {
            web_main.Navigate("http://Yahoo.com");
            notifyIconMain.BalloonTipText = "Loading Yahoo";
            notifyIconMain.BalloonTipIcon = ToolTipIcon.Info;
            notifyIconMain.ShowBalloonTip(3000);
        }

        private void notifyIconMain_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.ShowInTaskbar = true;
        }

        private void button_fetch_Click(object sender, EventArgs e)
        {

            IToken token = new Token("My Access token", "My Access token secret", "My Consumer key", "My Consumer secret"); // Set your credentials here.
            List<IUser> myFriendsToUpdate = new List<IUser>
            {
                new User("BillGates")
            };

            IUserStream us = new UserStream();
            us.TweetCreatedByAnyone += (s, args) =>
            {
                var senderScreenName = args.Value.Creator.ScreenName;
                if (myFriendsToUpdate.Select(x => x.ScreenName.ToLower()).Contains(senderScreenName.ToLower()))
                {
                    web_main.Navigate("http://google.com");
                }
            };

            Thread t = new Thread(() =>
            {
                us.StartStream(token);
            });

            t.Start();
        }
    }
}
In this case I choose @billgates, when ever he tweets something it should load google but I obviously borked something once again and it just wont,
I renamed some of the stuff above, mostly strings.
On my end I am using a test Twitter account to try my program, and I tweet random stuff to see if the thing would work, it wont.

I got my tokens and Consumer keys from my DEV application from Twitter.
This is how the link looks like https://dev.twitter.com/apps/XXXXX/show

All that and I still failed.
Dec 9, 2013 at 5:03 PM
Is the twitter account providing the credentials follows BillGates? Because, as I said, you must follow a user from which you want to catch events like new tweets.
Dec 9, 2013 at 5:14 PM
yes in that case I am using my own Dev Tokens and stuff and I am following him
Dec 9, 2013 at 9:15 PM
Hi,

Please find a project example doing exactly what you are looking for.
Download - IAmListeningToYOU!

The project works perfectly well. If you have any issue with this project it would either be related with your credentials or the fact that you have not followed the user.

Kind Regards,
Linvi
Dec 10, 2013 at 2:23 PM
I've sent you a private message, please do check it out.