OSDN Git Service

画像を添付したDMの送信に対応
authorKimura Youichi <kim.upsilon@bucyou.net>
Tue, 5 Jun 2018 18:09:12 +0000 (03:09 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Tue, 5 Jun 2018 18:20:36 +0000 (03:20 +0900)
OpenTween.Tests/Api/TwitterApiTest.cs
OpenTween/Api/TwitterApi.cs
OpenTween/Connection/TwitterPhoto.cs
OpenTween/Resources/ChangeLog.txt
OpenTween/Twitter.cs

index 891050b..bfe5743 100644 (file)
@@ -763,7 +763,13 @@ namespace OpenTween.Api
         ""recipient_id"": ""12345""
       },
       ""message_data"": {
-        ""text"": ""hogehoge""
+        ""text"": ""hogehoge"",
+        ""attachment"": {
+          ""type"": ""media"",
+          ""media"": {
+            ""id"": ""67890""
+          }
+        }
       }
     }
   }
@@ -773,7 +779,7 @@ namespace OpenTween.Api
 
                 twitterApi.apiConnection = mock.Object;
 
-                await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge")
+                await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge", mediaId: 67890L)
                     .ConfigureAwait(false);
 
                 mock.VerifyAll();
@@ -1282,13 +1288,14 @@ namespace OpenTween.Api
                             { "command", "INIT" },
                             { "total_bytes", "123456" },
                             { "media_type", "image/png" },
+                            { "media_category", "dm_image" },
                         })
                 )
                 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaInit()));
 
                 twitterApi.apiConnection = mock.Object;
 
-                await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png")
+                await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png", mediaCategory: "dm_image")
                     .IgnoreResponse()
                     .ConfigureAwait(false);
 
index 43b7386..26710e7 100644 (file)
@@ -432,10 +432,22 @@ namespace OpenTween.Api
             return this.apiConnection.PostLazyAsync<TwitterDirectMessage>(endpoint, param);
         }
 
-        public Task DirectMessagesEventsNew(long recipientId, string text)
+        public Task DirectMessagesEventsNew(long recipientId, string text, long? mediaId = null)
         {
             var endpoint = new Uri("direct_messages/events/new.json", UriKind.Relative);
 
+            var attachment = "";
+            if (mediaId != null)
+            {
+                attachment = "," + $@"
+        ""attachment"": {{
+          ""type"": ""media"",
+          ""media"": {{
+            ""id"": ""{EscapeJsonString(mediaId.ToString())}""
+          }}
+        }}";
+            }
+
             var json = $@"{{
   ""event"": {{
     ""type"": ""message_create"",
@@ -444,7 +456,7 @@ namespace OpenTween.Api
         ""recipient_id"": ""{EscapeJsonString(recipientId.ToString())}""
       }},
       ""message_data"": {{
-        ""text"": ""{EscapeJsonString(text)}""
+        ""text"": ""{EscapeJsonString(text)}""{attachment}
       }}
     }}
   }}
@@ -699,7 +711,7 @@ namespace OpenTween.Api
             return this.apiConnection.GetAsync<TwitterConfiguration>(endpoint, null, "/help/configuration");
         }
 
-        public Task<LazyJson<TwitterUploadMediaInit>> MediaUploadInit(long totalBytes, string mediaType)
+        public Task<LazyJson<TwitterUploadMediaInit>> MediaUploadInit(long totalBytes, string mediaType, string mediaCategory = null)
         {
             var endpoint = new Uri("https://upload.twitter.com/1.1/media/upload.json");
             var param = new Dictionary<string, string>
@@ -709,6 +721,9 @@ namespace OpenTween.Api
                 ["media_type"] = mediaType,
             };
 
+            if (mediaCategory != null)
+                param["media_category"] = mediaCategory;
+
             return this.apiConnection.PostLazyAsync<TwitterUploadMediaInit>(endpoint, param);
         }
 
index 87fa7e8..80e6c53 100644 (file)
@@ -85,11 +85,12 @@ namespace OpenTween.Connection
                     throw new ArgumentException("Err:Media not found.");
             }
 
-            var uploadTasks = from m in mediaItems
-                              select this.UploadMediaItem(m);
+            long[] mediaIds;
 
-            var mediaIds = await Task.WhenAll(uploadTasks)
-                .ConfigureAwait(false);
+            if (Twitter.DMSendTextRegex.IsMatch(postParams.Text))
+                mediaIds = new[] { await this.UploadMediaForDM(mediaItems).ConfigureAwait(false) };
+            else
+                mediaIds = await this.UploadMediaForTweet(mediaItems).ConfigureAwait(false);
 
             postParams.MediaIds = mediaIds;
 
@@ -103,11 +104,46 @@ namespace OpenTween.Connection
         public void UpdateTwitterConfiguration(TwitterConfiguration config)
             => this.twitterConfig = config;
 
-        private async Task<long> UploadMediaItem(IMediaItem mediaItem)
+        private async Task<long[]> UploadMediaForTweet(IMediaItem[] mediaItems)
+        {
+            var uploadTasks = from m in mediaItems
+                              select this.UploadMediaItem(m, mediaCategory: null);
+
+            var mediaIds = await Task.WhenAll(uploadTasks)
+                .ConfigureAwait(false);
+
+            return mediaIds;
+        }
+
+        private async Task<long> UploadMediaForDM(IMediaItem[] mediaItems)
+        {
+            if (mediaItems.Length > 1)
+                throw new InvalidOperationException("Err:Can't attach multiple media to DM.");
+
+            var mediaItem = mediaItems[0];
+
+            string mediaCategory;
+            switch (mediaItem.Extension)
+            {
+                case ".gif":
+                    mediaCategory = "dm_gif";
+                    break;
+                default:
+                    mediaCategory = "dm_image";
+                    break;
+            }
+
+            var mediaId = await this.UploadMediaItem(mediaItems[0], mediaCategory)
+                .ConfigureAwait(false);
+
+            return mediaId;
+        }
+
+        private async Task<long> UploadMediaItem(IMediaItem mediaItem, string mediaCategory)
         {
-            async Task<long> UploadInternal(IMediaItem media)
+            async Task<long> UploadInternal(IMediaItem media, string category)
             {
-                var mediaId = await this.tw.UploadMedia(media)
+                var mediaId = await this.tw.UploadMedia(media, category)
                     .ConfigureAwait(false);
 
                 if (!string.IsNullOrEmpty(media.AltText))
@@ -126,12 +162,12 @@ namespace OpenTween.Connection
                     using (var newMediaItem = new MemoryImageMediaItem(newImage))
                     {
                         newMediaItem.AltText = mediaItem.AltText;
-                        return await UploadInternal(newMediaItem);
+                        return await UploadInternal(newMediaItem, mediaCategory);
                     }
                 }
                 else
                 {
-                    return await UploadInternal(mediaItem);
+                    return await UploadInternal(mediaItem, mediaCategory);
                 }
             }
         }
index 9150840..0b52683 100644 (file)
@@ -1,6 +1,7 @@
 更新履歴
 
 ==== Ver 1.4.2-dev(xxxx/xx/xx)
+ * NEW: 画像を添付したDMの送信に対応しました
  * NEW: システムのタイムゾーンの変更を検知して、ツイートの投稿日時などの表示を新しいタイムゾーンに同期します
  * NEW: 5月中旬に予定されている引用ツイートに関する Twitter API の仕様変更に対応
  * NEW: リプライ送信時にリプライ以外何も入力されていない状態であった場合は警告のダイアログを表示します
index 7e39cfd..f7a3eed 100644 (file)
@@ -281,7 +281,9 @@ namespace OpenTween
 
             if (Twitter.DMSendTextRegex.IsMatch(param.Text))
             {
-                await this.SendDirectMessage(param.Text)
+                var mediaId = param.MediaIds != null && param.MediaIds.Any() ? param.MediaIds[0] : (long?)null;
+
+                await this.SendDirectMessage(param.Text, mediaId)
                     .ConfigureAwait(false);
                 return;
             }
@@ -301,7 +303,7 @@ namespace OpenTween
             this.previousStatusId = status.Id;
         }
 
-        public async Task<long> UploadMedia(IMediaItem item)
+        public async Task<long> UploadMedia(IMediaItem item, string mediaCategory = null)
         {
             this.CheckAccountState();
 
@@ -324,7 +326,7 @@ namespace OpenTween
                     break;
             }
 
-            var initResponse = await this.Api.MediaUploadInit(item.Size, mediaType)
+            var initResponse = await this.Api.MediaUploadInit(item.Size, mediaType, mediaCategory)
                 .ConfigureAwait(false);
 
             var initMedia = await initResponse.LoadJsonAsync()
@@ -368,7 +370,7 @@ namespace OpenTween
             return media.MediaId;
         }
 
-        public async Task SendDirectMessage(string postStr)
+        public async Task SendDirectMessage(string postStr, long? mediaId = null)
         {
             this.CheckAccountState();
             this.CheckAccessLevel(TwitterApiAccessLevel.ReadWriteAndDirectMessage);
@@ -381,7 +383,7 @@ namespace OpenTween
             var recipient = await this.Api.UsersShow(recipientName)
                 .ConfigureAwait(false);
 
-            await this.Api.DirectMessagesEventsNew(recipient.Id, body)
+            await this.Api.DirectMessagesEventsNew(recipient.Id, body, mediaId)
                 .ConfigureAwait(false);
         }