nikoksr/notify

View on GitHub
service/twitter/twitter.go

Summary

Maintainability
A
0 mins
Test Coverage
package twitter

import (
    "context"
    "fmt"

    "github.com/dghubble/oauth1"
    "github.com/drswork/go-twitter/twitter"
)

// 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 Twitter service.
// For more information about Twitter access token:
//
//    -> https://developer.twitter.com/en/docs/authentication/oauth-1-0a/obtaining-user-access-tokens
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,
            }

            if _, _, err := t.client.DirectMessages.EventsNew(directMessageParams); err != nil {
                return fmt.Errorf("send message to %q: %w", twitterID, err)
            }
        }
    }

    return nil
}