@ -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 |
@ -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" |
||||
|
} |
||||
|
] |
@ -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
|
||||
|
} |
@ -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 |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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 |
||||
|
} |
@ -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 |
||||
|
} |
||||
|
} |
@ -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) |
||||
|
} |