Adding basic Bot functionality
This commit is contained in:
parent
9101453bb7
commit
a2e793a6c3
|
@ -3,9 +3,11 @@ package main
|
|||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/bot"
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/config"
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/twitter"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -15,18 +17,13 @@ func main() {
|
|||
log.Fatalf("Config file must not be empty!")
|
||||
}
|
||||
|
||||
log.Println("Hello World!")
|
||||
|
||||
config.LoadConfig(*cfg)
|
||||
twitter.Init()
|
||||
stream, err := twitter.GetStreamForTag("#NationalPuppyDay")
|
||||
if err != nil {
|
||||
log.Fatalf("Could not establish twitter stream: %+v", err)
|
||||
}
|
||||
bot.Init()
|
||||
|
||||
twitter.StreamDemux(stream, showTweet)
|
||||
}
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
<-c
|
||||
|
||||
func showTweet(tweet *twitter.Tweet) {
|
||||
log.Printf("%s\n", tweet.Text)
|
||||
bot.DeInit()
|
||||
config.WriteConfig(*cfg)
|
||||
}
|
||||
|
|
83
internal/bot/bot.go
Normal file
83
internal/bot/bot.go
Normal file
|
@ -0,0 +1,83 @@
|
|||
package bot
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/config"
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/database"
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/twitter"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
var stream *twitter.Stream
|
||||
|
||||
// Init initzializes the bot and subscribes the magic hashtag feed
|
||||
func Init() {
|
||||
var err error
|
||||
|
||||
err = database.Open(config.C.Database.Dialect, config.C.Database.Connection)
|
||||
if err != nil {
|
||||
log.Fatalf("could not establish database connection: %+v", err)
|
||||
}
|
||||
|
||||
twitter.Init()
|
||||
stream, err = twitter.GetStreamForTag(config.C.Twitter.MagicHashtag)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not establish twitter stream: %+v", err)
|
||||
}
|
||||
|
||||
twitter.StreamDemux(stream, handleHashtagTweet)
|
||||
}
|
||||
|
||||
// DeInit stops the stream and deinitzializes the bot
|
||||
func DeInit() {
|
||||
stream.Stop()
|
||||
database.Close()
|
||||
}
|
||||
|
||||
func handleHashtagTweet(tweet *twitter.Tweet) {
|
||||
msg, tags := twitter.GetTextAndHashtags(tweet)
|
||||
// Ignore retweets
|
||||
if tweet.RetweetedStatus != nil {
|
||||
log.Printf("%s: %s - IGNORED (RT)\n", tweet.User.ScreenName, msg)
|
||||
return
|
||||
}
|
||||
// Ignore replys
|
||||
if tweet.InReplyToStatusID != 0 {
|
||||
log.Printf("%s: %s - IGNORED (RPLY)\n", tweet.User.ScreenName, msg)
|
||||
return
|
||||
}
|
||||
// Ignore if only magic hashtag is given
|
||||
if len(tags) < 2 {
|
||||
log.Printf("%s: %s - IGNORED (<2#)\n", tweet.User.ScreenName, msg)
|
||||
return
|
||||
}
|
||||
log.Printf("%s: %s\n", tweet.User.ScreenName, msg)
|
||||
go findCodes(tweet)
|
||||
}
|
||||
|
||||
func findCodes(tweet *twitter.Tweet) {
|
||||
_, tags := twitter.GetTextAndHashtags(tweet)
|
||||
var betriebsstellen []database.Betriebsstelle
|
||||
for _, tag := range tags {
|
||||
code := strings.ReplaceAll(tag.Text, "_", " ")
|
||||
var bs database.Betriebsstelle
|
||||
if database.Db.First(&bs, "code = ?", code).Error != gorm.ErrRecordNotFound {
|
||||
betriebsstellen = append(betriebsstellen, bs)
|
||||
}
|
||||
}
|
||||
sendReply(tweet, betriebsstellen)
|
||||
}
|
||||
|
||||
func sendReply(tweet *twitter.Tweet, betriebsstellen []database.Betriebsstelle) {
|
||||
var reply string
|
||||
for _, bs := range betriebsstellen {
|
||||
reply = reply + bs.Code + ": " + bs.Name + "\n"
|
||||
}
|
||||
reply = reply[0 : len(reply)-1]
|
||||
_, _, err := twitter.SendTweet(reply, tweet)
|
||||
if err != nil {
|
||||
log.Printf("Cannot send reply, error: %+v", err)
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import (
|
|||
// Config main type
|
||||
type Config struct {
|
||||
Twitter Twitter
|
||||
Database Database
|
||||
}
|
||||
|
||||
// Twitter related config
|
||||
|
@ -21,6 +22,13 @@ type Twitter struct {
|
|||
ConsumerSecret string
|
||||
AccessKey string
|
||||
AccessSecret string
|
||||
MagicHashtag string
|
||||
}
|
||||
|
||||
// Database related config
|
||||
type Database struct {
|
||||
Dialect string
|
||||
Connection string
|
||||
}
|
||||
|
||||
// C holds the loaded configuration
|
||||
|
@ -32,6 +40,10 @@ func LoadDefaults() {
|
|||
C.Twitter.AccessSecret = "ACCESSSECRET"
|
||||
C.Twitter.ConsumerKey = "CONSUMERKEY"
|
||||
C.Twitter.ConsumerSecret = "CONSUMERSECRET"
|
||||
C.Twitter.MagicHashtag = "#DB640"
|
||||
|
||||
C.Database.Dialect = "sqlite3"
|
||||
C.Database.Connection = ":memory:"
|
||||
}
|
||||
|
||||
// LoadConfig loads the configuration from given path
|
||||
|
|
|
@ -18,6 +18,9 @@ func TestWriteConfig(t *testing.T) {
|
|||
C.Twitter.AccessSecret = "SuperNiceSecret"
|
||||
C.Twitter.ConsumerKey = "ConsumeMe"
|
||||
C.Twitter.ConsumerSecret = "EatASecret"
|
||||
C.Twitter.MagicHashtag = "#notsomagic"
|
||||
C.Database.Dialect = "somedia"
|
||||
C.Database.Connection = "conn"
|
||||
err := WriteConfig(filepath.Join("..", "..", "test", "data", "doesnotexist.toml"))
|
||||
if err != nil {
|
||||
t.Errorf("Could not write config, got error: %+v", err)
|
||||
|
@ -30,7 +33,13 @@ func TestLoadConfig(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("Cannot read config, error: %+v", err)
|
||||
}
|
||||
if C.Twitter.AccessKey != "§OneNiceKey" || C.Twitter.AccessSecret != "SuperNiceSecret" || C.Twitter.ConsumerKey != "ConsumeMe" || C.Twitter.ConsumerSecret != "EatASecret" {
|
||||
if C.Twitter.AccessKey != "§OneNiceKey" ||
|
||||
C.Twitter.AccessSecret != "SuperNiceSecret" ||
|
||||
C.Twitter.ConsumerKey != "ConsumeMe" ||
|
||||
C.Twitter.ConsumerSecret != "EatASecret" ||
|
||||
C.Twitter.MagicHashtag != "#notsomagic" ||
|
||||
C.Database.Dialect != "somedia" ||
|
||||
C.Database.Connection != "conn" {
|
||||
t.Errorf("Could not read config, entries wrong")
|
||||
}
|
||||
t.Cleanup(CleanupConfigTest)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package twitter
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/config"
|
||||
"github.com/dghubble/go-twitter/twitter"
|
||||
"github.com/dghubble/oauth1"
|
||||
|
@ -12,6 +14,9 @@ var Client *twitter.Client
|
|||
// Tweet as in twitter.Tweet
|
||||
type Tweet = twitter.Tweet
|
||||
|
||||
// Stream as in twitter.Stream
|
||||
type Stream = twitter.Stream
|
||||
|
||||
// Init initzializes the twitter client
|
||||
func Init() {
|
||||
conf := oauth1.NewConfig(config.C.Twitter.ConsumerKey, config.C.Twitter.ConsumerSecret)
|
||||
|
@ -36,3 +41,24 @@ func StreamDemux(stream *twitter.Stream, cb func(*Tweet)) {
|
|||
demux.Tweet = cb
|
||||
demux.HandleChan(stream.Messages)
|
||||
}
|
||||
|
||||
// SendTweet allows to send a string as tweet (optionally as reply to a specified tweet)
|
||||
func SendTweet(msg string, replytweet *twitter.Tweet) (*twitter.Tweet, *http.Response, error) {
|
||||
if replytweet == nil {
|
||||
// not a reply
|
||||
return Client.Statuses.Update(msg, nil)
|
||||
}
|
||||
// replying
|
||||
p := twitter.StatusUpdateParams{
|
||||
InReplyToStatusID: replytweet.ID,
|
||||
}
|
||||
return Client.Statuses.Update("@"+replytweet.User.ScreenName+" "+msg, &p)
|
||||
}
|
||||
|
||||
// GetTextAndHashtags returns #tweet text and hashtags for short and extended tweets
|
||||
func GetTextAndHashtags(tweet *twitter.Tweet) (string, []twitter.HashtagEntity) {
|
||||
if tweet.ExtendedTweet == nil {
|
||||
return tweet.Text, tweet.Entities.Hashtags
|
||||
}
|
||||
return tweet.ExtendedTweet.FullText, tweet.ExtendedTweet.Entities.Hashtags
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue