From: Kimura Youichi Date: Mon, 27 May 2024 22:32:42 +0000 (+0900) Subject: MisskeyClient.CreatePostメソッドを実装 X-Git-Tag: OpenTween_v3.14.0^2~1^2~13 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=41b291a5fd007def4184f7d495187131df25d40a;p=opentween%2Fopen-tween.git MisskeyClient.CreatePostメソッドを実装 --- diff --git a/OpenTween.Tests/Api/Misskey/NoteCreateRequestTest.cs b/OpenTween.Tests/Api/Misskey/NoteCreateRequestTest.cs new file mode 100644 index 00000000..d020c8ad --- /dev/null +++ b/OpenTween.Tests/Api/Misskey/NoteCreateRequestTest.cs @@ -0,0 +1,63 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Threading.Tasks; +using Moq; +using OpenTween.Connection; +using Xunit; + +namespace OpenTween.Api.Misskey +{ + public class NoteCreateRequestTest + { + [Fact] + public async Task Send_Test() + { + var response = TestUtils.CreateApiResponse(new MisskeyNote()); + + var mock = new Mock(); + mock.Setup(x => + x.SendAsync(It.IsAny()) + ) + .Callback(x => + { + var request = Assert.IsType(x); + Assert.Equal(new("notes/create", UriKind.Relative), request.RequestUri); + Assert.Equal( + """{"replyId":"aaaaa","text":"tetete","visibility":"public"}""", + request.JsonString + ); + }) + .ReturnsAsync(response); + + var request = new NoteCreateRequest + { + Text = "tetete", + Visibility = "public", + ReplyId = new("aaaaa"), + }; + await request.Send(mock.Object); + + mock.VerifyAll(); + } + } +} diff --git a/OpenTween/Api/Misskey/NoteCreateRequest.cs b/OpenTween/Api/Misskey/NoteCreateRequest.cs new file mode 100644 index 00000000..858e6602 --- /dev/null +++ b/OpenTween/Api/Misskey/NoteCreateRequest.cs @@ -0,0 +1,90 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Runtime.Serialization; +using System.Threading.Tasks; +using OpenTween.Connection; +using OpenTween.SocialProtocol.Misskey; + +namespace OpenTween.Api.Misskey +{ + public class NoteCreateRequest + { + public string? Text { get; set; } + + public string? Visibility { get; set; } + + public MisskeyNoteId? ReplyId { get; set; } + + public MisskeyNoteId? RenoteId { get; set; } + + public async Task Send(IApiConnection apiConnection) + { + var request = new PostJsonRequest + { + RequestUri = new("notes/create", UriKind.Relative), + JsonString = this.CreateRequestJson(), + }; + + using var response = await apiConnection.SendAsync(request) + .ConfigureAwait(false); + + var responseBody = await response.ReadAsJson() + .ConfigureAwait(false); + + return responseBody.CreatedNote; + } + + [DataContract] + private record RequestBody( + [property: DataMember(Name = "text", EmitDefaultValue = false)] + string? Text, + [property: DataMember(Name = "visibility", EmitDefaultValue = false)] + string? Visibility, + [property: DataMember(Name = "replyId", EmitDefaultValue = false)] + string? ReplyId, + [property: DataMember(Name = "renoteId", EmitDefaultValue = false)] + string? RenoteId + ); + + [DataContract] + private class ResponseBody + { + [DataMember(Name = "createdNote")] + public MisskeyNote CreatedNote { get; set; } = new(); + } + + private string CreateRequestJson() + { + var body = new RequestBody( + Text: this.Text, + Visibility: this.Visibility, + ReplyId: this.ReplyId?.Id, + RenoteId: this.RenoteId?.Id + ); + + return JsonUtils.SerializeJsonByDataContract(body); + } + } +} diff --git a/OpenTween/SocialProtocol/Misskey/MisskeyClient.cs b/OpenTween/SocialProtocol/Misskey/MisskeyClient.cs index 460a1a24..af842248 100644 --- a/OpenTween/SocialProtocol/Misskey/MisskeyClient.cs +++ b/OpenTween/SocialProtocol/Misskey/MisskeyClient.cs @@ -30,6 +30,8 @@ namespace OpenTween.SocialProtocol.Misskey { public class MisskeyClient : ISocialProtocolClient { + public static int MaxNoteTextLength { get; } = 3_000; + private readonly MisskeyAccount account; private readonly MisskeyPostFactory postFactory = new(); @@ -96,11 +98,29 @@ namespace OpenTween.SocialProtocol.Misskey public Task GetRelatedPosts(PostClass targetPost, bool firstLoad) => throw this.CreateException(); - public Task CreatePost(PostStatusParams postParams) - => throw this.CreateException(); + public async Task CreatePost(PostStatusParams postParams) + { + if (postParams.Text.StartsWith("D ")) + throw this.CreateException(); // DM の送信は非対応 + + var request = new NoteCreateRequest + { + Text = postParams.Text, + ReplyId = postParams.InReplyTo is { } replyTo + ? this.AssertMisskeyNoteId(replyTo.StatusId) + : null, + }; + + var note = await request.Send(this.account.Connection) + .ConfigureAwait(false); + + var post = this.CreatePostFromNote(note, firstLoad: false); + + return post; + } public int GetTextLengthRemain(PostStatusParams postParams) - => 0; + => MaxNoteTextLength - postParams.Text.ToCodepoints().Count(); public Task DeletePost(PostId postId) => throw this.CreateException();