diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f07d5cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + + +flockConfig.json +build/flockConfig.json +temp diff --git a/build/flockConfigDEMO.json b/build/flockConfigDEMO.json new file mode 100644 index 0000000..551eeba --- /dev/null +++ b/build/flockConfigDEMO.json @@ -0,0 +1,22 @@ +[{ + "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/build/twFlock b/build/twFlock new file mode 100755 index 0000000..54fc152 Binary files /dev/null and b/build/twFlock differ diff --git a/color.go b/color.go new file mode 100644 index 0000000..5c0dcc8 --- /dev/null +++ b/color.go @@ -0,0 +1,49 @@ +package main + +import "fmt" + +type Color struct{} + +var c Color + +func (c Color) DarkGray(t string) { + fmt.Print("\x1b[30;1m") //red + fmt.Println(t) + fmt.Print("\x1b[0m") //defaultColor +} + +func (c Color) Red(t string) { + fmt.Print("\x1b[31;1m") //red + fmt.Println(t) + fmt.Print("\x1b[0m") //defaultColor +} + +func (c Color) Green(t string) { + fmt.Print("\x1b[32;1m") //green + fmt.Println(t) + fmt.Print("\x1b[0m") //defaultColor +} + +func (c Color) Yellow(t string) { + fmt.Print("\x1b[33;1m") //green + fmt.Println(t) + fmt.Print("\x1b[0m") //defaultColor +} + +func (c Color) Blue(t string) { + fmt.Print("\x1b[34;1m") //blue + fmt.Println(t) + fmt.Print("\x1b[0m") //defaultColor +} + +func (c Color) Purple(t string) { + fmt.Print("\x1b[35;1m") //purple + fmt.Println(t) + fmt.Print("\x1b[0m") //defaultColor +} + +func (c Color) Cyan(t string) { + fmt.Print("\x1b[36;1m") //cyan + fmt.Println(t) + fmt.Print("\x1b[0m") //defaultColor +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..b22de2a --- /dev/null +++ b/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +const version = "0.1-dev" + +func main() { + c.Yellow("twFlock") + fmt.Println("---------------") + c.Cyan("twFlock initialized") + c.Purple("https://github.com/arnaucode/twFlock") + fmt.Println("version " + version) + fmt.Println("Reading flockConfig.json file") + flock := readConfigTokensAndConnect() + fmt.Println("---------------") + newcommand := bufio.NewReader(os.Stdin) + fmt.Print("Please select command number") + options := ` + 1 - Tweet from flock of bots + 0 - Exit script +option to select: ` + for { + fmt.Print(options) + + option, _ := newcommand.ReadString('\n') + option = strings.TrimSpace(option) + + switch option { + case "1": + fmt.Println("selected 1 - Tweet from flock of bots") + optionTweetFromFlock(flock) + break + case "0": + fmt.Println("selected 0 - exit script") + os.Exit(3) + break + default: + fmt.Println("Invalid option") + break + } + } +} diff --git a/readConfigTokensAndConnect.go b/readConfigTokensAndConnect.go new file mode 100644 index 0000000..9eb36ca --- /dev/null +++ b/readConfigTokensAndConnect.go @@ -0,0 +1,51 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + + "github.com/dghubble/go-twitter/twitter" + "github.com/dghubble/oauth1" +) + +type Config struct { + Title string `json:"title"` + Consumer_key string `json:"consumer_key"` + Consumer_secret string `json:"consumer_secret"` + Access_token_key string `json:"access_token_key"` + Access_token_secret string `json:"access_token_secret"` +} +type Flock struct { + ScreenNames []string + Clients []*twitter.Client +} + +func readConfigTokensAndConnect() (flock Flock) { + var config []Config + var clients []*twitter.Client + + file, e := ioutil.ReadFile("flockConfig.json") + if e != nil { + fmt.Println("error:", e) + } + content := string(file) + json.Unmarshal([]byte(content), &config) + fmt.Println("flockConfig.json read comlete") + + fmt.Print("connecting to twitter api --> ") + for i := 0; i < len(config); i++ { + configu := oauth1.NewConfig(config[i].Consumer_key, config[i].Consumer_secret) + token := oauth1.NewToken(config[i].Access_token_key, config[i].Access_token_secret) + httpClient := configu.Client(oauth1.NoContext, token) + // twitter client + client := twitter.NewClient(httpClient) + clients = append(clients, client) + flock.ScreenNames = append(flock.ScreenNames, config[i].Title) + } + flock.Clients = clients + + fmt.Println("connection successfull") + + return flock +} diff --git a/tweetFromFlock.go b/tweetFromFlock.go new file mode 100644 index 0000000..8ce1e0d --- /dev/null +++ b/tweetFromFlock.go @@ -0,0 +1,59 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" + + "github.com/dghubble/go-twitter/twitter" +) + +func postTweet(client *twitter.Client, text string) { + tweet, httpResp, err := client.Statuses.Update(text, nil) + if err != nil { + fmt.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") + } + fmt.Print("tweet posted: ") + c.Green(tweet.Text) +} +func tweetFromFlock(flock Flock, text string) { + fmt.Println("Starting to publish tweet: " + text) + fmt.Println(strconv.Itoa(len(flock.Clients))) + for i := 0; i < len(flock.Clients); i++ { + fmt.Print("tweeting from: ") + c.Cyan("@" + flock.ScreenNames[i]) + postTweet(flock.Clients[i], text) + //waitTime(1) + } + +} + +func optionTweetFromFlock(flock Flock) { + + fmt.Print("entry tweet content: ") + newcommand := bufio.NewReader(os.Stdin) + text, _ := newcommand.ReadString('\n') + text = strings.TrimSpace(text) + fmt.Print("tweet content: ") + c.Purple(text) + + c.Red("Are you sure? [y/n]") + newcommand = bufio.NewReader(os.Stdin) + answer, _ := newcommand.ReadString('\n') + answer = strings.TrimSpace(answer) + switch answer { + case "y": + fmt.Println("ok, you are sure") + tweetFromFlock(flock, text) + break + default: + fmt.Println("Operation cancelled") + break + } +} diff --git a/waitTime.go b/waitTime.go new file mode 100644 index 0000000..f4e293f --- /dev/null +++ b/waitTime.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "strconv" + "time" +) + +func waitTime(minutes int) { + //wait to avoid the twitter api limitation + timeToSleep := time.Duration(minutes) * time.Minute + fmt.Println("waiting " + strconv.Itoa(minutes) + " min to avoid twitter api limitation") + fmt.Println(time.Now().Local()) + time.Sleep(timeToSleep) +}