» Evvvvil Tweet Engine
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

Evvvvil Tweet Engine

plugin network twitter
Credits: evvvvil

about

Evvvvil Tweet Engine brings most of the Twitter REST API to vvvv. Authorize, search, publish, favourite or retweet tweets and even spam twitter with batch actions that can send hundreds of tweets in one click. Other cool features include: geo localised search, time interval search, posting with pictures or geo coordinates, reply to tweets, destroy tweets, etc...

Please watch this tutorial video to learn how to use this Twitter engine:

https://vimeo.com/111038984

Plugin written by evvvvil in C# with the TweetINVI API.

Changes since the video has been made:

  • Cancel search action button added so you can cancel if search is taking too long
  • All actions are finished bang, so you can know when all the batch actions have been done, not just each individual action.

Upcoming features:

  • Add a failed action bang to let you know when an action has failed, not just been done.

Feel free to use my website and callback url when creating your application:
Website: http://frogandbone.com/twitterWelcome.html
Callback URL: https://frogandbone.com/twitterCallback.html

Please report any bugs or new feature requests on this page.

Keep it gritty, evvvvil.

download

EvvvvilTweetEngine_1.0.zip
08.11.14 [16:25 UTC] by evvvvil | 930 downloads

lecloneur 08/11/2014 - 19:30

Maaaaaaassive

h99 09/11/2014 - 16:34

I was thinking about this project this very morning and then I see the shout, and then I fly to vimeo and Ha! I lost it at the "machine gun mode".
>43 min tutorial! WTF?!
Great... And thank you.

evvvvil 09/11/2014 - 20:11

Thankx guys much appreciated, hope the plugin is at least as massive as that kid in the picture ;)
Yeah the tutorial is bit long but covers everything even how to create twitter application as you've seen, which is pretty basic, but can get confusing for non tweet-heads, what tokens are etc... Anyway thankx a lot hope you find it useful and feel free to report any bug or new feature requests I am open to make this even better.

PLEASE NOTE: If you are replying in batch to many tweets then the time interval should be pretty high and make sure you have a lot of possible randomize replies because, well I just got banned AGAIN yesterday at 5 seconds interval without randomize though, for replying to 50 tweets. You basically start getting "FAILED!..." after about 15 replies... It would be nice if you guys could let me know how it works for you as it's hard to test. I will do further testing but last time I checked I was banned from replying again. lol this a lot of fun though :)

It would be nice to find out what the machine gun mode time interval should be for replying in batch, seems for the rest it's fine to keep it low but replying is a bitch...

Anyway peace :)

korriander 09/11/2014 - 23:47

Great Work!
This Node is really excellent. Do think you could share some examples how you implemented everything asynchronous?

manolito 10/11/2014 - 10:53

Great news. Thanks for sharing and the in depth video!

evvvvil 10/11/2014 - 13:37

@korriander: Sure bro, actually the key is making your code "Multi-threaded" more than "asynchronous". Multi-threading means you have one thread running with what you need to do in your plugin and you leave another cpu thread, the main thread, for vvvv to run it's user interface and other calculation stuff, I think it's even called the "ui" thread. ANYWAYS essentially it's very simple to convert your code from single threaded to multi-threaded. Let's say you have a function called DoSomething(), and usually you simply call it like this:

DoSomething();

To make this multi threaded, You need to create a task and cancellation token as global variables at top of your code, like this:

public CancellationTokenSource DoSomethingToken;
public Task DoSomethingTask;

Then instead of calling "DoSomething()" simply use these 3 lines of code:

DoSomethingToken = new CancellationTokenSource();
DoSomethingTask = new Task(DoSomething, DoSomethingToken.Token);
DoSomethingTask.Start();

And that's it! It will now leave main cpu thread for vvvv to run and vvvv will not stop or halt or stutter when you call DoSomething().
The great thing about multi-threading is that you can make a task "wait" and also "cancel it from running", which is why we need a cancellation token.

Here is how to make a task "wait":

DoSomethingTask.Wait(1000,DoSomethingToken.Token); //1000 is int and is time in ms

Here is how to cancel a task, with a check to see if it is running or not(if it's not running/has finished running then no point in cancelling it)

if (DoSomethingTask != null && DoSomethingTask.Status == TaskStatus.Running)
{
DoSomethingToken.Cancel();
}

And finally here is the code I actually use instead of simply calling "DoSomething()" it's the same as I put above but it just has similar check to see if the action is running already or not:

if ((DoSomethingTask != null && DoSomethingTask.Status == TaskStatus.Running))
{
     FLogger.Log(LogType.Debug, "Action already running bro"); 
     //Tell debugger you're already running an action and you could tell an output pin named "FoutputStatus" like this:
     FOutputStatus[0]="Action already running bro";
}
else
{
     DoSomethingToken = new CancellationTokenSource();
     DoSomethingTask = new Task(DoPublish, DoSomethingToken.Token);
     DoSomethingTask.Start();
}

You might need to change a bool global variable when you cancel, something like this: "DoSomethingCanceled = true" and then if you are running a loop in your DoSomething() function just add a a check at beginning/end of loop like that:

if(DoSomethingCanceled){ break; }

There you go bro, I hope it helps, let me know if it makes sense otherwise can explain in more detail. You can do more with mutli-threading but involves linq/lambda notation and is a lot more complicated, this is the easiest multi-theading implementation I think, keep it simple, innit? Peace

korriander 10/11/2014 - 16:14

@evvvil
thnx for the detailed explanation! I will try to wrap my head around and and apply it to my nodes...

digitalwannabe 13/11/2014 - 14:54

@evvvvil: great plugin and even better tutorial!

also, thanks for all that information on threading! Have you maybe also got information/example code which you can share on threading functions which need parameters:

eg
DoSomething (int param1, int param2){
.....
}

afaik it should be done with a lambda expression then, but i can't get it to work: threaded-generic-nodes-big-integer-data-type

any hints much appreciated, thanks in advance!

evvvvil 13/11/2014 - 17:31

Ah yes I can help, I had same problem: basically I couldn't get the task with lambda notation and parameters to work as well. So the trick is simply to have your parameters as global variables start a task with a function with no parameters, which then uses those global variables inside function instead of parameters...

Actually well fuck it I might as well paste the whole code for everyone to see, this is a working c# multi-threaded plugin node with 3 input pins. First is a bang which when you bang it simply runs Dosomething function then another input pin which expects a spread of 2 numbers, you know x,y kinda thing parameters to dosomething, so like in comment above DoSomething(param1, param2... Finally last input pin is to cancel the current action running as it is multi-threaded we should be able to cancel. It also has a output pin showing result of DoSomething and another output pin giving your status message on the action.

patrick
//bunch of usings, more that you need but pay attention to System.Threading, etc
using System;
using System.Net;
using System.Configuration;
using System.ComponentModel.Composition;
using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VColor;
using VVVV.Utils.VMath;
using VVVV.Core.Logging;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Timers;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime;
using System.Runtime.InteropServices;
 
 
namespace VVVV.Nodes
{
    [PluginInfo(Name = "DoSomethingNode", Help = "nada", Tags = "tags", Author="evvvvil")]
 
    public class DoSomethingNode : IPluginEvaluate
    {
        [Input("Do Something", IsBang = true, IsSingle = true)]
        public ISpread<bool> FInputDoSomething;
 
        [Input("Do Something Param 1 & 2")]
        public ISpread<int> FInputDoSomethingParam;
 
        [Input("Cancel Do Something", IsBang = true, IsSingle = true)]
        public ISpread<bool> FInputCancel;
 
        [Output("Do Something Result")]
        public ISpread<int> FOutputDoSomething;
 
        [Output("Do Something Status")]
        public ISpread<string> FOutputStatus;
 
        //add connection to TTY renderer for debugging, like console
        [Import()]
        public ILogger FLogger;
 
        public CancellationTokenSource DoSomethingToken;
        public Task DoSomethingTask;
        public bool canceledTask;
 
        //define your dosomething(int param1... as global variables
        //we will set them before calling the function, see "evaluate"
        public int param1;
        public int param2;
 
        public void DoSomething(){
        canceledTask=false;
        //totally doing something with param1 & param2 too like in a loop
        int finalResult = 0;
        for (int i = 0; i < 1000; i++)
                {
                    finalResult += param1 * param2;
 
                    //this may or may not be necessary
                    if (canceledTask)
                    {
                        break;
                    }
                }
        //pass final result or pass 0 if it's been canceled
        if(!canceledTask){
        FOutputDoSomething[0]=finalResult;
        FOutputStatus[0] = "Nice one, result displayed.";
        FLogger.Log(LogType.Debug, "Nice one, result displayed.");
        }
        else{
        FOutputDoSomething[0]=0;
        }
        }
 
 
        public void Evaluate(int SpreadMax)
        {
 
            if (FInputDoSomething[0])
            {
                if ((DoSomethingTask != null && DoSomethingTask.Status == TaskStatus.Running))
                    {
                        FOutputStatus[0] = "Action already running bro";
                        FLogger.Log(LogType.Debug, "Action already running bro");
                    }
                    else
                    {
                        if(FInputDoSomethingParam.SliceCount==2){
                        param1 = FInputDoSomethingParam[0];
                        param2 = FInputDoSomethingParam[1];
                        DoSomethingToken = new CancellationTokenSource();
                        DoSomethingTask = new Task(DoSomething, DoSomethingToken.Token);
                        DoSomethingTask.Start();
                        }
                        else{
                        FOutputStatus[0] = "Bad number of parameters/slices in your spread";
                        FLogger.Log(LogType.Debug, "Bad number of parameters/slices in your spread");
                        }
                    }
            }
 
 
 
            if (FInputCancel[0])
            {
                bool boolo = false;
                if (DoSomethingTask != null && DoSomethingTask.Status == TaskStatus.Running)
                {
                    DoSomethingToken.Cancel();
                    canceledTask = true;
                    boolo = true;
                }
                if (!boolo)
                {
                    FOutputStatus[0] = "No action currently running, fuck face.";
                    FLogger.Log(LogType.Debug, "No action currently running, fuck face.");
                }else{
                    FOutputStatus[0] = "CANCELED! You are SO in control bro";
                    FLogger.Log(LogType.Debug, "CANCELED! You are SO in control bro");
                }
            }
         }        
    }   
}
digitalwannabe 16/11/2014 - 01:53

yeah, very cool, thanks for sharing the code & it's comments!

p.s. & for other readers: in the meantime elias also posted a solution to my original thread (link above)- very similar at first glance but didn't check in detail yet! might be of interest for you too!

thanks again!

digitalwannabe 16/11/2014 - 02:22

also, with swayze as representative, i suggest calling the function "DoSomethingAboutYourHair"...

h99 12/12/2014 - 20:03

Dirty Patching

evvvvil 30/01/2015 - 18:26

Ok I have put the SOURCE CODE ON GITHUB, find it here:

https://github.com/evvvvil/Evvvvil_Tweet_Engine

Please let me know about any new feature you can think of or any bugs you may find, peace.

idab 27/05/2015 - 18:14

Great job evvvvil! It works like a charm! Thanks!

hengge 09/07/2015 - 22:14

Great engine evvvvil!

Suggestion for an addition feature:
Add timeline search to the search plugin, so you can search for any tweets that have been tweeted by a specific user. Should be part of the REST API...Pedro knows how to do it.

omykron 17/09/2015 - 03:06

hey @evvvvil , I keep getting bad credential messages, both with dev and normal authorization, there's a new "Enable callback locking" button in the app details tab, tried enabling and disabling it but the same happens. Tried with both vvvv_45beta34.1_x86 and _x64

Not sure where to look for more information, When I open EvvvvilTweetEngine_example.v4p there's a nasty couldn't divide by zero there as soon as I open the patch (I've attached the tty Renderer output), but it doesn't appears when I open EvvvvilTweetEngine.v4p, I still get the Bad consumer key or secret, monsieur tete de bite.

http://imgur.com/0TeB9gA

Should I get a mullet? :o

update: Well, I should get half a mullet, tried it with vvvv45_beta33.7_x86 in win8.1 and worked GREAT, seems to fail in win10.

benja 29/10/2015 - 14:30

lovely work evvvvil, thanks'n'kisses

did run into some problems though,

I often get no search results. engine starts searching but that's about it.
Sometimes a restart of vvvv helps, sometimes rebooting helps, sometimes not even that for a couple of minutes.

If I try to search again, it keeps shouting at me to "Chill out bro it's already searching".
You did build in the new cancel search bang for that, but it doesnt, whatever I do to it, press it, shake it, squeeze it. Keeps telling me to "chill..."
Need to restart then. But often still get no search results.

(win7, vvvv_45beta34.1_x64)

And finally after not washing my nicely curled mullet for a month - I love the naturally greesy style - I started to get itchy dendruff.

Anything you can do about that? Workarounds? Cheers m8

TwoBeAss 18/11/2015 - 18:11

Great contribution bro!!

Is there a way to handle those emoticons ???

isdzaurov 29/03/2016 - 15:01

Hi evvvvil!

Can i connect your engine with instagram?
Or it work only with twitter?

Thank youuuuuuuuuuu!

dominikKoller 24/06/2017 - 20:14

Hey Evvvvil!

Thanks for the great contrib.

TweetSearch is working without problems for me. I'm having trouble with the TweetLogger and TweetAction.

Trying to login as dev first works, when klicking Refresh Login Status it says Logged In, but trying again after a few seconds says Not logged in any more.

TweetAction always sais Failed! Tweet was not published

Any ideas how to debug?

anonymous user login

Shoutbox

~4h ago

microdee: @fibo: vvvv is delphi in its core, it just interacts with .NET with com visible objects under the hood. VL on the other hand...

~1d ago

drupal_admin: hello. maintenance reboot at 1am. save your work. back in a few minutes

~1d ago

fibo: lol now AWS Lambda supports C# ... does it mean we will see vvvv cloud version?

~2d ago

joreg: @pdubost great, i'd love to see this in our gallery 24

~3d ago

skyliner: @pdubost: vvvvery good!

~3d ago

gerrit: Any recommendations for interesting / exciting booths at IAA? Any good media installations? Somebody made something with vvvv? Thx

~3d ago

microdee: @matka: nope because the SD card got full and we never received an empty one :(

~3d ago

matka: Do we have recordings of the second part of PBR Rendering workshop at NODE17?

~5d ago

pdubost: latest personal project thanks devs and @mrvux for Box2d :) https://vimeo.com/233756367