Skip to content

Commit 7fc529a

Browse files
committed
⚗️ [twitter] v2 APIで返信禁止にできるように
1 parent 32093fd commit 7fc529a

File tree

4 files changed

+94
-30
lines changed

4 files changed

+94
-30
lines changed

src/miraktest-twitter/components/Tweet.tsx

+65-26
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,18 @@ export const TweetComponent: React.FC<{
148148
"bg-gray-800",
149149
"flex",
150150
"justify-between",
151-
"items-center"
151+
"items-center",
152+
"space-x-2"
152153
)}
153154
>
154-
<h1 className={clsx("text-lg")}>ツイート</h1>
155+
<h1 className={clsx("text-lg", "flex-shrink-0")}>ツイート</h1>
155156
{failed && (
156-
<p className={clsx("text-red-400", "font-semibold")}>{failed}</p>
157+
<p
158+
className={clsx("text-red-400", "font-semibold", "truncate")}
159+
title={failed}
160+
>
161+
{failed}
162+
</p>
157163
)}
158164
</div>
159165
<div className={clsx("w-full", "flex", "overflow-auto")}>
@@ -358,29 +364,62 @@ export const TweetComponent: React.FC<{
358364
})
359365
)
360366
.then((mediaIds) => {
361-
twitter.tweets
362-
.statusesUpdate({
363-
status: tweetText,
364-
media_ids: mediaIds.join(",") || undefined,
365-
})
366-
.then(() => {
367-
setText("")
368-
setSelectedImages([])
369-
})
370-
.catch((e) => {
371-
console.error(e)
372-
if ("data" in e) {
373-
const data = JSON.parse(e.data)
374-
setFailed(
375-
"ツイートに失敗しました: " + data.message || e.data
376-
)
377-
} else {
378-
setFailed("ツイートに失敗しました")
379-
}
380-
})
381-
.finally(() => {
382-
setIsPosting(false)
383-
})
367+
const media_ids = mediaIds.filter((s): s is string => !!s)
368+
setting.isReplyProhibitEnabled
369+
? twitter.tweetsV2
370+
.createTweet({
371+
text: tweetText,
372+
media:
373+
0 < media_ids.length
374+
? {
375+
media_ids,
376+
}
377+
: undefined,
378+
reply_settings: "mentionedUsers",
379+
})
380+
.then(() => {
381+
setText("")
382+
setSelectedImages([])
383+
})
384+
.catch((e) => {
385+
console.error(e)
386+
if ("data" in e) {
387+
const data = JSON.parse(e.data)
388+
setFailed(
389+
"失敗しました: " +
390+
(data.detail || data.message || e.data)
391+
)
392+
} else {
393+
setFailed("失敗しました")
394+
}
395+
})
396+
.finally(() => {
397+
setIsPosting(false)
398+
})
399+
: twitter.tweets
400+
.statusesUpdate({
401+
status: tweetText,
402+
media_ids: media_ids.join(",") || undefined,
403+
})
404+
.then(() => {
405+
setText("")
406+
setSelectedImages([])
407+
})
408+
.catch((e) => {
409+
console.error(e)
410+
if ("data" in e) {
411+
const data = JSON.parse(e.data)
412+
setFailed(
413+
"失敗しました: " +
414+
(data.detail || data.message || e.data)
415+
)
416+
} else {
417+
setFailed("失敗しました")
418+
}
419+
})
420+
.finally(() => {
421+
setIsPosting(false)
422+
})
384423
})
385424
.catch((e) => {
386425
console.error(e)

src/miraktest-twitter/components/TwitterRenderer.tsx

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Axios from "axios"
2+
import clsx from "clsx"
23
import React, { useEffect, useState } from "react"
34
import { useThrottleFn } from "react-use"
45
import { atom, useRecoilValue, useRecoilState, useSetRecoilState } from "recoil"
@@ -21,7 +22,10 @@ export const TwitterRenderer: InitPlugin["renderer"] = ({
2122
}) => {
2223
const settingAtom = atom<TwitterSetting>({
2324
key: `${TWITTER_PLUGIN_PREFIX}.setting`,
24-
default: { isContentInfoEmbedInImageEnabled: false },
25+
default: {
26+
isContentInfoEmbedInImageEnabled: false,
27+
isReplyProhibitEnabled: false,
28+
},
2529
})
2630
const imageUrlAtom = atom<string | null>({
2731
key: `${TWITTER_PLUGIN_PREFIX}.imageUrl`,
@@ -74,6 +78,9 @@ export const TwitterRenderer: InitPlugin["renderer"] = ({
7478
isContentInfoEmbedInImageEnabled,
7579
setIsContentInfoEmbedInImageEnabled,
7680
] = useState(setting.isContentInfoEmbedInImageEnabled)
81+
const [isReplyProhibitEnabled, setIsReplyProhibitEnabled] = useState(
82+
setting.isReplyProhibitEnabled
83+
)
7784
return (
7885
<>
7986
<style>{tailwind}</style>
@@ -86,8 +93,8 @@ export const TwitterRenderer: InitPlugin["renderer"] = ({
8693
consumerSecret: consumerSecret || undefined,
8794
accessToken: accessToken || undefined,
8895
accessTokenSecret: accessTokenSecret || undefined,
89-
isContentInfoEmbedInImageEnabled:
90-
isContentInfoEmbedInImageEnabled,
96+
isContentInfoEmbedInImageEnabled,
97+
isReplyProhibitEnabled,
9198
})
9299
}}
93100
>
@@ -134,6 +141,23 @@ export const TwitterRenderer: InitPlugin["renderer"] = ({
134141
}
135142
/>
136143
</label>
144+
<label className="block mt-4">
145+
<span>ツイートを返信禁止に設定する</span>
146+
<input
147+
type="checkbox"
148+
className="block mt-2 form-checkbox"
149+
checked={isReplyProhibitEnabled || false}
150+
onChange={() =>
151+
setIsReplyProhibitEnabled((enabled) => !enabled)
152+
}
153+
/>
154+
<span
155+
className={clsx("block mt-1", "text-sm", "text-gray-400")}
156+
>
157+
設定する認証情報においてTwitter API v2
158+
が有効化されている必要があります
159+
</span>
160+
</label>
137161
</label>
138162
<button
139163
type="submit"

src/miraktest-twitter/constants.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export const TWITTER_META = {
44
id: TWITTER_PLUGIN_ID,
55
name: "Twitter",
66
author: "ci7lus",
7-
version: "0.0.8",
7+
version: "0.0.9",
88
description: "視聴中の番組に関連するツイートを投稿する",
99
}
1010
export const TWITTER_TWEET_WINDOW_ID = `${TWITTER_PLUGIN_ID}.tweet`

src/miraktest-twitter/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export type TwitterSetting = {
44
accessToken?: string
55
accessTokenSecret?: string
66
isContentInfoEmbedInImageEnabled: boolean
7+
isReplyProhibitEnabled: boolean
78
}
89

910
export type SayaDefinitionBoard = {

0 commit comments

Comments
 (0)