diff --git a/directmessage.go b/directmessage.go index ef14c11..ce1e480 100644 --- a/directmessage.go +++ b/directmessage.go @@ -13,3 +13,47 @@ type DirectMessage struct { SenderScreenName string `json:"sender_screen_name"` Text string `json:"text"` } + +type DMEventData struct { + DMEvent *DMEvent `json:"event"` +} + +type DMEventList struct { + NextCursor string `json:"next_cursor"` + DMEvents []DMEvent `json:"events"` +} + +type DMEvent struct { + Type string `json:"type"` + Id string `json:"id"` + CreatedTimestamp string `json:"created_timestamp"` + + InitiatedVia *struct { + TweetId string `json:"tweet_id"` + WelcomeMessageId string `json:"welcome_message_id"` + } `json:"initiated_via"` + + MessageCreate *MessageCreate `json:"message_create"` +} + +type MessageCreate struct { + Target struct { + RecipientId string `json:"recipient_id"` + } `json:"target"` + SenderId string `json:"sender_id"` + SourceAppId string `json:"source_app_id"` + MessageData *MessageData `json:"message_data"` +} + +type MessageData struct { + Text string `json:"text"` + Entities Entities `json:"entities"` + QuickReplyResponse *struct { + Type string `json:"type"` + Metadata string `json:"metadata"` + } `json:"quick_reply_response"` + Attachment *struct { + Type string `json:"type"` + Media EntityMedia `json:"media"` + } `json:"attachment"` +} diff --git a/directmessages.go b/directmessages.go index e3e3f2c..674b465 100644 --- a/directmessages.go +++ b/directmessages.go @@ -65,3 +65,19 @@ func (a TwitterApi) IndicateTyping(id int64) (err error) { a.queryQueue <- query{a.baseUrl + "/direct_messages/indicate_typing.json", v, nil, _POST, response_ch} return (<-response_ch).err } + +// https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events +func (a TwitterApi) GetDMEventList(v url.Values) (eventList DMEventList, err error) { + response_ch := make(chan response) + a.queryQueue <- query{a.baseUrl + "/direct_messages/events/list.json", v, &eventList, _GET, response_ch} + return eventList, (<-response_ch).err +} + +// https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-event +func (a TwitterApi) GetDMEventShow(id string) (eventData DMEventData, err error) { + v := url.Values{} + v.Set("id", id) + response_ch := make(chan response) + a.queryQueue <- query{a.baseUrl + "/direct_messages/events/show.json", v, &eventData, _GET, response_ch} + return eventData, (<-response_ch).err +} diff --git a/example_test.go b/example_test.go index 39c3f31..26134bd 100644 --- a/example_test.go +++ b/example_test.go @@ -5,6 +5,7 @@ import ( "time" "github.com/ChimeraCoder/anaconda" + "net/url" ) // Initialize an client library for a given user. @@ -57,3 +58,36 @@ func ExampleTwitterApi_GetFollowersListAll() { fmt.Println(page.Followers) } } + +func ExampleTwitterApi_GetDMEventList() { + anaconda.SetConsumerKey("your-consumer-key") + anaconda.SetConsumerSecret("your-consumer-secret") + api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret") + + v := url.Values{} + v.Set("count", "50") + v.Set("cursor", "next-cursor") + result, err := api.GetDMEventList(v) + if err != nil { + panic(err) + } + + fmt.Println(result.NextCursor) + for _, event := range result.DMEvents { + fmt.Println(event.Id) + fmt.Println(event.MessageCreate.MessageData.Text) + } +} + +func ExampleTwitterApi_GetDMEventShow() { + anaconda.SetConsumerKey("your-consumer-key") + anaconda.SetConsumerSecret("your-consumer-secret") + api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret") + + result, err := api.GetDMEventShow("your-event-id") + if err != nil { + panic(err) + } + + fmt.Println(result) +} diff --git a/json/direct_messages/events/list.json b/json/direct_messages/events/list.json new file mode 100644 index 0000000..9bd5793 --- /dev/null +++ b/json/direct_messages/events/list.json @@ -0,0 +1,144 @@ +{ + "events": [ + { + "type": "message_create", + "id": "1058346010592739338", + "created_timestamp": "1541164326700", + "message_create": { + "target": { + "recipient_id": "3108078572" + }, + "sender_id": "382807713", + "message_data": { + "text": "Hello anaconda", + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [], + "urls": [] + } + } + } + }, + { + "type": "message_create", + "id": "1055367239690375172", + "created_timestamp": "1540454132374", + "message_create": { + "target": { + "recipient_id": "382807713" + }, + "sender_id": "3108078572", + "source_app_id": "9339052", + "message_data": { + "text": "Hi anaconda", + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [], + "urls": [] + } + } + } + }, + { + "type": "message_create", + "id": "1054668132357304324", + "created_timestamp": "1540287452197", + "message_create": { + "target": { + "recipient_id": "382807713" + }, + "sender_id": "3108078572", + "source_app_id": "9339052", + "message_data": { + "text": "Hello Hi #cool #cool #dm https://t.co/968ExeqylC", + "entities": { + "hashtags": [ + { + "text": "cool", + "indices": [ + 9, + 14 + ] + }, + { + "text": "cool", + "indices": [ + 15, + 20 + ] + }, + { + "text": "dm", + "indices": [ + 21, + 24 + ] + } + ], + "symbols": [], + "user_mentions": [], + "urls": [ + { + "url": "https://t.co/968ExeqylC", + "expanded_url": "https://twitter.com/messages/media/1054668132357304324", + "display_url": "pic.twitter.com/968ExeqylC", + "indices": [ + 25, + 48 + ] + } + ] + }, + "attachment": { + "type": "media", + "media": { + "id": 1054668128783753217, + "id_str": "1054668128783753217", + "indices": [ + 25, + 48 + ], + "media_url": "https://ton.twitter.com/1.1/ton/data/dm/1054668132357304324/1054668128783753217/FYXhfERd.jpg", + "media_url_https": "https://ton.twitter.com/1.1/ton/data/dm/1054668132357304324/1054668128783753217/FYXhfERd.jpg", + "url": "https://t.co/968ExeqylC", + "display_url": "pic.twitter.com/968ExeqylC", + "expanded_url": "https://twitter.com/messages/media/1054668132357304324", + "type": "photo", + "sizes": { + "medium": { + "w": 500, + "h": 300, + "resize": "fit" + }, + "small": { + "w": 500, + "h": 300, + "resize": "fit" + }, + "thumb": { + "w": 150, + "h": 150, + "resize": "crop" + }, + "large": { + "w": 500, + "h": 300, + "resize": "fit" + } + } + } + } + } + } + } + ], + "apps": { + "9339052": { + "id": "9339052", + "name": "anaconda-testing", + "url": "http://www.anaconda-testing.com" + } + } +} \ No newline at end of file diff --git a/json/direct_messages/events/show.json b/json/direct_messages/events/show.json new file mode 100644 index 0000000..45b30b6 --- /dev/null +++ b/json/direct_messages/events/show.json @@ -0,0 +1,30 @@ +{ + "event": { + "type": "message_create", + "id": "1052471375942709253", + "created_timestamp": "1539763704654", + "message_create": { + "target": { + "recipient_id": "382807713" + }, + "sender_id": "3108078572", + "source_app_id": "9339052", + "message_data": { + "text": "text", + "entities": { + "hashtags": [], + "symbols": [], + "user_mentions": [], + "urls": [] + } + } + } + }, + "apps": { + "9339052": { + "id": "9339052", + "name": "anaconda-testing", + "url": "http://www.anaconda-testing.com" + } + } +} \ No newline at end of file diff --git a/twitter_test.go b/twitter_test.go index a394106..41123f2 100644 --- a/twitter_test.go +++ b/twitter_test.go @@ -467,6 +467,39 @@ func Test_RemoveMultipleUsersFromList(t *testing.T) { } } +// This assumes that the dm events list is not empty for the user +func Test_GetDMEventList(t *testing.T) { + v := url.Values{} + result, err := api.GetDMEventList(v) + if err != nil { + t.Error(err) + return + } + + if result.DMEvents == nil || len(result.DMEvents) == 0 { + t.Fatalf("Received invalid value for DMEvents : %v", result.DMEvents) + } +} + +// This assumes that the dm event for given dmID exists in json response +func Test_GetDMEventShow(t *testing.T) { + dmID := "1052471375942709253" + + result, err := api.GetDMEventShow(dmID) + if err != nil { + t.Error(err) + return + } + + if result.DMEvent == nil { + t.Fatalf("Received invalid value for DMEvent : %v", result.DMEvent) + } + + if result.DMEvent.Id != dmID { + t.Fatalf("Received invalid value for id : %s", result.DMEvent.Id) + } +} + // Test that the client can be used to throttle to an arbitrary duration func Test_TwitterApi_Throttling(t *testing.T) { const MIN_DELAY = 15 * time.Second