diff --git a/.gitignore b/.gitignore index ee19125..eb5b34a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ settings_custom.json history.json -users.json \ No newline at end of file +users.json +chat_data.json \ No newline at end of file diff --git a/alfred.go b/alfred.go index 799adcf..b8d4956 100644 --- a/alfred.go +++ b/alfred.go @@ -2,7 +2,7 @@ * @Author: Bartuccio Antoine * @Date: 2018-07-23 15:24:22 * @Last Modified by: klmp200 -* @Last Modified time: 2018-07-24 20:55:53 +* @Last Modified time: 2018-07-27 16:13:32 */ package main @@ -26,6 +26,9 @@ func main() { "/setgender": commands.SetGender, "/gender": commands.Gender, "/roll": commands.Dice, + "/trump": commands.LastTrumpTweet, + "/trends": commands.TwitterTrends, + "/chaos": commands.TwitterSJW, } if err := settings.LoadSettings("settings.json", "settings_custom.json"); err != nil { @@ -37,6 +40,8 @@ func main() { settings.Settings["history file"].(string)) log.Println("Initialize users infos") shared.InitUsers(settings.Settings["users file"].(string)) + log.Println("Initialize chat data") + shared.InitChatData(settings.Settings["chat data file"].(string)) log.Println("Bot initialisation") b, err := tb.NewBot(tb.Settings{ diff --git a/commands/gender.go b/commands/gender.go index b126dbf..26d1d80 100644 --- a/commands/gender.go +++ b/commands/gender.go @@ -2,7 +2,7 @@ * @Author: Bartuccio Antoine * @Date: 2018-07-24 14:55:33 * @Last Modified by: klmp200 -* @Last Modified time: 2018-07-24 20:29:36 +* @Last Modified time: 2018-07-25 01:29:53 */ package commands @@ -24,6 +24,10 @@ func SetGender(m *tb.Message) { return } data := strings.Join(split, " ") + if data == "" { + shared.Bot.Send(m.Chat, "Attention, votre genre est vide. Ce n'est pas enregistrable.") + return + } shared.Users.Set(m.Sender.Username, "gender", data) shared.Bot.Send(m.Chat, "Votre genre est enregistré, je vous considère maintenant comme « "+data+" ».") } @@ -52,13 +56,12 @@ func Gender(m *tb.Message) { func cleanGender(slice []string) []string { for i := range slice { + slice[i] = strings.Replace(slice[i], "\\", "", -1) + slice[i] = strings.Replace(slice[i], "@", "", -1) clean := false for !clean { clean = true - if strings.HasPrefix(slice[i], "@") { - slice[i] = strings.Replace(slice[i], "@", "", 1) - clean = false - } else if strings.HasPrefix(slice[i], "/") { + if strings.HasPrefix(slice[i], "/") { slice[i] = strings.Replace(slice[i], "/", "", 1) clean = false } diff --git a/commands/twitter.go b/commands/twitter.go new file mode 100644 index 0000000..42e9ad8 --- /dev/null +++ b/commands/twitter.go @@ -0,0 +1,114 @@ +/* +* @Author: Bartuccio Antoine +* @Date: 2018-07-25 18:51:38 +* @Last Modified by: klmp200 +* @Last Modified time: 2018-07-27 16:49:59 + */ + +package commands + +import ( + "../settings" + "../shared" + "github.com/dghubble/go-twitter/twitter" + "github.com/dghubble/oauth1" + tb "gopkg.in/tucnak/telebot.v2" + "strconv" + "strings" + "time" +) + +var client *twitter.Client + +func initTwitter() { + config := oauth1.NewConfig( + settings.Settings["twitter consumer key"].(string), + settings.Settings["twitter consumer secret"].(string), + ) + token := oauth1.NewToken( + settings.Settings["twitter access token"].(string), + settings.Settings["twitter access secret"].(string), + ) + + http_client := config.Client(oauth1.NoContext, token) + client = twitter.NewClient(http_client) +} + +func testOrInitTwitter() { + if client == nil { + initTwitter() + } +} + +func twitterCommunicationError(m *tb.Message) { + shared.Bot.Send(m.Chat, "Désolé, les serveurs de twitter sont injoignables.") +} + +func LastTrumpTweet(m *tb.Message) { + testOrInitTwitter() + user, _, err := client.Users.Show(&twitter.UserShowParams{ScreenName: "realDonaldTrump"}) + if err != nil { + twitterCommunicationError(m) + return + } + timeline, _, err := client.Timelines.UserTimeline(&twitter.UserTimelineParams{ScreenName: "realDonaldTrump"}) + if err != nil { + twitterCommunicationError(m) + return + } + response := []string{ + user.Name, + "\nFollowers : ", + strconv.Itoa(user.FollowersCount), + "\nStatus : ", + user.Description, + "\n ---", + "\n" + timeline[0].Text, + "\n ---", + "\n" + timeline[0].Source, + } + shared.Bot.Send(m.Chat, strings.Join(response, " ")) +} + +func TwitterTrends(m *tb.Message) { + testOrInitTwitter() + trends, _, err := client.Trends.Place(int64(615702), nil) + if err != nil { + twitterCommunicationError(m) + return + } + message := "Voici les dernières tendances en France" + for _, trend := range trends[0].Trends { + message += "\n" + trend.Name + } + shared.Bot.Send(m.Chat, message) +} + +func TwitterSJW(m *tb.Message) { + testOrInitTwitter() + last_use, exists := shared.ChatData.Get(m.Chat.ID, "last chaos use") + if exists { + var date time.Time + if _, is_string := last_use.(string); is_string { + date, _ = time.Parse(time.RFC3339, last_use.(string)) + } else { + date = last_use.(time.Time) + } + if time.Now().Before(date.Add(time.Hour * 24)) { + shared.Bot.Send(m.Chat, "Arioch ne répondra pas à votre appel.") + return + } + } + shared.ChatData.Set(m.Chat.ID, "last chaos use", time.Now()) + + tweets, _, err := client.Search.Tweets(&twitter.SearchTweetParams{ + Query: "#SJW", + }) + if err != nil { + twitterCommunicationError(m) + return + } + for _, tweet := range tweets.Statuses { + shared.Bot.Send(m.Chat, tweet.Text) + } +} diff --git a/settings.json b/settings.json index a43accc..de9860a 100644 --- a/settings.json +++ b/settings.json @@ -1,6 +1,11 @@ { "token": "INSERT TOKEN HERE", + "twitter access token": "INSERT TOKEN HERE", + "twitter access secret": "INSERT TOKEN HERE", + "twitter consumer key": "INSERT TOKEN HERE", + "twitter consumer secret": "INSERT TOKEN HERE", "history size": 10, "history file": "history.json", - "users file": "users.json" + "users file": "users.json", + "chat data file": "chat_data.json" } \ No newline at end of file diff --git a/shared/chat.go b/shared/chat.go new file mode 100644 index 0000000..6158a28 --- /dev/null +++ b/shared/chat.go @@ -0,0 +1,82 @@ +/* +* @Author: Bartuccio Antoine +* @Date: 2018-07-27 15:37:59 +* @Last Modified by: klmp200 +* @Last Modified time: 2018-07-27 16:06:51 + */ + +package shared + +import ( + "encoding/json" + "io/ioutil" + "sync" +) + +// General purpose chat info storage +type chatData struct { + mutex sync.Mutex + data map[int64]map[string]interface{} +} + +type chatDataFile struct { + mutex sync.Mutex + path string +} + +var ChatData chatData +var cdf chatDataFile + +// Init chat data meant to store infos about a chat. +func InitChatData(path string) { + cdf = chatDataFile{path: path} + ChatData = chatData{data: make(map[int64]map[string]interface{})} + ChatData.mutex.Lock() + defer ChatData.mutex.Unlock() + cdf.read() + +} + +func (c chatData) Set(chat int64, key string, data interface{}) { + c.mutex.Lock() + defer c.mutex.Unlock() + if _, exists := c.data[chat]; !exists { + c.data[chat] = make(map[string]interface{}) + } + c.data[chat][key] = data + go cdf.write() +} + +func (c chatData) Get(chat int64, key string) (interface{}, bool) { + c.mutex.Lock() + defer c.mutex.Unlock() + m, exists := c.data[chat] + if !exists { + return nil, false + } + data, ok := m[key] + if !ok { + return nil, false + } + return data, true +} + +func (c chatDataFile) read() { + c.mutex.Lock() + defer c.mutex.Unlock() + data, err := ioutil.ReadFile(c.path) + if err != nil { + // File doesn't exist, skip import + return + } + json.Unmarshal(data, &ChatData.data) +} + +func (c chatDataFile) write() { + c.mutex.Lock() + defer c.mutex.Unlock() + ChatData.mutex.Lock() + defer ChatData.mutex.Unlock() + data, _ := json.Marshal(ChatData.data) + ioutil.WriteFile(c.path, data, 0770) +}