package twitter import ( "context" "github.com/dghubble/go-twitter/twitter" "github.com/dghubble/oauth1" "github.com/pkg/errors" ) // Twitter struct holds necessary data to communicate with the Twitter API type Twitter struct { client *twitter.Client twitterIDs []string } // Credentials contains the authentication credentials needed for twitter // api access // // ConsumerKey and ConsumerSecret can be thought of as the user name // and password that represents your Twitter developer app when making // API requests. // // An access token and access token secret are user-specific credentials // used to authenticate OAuth 1.0a API requests. // They specify the Twitter account the request is made on behalf of. // // See https://developer.twitter.com/en/docs/authentication/oauth-1-0a for more details type Credentials struct { ConsumerKey string ConsumerSecret string AccessToken string AccessTokenSecret string } // New returns a new instance of a Slack notification service. // For more information about slack api token: // // -> https://pkg.go.dev/github.com/slack-go/slack#New func New(credentials Credentials) (*Twitter, error) { config := oauth1.NewConfig(credentials.ConsumerKey, credentials.ConsumerSecret) token := oauth1.NewToken(credentials.AccessToken, credentials.AccessTokenSecret) httpClient := config.Client(oauth1.NoContext, token) client := twitter.NewClient(httpClient) // Verify Credentials verifyParams := &twitter.AccountVerifyParams{ SkipStatus: twitter.Bool(true), IncludeEmail: twitter.Bool(true), } // we can retrieve the user and verify if the credentials // we have used successfully allow us to log in! _, _, err := client.Accounts.VerifyCredentials(verifyParams) if err != nil { return nil, err } t := &Twitter{ client: client, twitterIDs: []string{}, } return t, nil } // AddReceivers takes TwitterIds and adds them to the internal twitterIDs list. func (t *Twitter) AddReceivers(twitterIDs ...string) { t.twitterIDs = append(t.twitterIDs, twitterIDs...) } // Send takes a message subject and a message body and sends them to all previously set twitterIDs as a DM. // See https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/new-event func (t Twitter) Send(ctx context.Context, subject, message string) error { directMessageData := &twitter.DirectMessageData{ Text: subject + "\n" + message, } for _, twitterID := range t.twitterIDs { select { case <-ctx.Done(): return ctx.Err() default: directMessageTarget := &twitter.DirectMessageTarget{ RecipientID: twitterID, } directMessageEvent := &twitter.DirectMessageEvent{ Type: "message_create", Message: &twitter.DirectMessageEventMessage{ Target: directMessageTarget, Data: directMessageData, }, } directMessageParams := &twitter.DirectMessageEventsNewParams{ Event: directMessageEvent, } _, _, err := t.client.DirectMessages.EventsNew(directMessageParams) if err != nil { return errors.Wrapf(err, "failed to send direct message to twitter ID '%s'", twitterID) } } } return nil }