avoiding reply to other bots of the botnet, and readme explanation

This commit is contained in:
arnaucode
2017-04-23 20:20:45 +02:00
parent 938db1f2cf
commit 32987c2a79
7 changed files with 67 additions and 6 deletions

View File

@@ -1 +1,47 @@
# projectFlock # 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"
}
]
```

View File

@@ -11,11 +11,18 @@ import (
"github.com/dghubble/go-twitter/twitter" "github.com/dghubble/go-twitter/twitter"
) )
func isRT(text string) bool { func isRT(tweet *twitter.Tweet) bool {
tweetWords := strings.Split(text, " ") tweetWords := strings.Split(tweet.Text, " ")
for i := 0; i < len(tweetWords); i++ { for i := 0; i < len(tweetWords); i++ {
if tweetWords[i] == "RT" { 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 return true
} }
} }
@@ -40,11 +47,11 @@ func processTweet(states []State, flockUser *twitter.Client, botScreenName strin
replyTweet(flockUser, "@"+tweet.User.ScreenName+" "+generatedText, tweet.ID) replyTweet(flockUser, "@"+tweet.User.ScreenName+" "+generatedText, tweet.ID)
waitTime(1) 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 // Convenience Demux demultiplexed stream messages
demux := twitter.NewSwitchDemux() demux := twitter.NewSwitchDemux()
demux.Tweet = func(tweet *twitter.Tweet) { 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) processTweet(states, flockUser, botScreenName, keywords, tweet)
} }
} }
@@ -101,7 +108,8 @@ func optionMarkovFlockBotnet(flock Flock) {
case "y": case "y":
fmt.Println("ok, you are sure") fmt.Println("ok, you are sure")
for i := 0; i < len(flock.Clients); i++ { 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 break
default: default:

BIN
screenshots/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
screenshots/02.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
screenshots/03.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
screenshots/04.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@@ -13,3 +13,10 @@ func waitTime(minutes int) {
fmt.Println(time.Now().Local()) fmt.Println(time.Now().Local())
time.Sleep(timeToSleep) 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)
}