Browse Source

cleaned code, and better structured design, need stop() the stream after tweet

master
arnaucode 5 years ago
parent
commit
ac88c9128e
10 changed files with 154 additions and 211 deletions
  1. +1
    -0
      .gitignore
  2. +0
    -57
      color.go
  3. +9
    -0
      errors.go
  4. +19
    -0
      log.go
  5. +38
    -14
      main.go
  6. +0
    -54
      readConfigTokensAndConnect.go
  7. +61
    -0
      readConfigurations.go
  8. +0
    -19
      readKeywordsConfig.go
  9. +0
    -19
      readRepliesConfig.go
  10. +26
    -48
      streamTweets.go

+ 1
- 0
.gitignore

@ -30,3 +30,4 @@ repliesConfig.json
keywordsConfig.json
temp
text.txt
logs

+ 0
- 57
color.go

@ -1,57 +0,0 @@
package main
import "fmt"
//Color struct, defines the color
type Color struct{}
var c Color
//DarkGray color
func (c Color) DarkGray(t string) {
fmt.Print("\x1b[30;1m") //dark gray
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Red color
func (c Color) Red(t string) {
fmt.Print("\x1b[31;1m") //red
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Green color
func (c Color) Green(t string) {
fmt.Print("\x1b[32;1m") //green
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Yellow color
func (c Color) Yellow(t string) {
fmt.Print("\x1b[33;1m") //yellow
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Blue color
func (c Color) Blue(t string) {
fmt.Print("\x1b[34;1m") //blue
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Purple color
func (c Color) Purple(t string) {
fmt.Print("\x1b[35;1m") //purple
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Cyan color
func (c Color) Cyan(t string) {
fmt.Print("\x1b[36;1m") //cyan
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}

+ 9
- 0
errors.go

@ -0,0 +1,9 @@
package main
import "log"
func check(err error) {
if err != nil {
log.Println(err)
}
}

+ 19
- 0
log.go

@ -0,0 +1,19 @@
package main
import (
"io"
"log"
"os"
"time"
)
func savelog() {
timeS := time.Now().String()
_ = os.Mkdir("logs", os.ModePerm)
logFile, err := os.OpenFile("logs/log-"+timeS+".log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if err != nil {
panic(err)
}
mw := io.MultiWriter(os.Stdout, logFile)
log.SetOutput(mw)
}

+ 38
- 14
main.go

@ -1,28 +1,52 @@
package main
import "fmt"
import (
"fmt"
"log"
"strconv"
"time"
"github.com/fatih/color"
)
const version = "0.1-dev"
func main() {
c.Yellow("echo-botnet")
savelog()
color.Blue("echo-botnet")
fmt.Println("---------------")
c.Cyan("echo-botnet initialized")
c.Purple("https://github.com/arnaucode/echo-botnet")
fmt.Println("version " + version)
color.Cyan("echo-botnet initialized")
color.Green("https://github.com/arnaucode/echo-botnet")
log.Println("version " + version)
keywords := readKeywordsConfig()
c.Cyan("keywords configured: ")
readKeywordsConfig()
color.Cyan("keywords configured: ")
fmt.Println(keywords)
replies := readRepliesConfig()
c.Cyan("replies configured: ")
readRepliesConfig()
color.Cyan("replies configured: ")
fmt.Println(replies)
fmt.Println("Reading botsConfig.json file")
botnet := readConfigTokensAndConnect()
c.Cyan("[list of configured bots]:")
for _, v := range botnet.ScreenNames {
c.Cyan(v)
readConfigTokensAndConnect()
color.Cyan("[list of configured bots]:")
for _, bot := range botnet {
color.Cyan(bot.Title)
}
var i int
for {
color.Red(strconv.Itoa(i))
sinceTweeted := time.Unix(botnet[i].SinceTweeted, 0)
elapsed := time.Since(sinceTweeted)
fmt.Println(elapsed)
if elapsed.Seconds() > 60 {
log.Println("starting to use bot: " + botnet[i].Title)
startStreaming(botnet[i])
} else {
log.Println("bot: " + botnet[i].Title + " not used due bot is in waiting time")
}
i++
if i > len(botnet)-1 {
i = 0
}
}
streamTweets(botnet, keywords, replies)
}

+ 0
- 54
readConfigTokensAndConnect.go

@ -1,54 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"github.com/dghubble/go-twitter/twitter"
"github.com/dghubble/oauth1"
)
//Config stores the data from json botsConfig.json file
type Config struct {
Title string `json:"title"`
ConsumerKey string `json:"consumer_key"`
ConsumerSecret string `json:"consumer_secret"`
AccessTokenKey string `json:"access_token_key"`
AccessTokenSecret string `json:"access_token_secret"`
}
//Botnet stores each bot configured
type Botnet struct {
ScreenNames []string
Clients []*twitter.Client
}
func readConfigTokensAndConnect() (botnet Botnet) {
var config []Config
var clients []*twitter.Client
file, e := ioutil.ReadFile("botsConfig.json")
if e != nil {
fmt.Println("error:", e)
}
content := string(file)
json.Unmarshal([]byte(content), &config)
fmt.Println("botnetConfig.json read comlete")
fmt.Print("connecting to twitter api --> ")
for i := 0; i < len(config); i++ {
configu := oauth1.NewConfig(config[i].ConsumerKey, config[i].ConsumerSecret)
token := oauth1.NewToken(config[i].AccessTokenKey, config[i].AccessTokenSecret)
httpClient := configu.Client(oauth1.NoContext, token)
// twitter client
client := twitter.NewClient(httpClient)
clients = append(clients, client)
botnet.ScreenNames = append(botnet.ScreenNames, config[i].Title)
}
botnet.Clients = clients
fmt.Println("connection successful")
return botnet
}

+ 61
- 0
readConfigurations.go

@ -0,0 +1,61 @@
package main
import (
"encoding/json"
"io/ioutil"
"log"
"github.com/dghubble/go-twitter/twitter"
"github.com/dghubble/oauth1"
)
//Bot stores the data from json botsConfig.json file
type Bot struct {
Title string `json:"title"`
ConsumerKey string `json:"consumer_key"`
ConsumerSecret string `json:"consumer_secret"`
AccessTokenKey string `json:"access_token_key"`
AccessTokenSecret string `json:"access_token_secret"`
Client *twitter.Client
SinceTweeted int64 `json:"sincetweeted"`
Blocked bool `json:"blocked"`
SinceBlocked int64 `json:"sinceblocked"`
}
var botnet []Bot
var keywords []string
var replies []string
func readConfigTokensAndConnect() {
file, err := ioutil.ReadFile("botsConfig.json")
check(err)
content := string(file)
json.Unmarshal([]byte(content), &botnet)
log.Println("botnetConfig.json read comlete")
log.Print("connecting to twitter api")
for k, _ := range botnet {
configu := oauth1.NewConfig(botnet[k].ConsumerKey, botnet[k].ConsumerSecret)
token := oauth1.NewToken(botnet[k].AccessTokenKey, botnet[k].AccessTokenSecret)
httpClient := configu.Client(oauth1.NoContext, token)
// twitter client
client := twitter.NewClient(httpClient)
botnet[k].Client = client
botnet[k].Blocked = false
}
log.Println("connection successful")
}
func readKeywordsConfig() {
file, err := ioutil.ReadFile("keywordsConfig.json")
check(err)
content := string(file)
json.Unmarshal([]byte(content), &keywords)
}
func readRepliesConfig() {
file, err := ioutil.ReadFile("repliesConfig.json")
check(err)
content := string(file)
json.Unmarshal([]byte(content), &replies)
}

+ 0
- 19
readKeywordsConfig.go

@ -1,19 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
)
func readKeywordsConfig() []string {
var keywords []string
file, e := ioutil.ReadFile("keywordsConfig.json")
if e != nil {
fmt.Println("error:", e)
}
content := string(file)
json.Unmarshal([]byte(content), &keywords)
return keywords
}

+ 0
- 19
readRepliesConfig.go

@ -1,19 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
)
func readRepliesConfig() []string {
var replies []string
file, e := ioutil.ReadFile("repliesConfig.json")
if e != nil {
fmt.Println("error:", e)
}
content := string(file)
json.Unmarshal([]byte(content), &replies)
return replies
}

+ 26
- 48
streamTweets.go

@ -4,11 +4,11 @@ import (
"fmt"
"log"
"math/rand"
"strconv"
"strings"
"time"
"github.com/dghubble/go-twitter/twitter"
"github.com/fatih/color"
)
func isRT(tweet *twitter.Tweet) bool {
@ -20,9 +20,9 @@ func isRT(tweet *twitter.Tweet) bool {
}
return false
}
func isFromOwnBot(flock Botnet, tweet *twitter.Tweet) bool {
for i := 0; i < len(flock.ScreenNames); i++ {
if flock.ScreenNames[i] == tweet.User.ScreenName {
func isFromBotnet(tweet *twitter.Tweet) bool {
for i := 0; i < len(botnet); i++ {
if botnet[i].Title == tweet.User.ScreenName {
return true
}
}
@ -40,39 +40,33 @@ func replyTweet(client *twitter.Client, text string, inReplyToStatusID int64) {
InReplyToStatusID: inReplyToStatusID,
})
if err != nil {
fmt.Println(err)
log.Println(err)
}
if httpResp.Status != "200 OK" {
c.Red("error: " + httpResp.Status)
c.Purple("maybe twitter has blocked the account, CTRL+C, wait 15 minutes and try again")
color.Red("error: " + httpResp.Status)
log.Println("error" + httpResp.Status)
color.Cyan("maybe twitter has blocked the account, CTRL+C, wait 15 minutes and try again")
log.Println("maybe twitter has blocked the account, CTRL+C, wait 15 minutes and try again")
}
fmt.Print("tweet posted: ")
c.Green(tweet.Text)
log.Println("tweet posted: " + tweet.Text)
}
func startStreaming(botnet Botnet, bot *twitter.Client, botScreenName string, keywords []string, replies []string) {
func startStreaming(bot Bot) {
// Convenience Demux demultiplexed stream messages
demux := twitter.NewSwitchDemux()
demux.Tweet = func(tweet *twitter.Tweet) {
if isRT(tweet) == false && isFromOwnBot(botnet, tweet) == false {
if isRT(tweet) == false && isFromBotnet(tweet) == false {
//processTweet(botnetUser, botScreenName, keywords, tweet)
fmt.Println("[bot @" + botScreenName + "] - New tweet detected:")
c.Yellow(tweet.Text)
log.Println("[bot @" + bot.Title + "] - New tweet detected:")
log.Println(tweet.Text)
reply := getRandomReplyFromReplies(replies)
fmt.Print("reply: ")
c.Green(reply)
fmt.Println(tweet.User.ScreenName)
fmt.Println(tweet.ID)
replyTweet(bot, "@"+tweet.User.ScreenName+" "+reply, tweet.ID)
waitMinutes(1)
log.Println("reply: " + reply + ", to: @" + tweet.User.ScreenName /* + ". tweet ID: " + tweet.ID*/)
//replyTweet(bot, "@"+tweet.User.ScreenName+" "+reply, tweet.ID)
color.Green("replying tweet!")
bot.SinceTweeted = time.Now().Unix()
}
}
demux.DM = func(dm *twitter.DirectMessage) {
fmt.Println(dm.SenderID)
}
demux.Event = func(event *twitter.Event) {
fmt.Printf("%#v\n", event)
}
fmt.Println("Starting Stream...")
// FILTER
@ -80,29 +74,13 @@ func startStreaming(botnet Botnet, bot *twitter.Client, botScreenName string, ke
Track: keywords,
StallWarnings: twitter.Bool(true),
}
stream, err := bot.Streams.Filter(filterParams)
if err != nil {
log.Fatal(err)
}
stream, err := bot.Client.Streams.Filter(filterParams)
check(err)
// Receive messages until stopped or stream quits
demux.HandleChan(stream.Messages)
// Wait for SIGINT and SIGTERM (HIT CTRL-C)
/*ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
log.Println(<-ch)
fmt.Println("Stopping Stream...")
stream.Stop()*/
}
func streamTweets(botnet Botnet, keywords []string, replies []string) {
fmt.Println("total keywords: " + strconv.Itoa(len(keywords)))
c.Purple("keywords to follow: ")
fmt.Println(keywords)
c.Green("Starting to stream tweets")
for i := 0; i < len(botnet.Clients); i++ {
go startStreaming(botnet, botnet.Clients[i], botnet.ScreenNames[i], keywords, replies)
//wait 35 seconds to start the next bot
waitSeconds(35)
}
/*for message := range stream.Messages {
demux.Handle(message)
log.Println("stopping stream")
stream.Stop()
}*/
}

Loading…
Cancel
Save