diff --git a/README.md b/README.md index 780156e..ac269cb 100644 --- a/README.md +++ b/README.md @@ -1 +1,47 @@ # projectFlock + +a twitter botnet with bots replying tweets with text generated by Markov chains + +##### generating text with Markov chains +The algorithm calculates the probabilities of Markov chains, analyzing a considerable amount of text, for the examples, I've done it with the book "The Critique of Pure Reason", by Immanuel Kant (http://www.gutenberg.org/cache/epub/4280/pg4280.txt). + +#### Replying tweets with Markov chains +When the botnet is up working, the bots start streaming all the twitter new tweets containing the configured keywords. Each bot takes a tweet, analyzes the containing words, and generates a reply using the Markov chains previously calculated, and posts the tweet as reply. + +In the following examples, the bots ("andreimarkov", "dodecahedron", "projectNSA") are replying some people. + +![Argos](https://raw.githubusercontent.com/arnaucode/projectFlock/master/screenshots/01.png "01") + +![Argos](https://raw.githubusercontent.com/arnaucode/projectFlock/master/screenshots/02.jpeg "02") + +![Argos](https://raw.githubusercontent.com/arnaucode/projectFlock/master/screenshots/03.jpeg "03") + +![Argos](https://raw.githubusercontent.com/arnaucode/projectFlock/master/screenshots/04.jpeg "04") + + +configuration file example (flockConfig.json): +``` +[{ + "title": "account1", + "consumer_key": "xxxxxxxxxxxxx", + "consumer_secret": "xxxxxxxxxxxxx", + "access_token_key": "xxxxxxxxxxxxx", + "access_token_secret": "xxxxxxxxxxxxx" + }, + { + "title": "account2", + "consumer_key": "xxxxxxxxxxxxx", + "consumer_secret": "xxxxxxxxxxxxx", + "access_token_key": "xxxxxxxxxxxxx", + "access_token_secret": "xxxxxxxxxxxxx" + }, + { + "title": "account3", + "consumer_key": "xxxxxxxxxxxxx", + "consumer_secret": "xxxxxxxxxxxxx", + "access_token_key": "xxxxxxxxxxxxx", + "access_token_secret": "xxxxxxxxxxxxx" + } +] + +``` diff --git a/optionMarkovFlockBotnet.go b/optionMarkovFlockBotnet.go index 555b8b9..7345e97 100644 --- a/optionMarkovFlockBotnet.go +++ b/optionMarkovFlockBotnet.go @@ -11,11 +11,18 @@ import ( "github.com/dghubble/go-twitter/twitter" ) -func isRT(text string) bool { - tweetWords := strings.Split(text, " ") +func isRT(tweet *twitter.Tweet) bool { + tweetWords := strings.Split(tweet.Text, " ") for i := 0; i < len(tweetWords); i++ { if tweetWords[i] == "RT" { - c.Red(text) + return true + } + } + return false +} +func isFromBot(flock Flock, tweet *twitter.Tweet) bool { + for i := 0; i < len(flock.ScreenNames); i++ { + if flock.ScreenNames[i] == tweet.User.ScreenName { return true } } @@ -40,11 +47,11 @@ func processTweet(states []State, flockUser *twitter.Client, botScreenName strin replyTweet(flockUser, "@"+tweet.User.ScreenName+" "+generatedText, tweet.ID) waitTime(1) } -func startStreaming(states []State, flockUser *twitter.Client, botScreenName string, keywords []string) { +func startStreaming(states []State, flock Flock, flockUser *twitter.Client, botScreenName string, keywords []string) { // Convenience Demux demultiplexed stream messages demux := twitter.NewSwitchDemux() demux.Tweet = func(tweet *twitter.Tweet) { - if isRT(tweet.Text) == false { + if isRT(tweet) == false && isFromBot(flock, tweet) == false { processTweet(states, flockUser, botScreenName, keywords, tweet) } } @@ -101,7 +108,8 @@ func optionMarkovFlockBotnet(flock Flock) { case "y": fmt.Println("ok, you are sure") for i := 0; i < len(flock.Clients); i++ { - go startStreaming(states, flock.Clients[i], flock.ScreenNames[i], keywords) + go startStreaming(states, flock, flock.Clients[i], flock.ScreenNames[i], keywords) + waitSeconds(35) } break default: diff --git a/screenshots/01.png b/screenshots/01.png new file mode 100644 index 0000000..b32882a Binary files /dev/null and b/screenshots/01.png differ diff --git a/screenshots/02.jpeg b/screenshots/02.jpeg new file mode 100644 index 0000000..fd58f70 Binary files /dev/null and b/screenshots/02.jpeg differ diff --git a/screenshots/03.jpeg b/screenshots/03.jpeg new file mode 100644 index 0000000..a9641fb Binary files /dev/null and b/screenshots/03.jpeg differ diff --git a/screenshots/04.jpeg b/screenshots/04.jpeg new file mode 100644 index 0000000..a627645 Binary files /dev/null and b/screenshots/04.jpeg differ diff --git a/waitTime.go b/waitTime.go index f4e293f..0032383 100644 --- a/waitTime.go +++ b/waitTime.go @@ -13,3 +13,10 @@ func waitTime(minutes int) { fmt.Println(time.Now().Local()) time.Sleep(timeToSleep) } +func waitSeconds(seconds int) { + //wait to avoid the twitter api limitation + timeToSleep := time.Duration(seconds) * time.Second + fmt.Println("waiting " + strconv.Itoa(seconds) + " seconds") + fmt.Println(time.Now().Local()) + time.Sleep(timeToSleep) +}