diff --git a/.github/workflows/deploy-website.yml b/.github/workflows/deploy-website.yml
index ef5110b..2e3b911 100644
--- a/.github/workflows/deploy-website.yml
+++ b/.github/workflows/deploy-website.yml
@@ -4,7 +4,7 @@ on:
branches:
- main
- master
- - dev/main
+# - dev/main
paths:
- 'Writerside/**'
- '.github/workflows/deploy-website.yml'
diff --git a/Writerside/topics/onebot11-OneBotMember.md b/Writerside/topics/onebot11-OneBotMember.md
index a9fd525..ae4e87d 100644
--- a/Writerside/topics/onebot11-OneBotMember.md
+++ b/Writerside/topics/onebot11-OneBotMember.md
@@ -418,6 +418,52 @@ member.unbanReserve()
+### 设置头衔
+
+可以通过 `setSpecialTitle(String?)` 设置此成员在群内的特殊头衔。
+
+
+
+想要获取头衔,可以通过
+[获取原始类型](#获取原始类型)
+取到 `title`。
+
+
+
+
+
+
+```Kotlin
+val member: OneBotMember = ...
+member.setSpecialTitle("newTitle")
+```
+
+
+
+
+```Java
+OneBotMember member = ...;
+member.setSpecialTitleAsync("newTitle");
+```
+{switcher-key=%ja%}
+
+```Java
+OneBotMember member = ...;
+member.setSpecialTitleBlocking("newTitle");
+```
+{switcher-key=%jb%}
+
+```Java
+OneBotMember member = ...;
+member.setSpecialTitleReserve("newTitle")
+ .transform(SuspendReserves.mono())
+ .subscribe();
+```
+{switcher-key=%jr%}
+
+
+
+
## 获取 OneBotMember
diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMember.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMember.kt
index 617cc52..31c8fd3 100644
--- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMember.kt
+++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMember.kt
@@ -128,6 +128,53 @@ public interface OneBotMember : Member, DeleteSupport, OneBotStrangerAware {
@ST
public suspend fun getSourceMemberInfo(): GetGroupMemberInfoResult
+ /**
+ * 使用 [SetGroupSpecialTitleApi] 为群成员设置专属头衔。
+ * 通常要求bot拥有群主权限。
+ *
+ * 如果想要获取当前成员的专属头衔,使用 [getSourceMemberInfo]
+ * 后可通过 [GetGroupMemberInfoResult.title] 获取。
+ *
+ * @param specialTitle 要设置的新头衔。为空或为 `null` 则代表取消头衔。
+ * @throws Throwable 任何可能在请求API过程中产生的异常。
+ */
+ @ST
+ public suspend fun setSpecialTitle(specialTitle: String? = null)
+
+ /**
+ * 使用 [SetGroupSpecialTitleApi] 为群成员设置专属头衔。
+ * 通常要求bot拥有群主权限。
+ *
+ * 如果想要获取当前成员的专属头衔,使用 [getSourceMemberInfo]
+ * 后可通过 [GetGroupMemberInfoResult.title] 获取。
+ *
+ * @param specialTitle 要设置的新头衔。为空或为 `null` 则代表取消头衔。
+ * @param duration 有效期,最终取秒值,如果小于0则会被忽略。
+ * 不一定有效果,更多说明参考 [SetGroupSpecialTitleApi] 和 [SetGroupSpecialTitleApi.create]。
+ * @param timeUnit [duration] 的时间单位。
+ * @throws Throwable 任何可能在请求API过程中产生的异常。
+ */
+ @ST
+ @JvmSynthetic
+ public suspend fun setSpecialTitle(specialTitle: String, duration: Long, timeUnit: TimeUnit)
+
+ /**
+ * 使用 [SetGroupSpecialTitleApi] 为群成员设置专属头衔。
+ * 通常要求bot拥有群主权限。
+ *
+ * 如果想要获取当前成员的专属头衔,使用 [getSourceMemberInfo]
+ * 后可通过 [GetGroupMemberInfoResult.title] 获取。
+ *
+ * @param specialTitle 要设置的新头衔。为空或为 `null` 则代表取消头衔。
+ * @param duration 有效期,最终取秒值,如果小于0则会被忽略。
+ * 不一定有效果,更多说明参考 [SetGroupSpecialTitleApi] 和 [SetGroupSpecialTitleApi.create]。
+ * @throws Throwable 任何可能在请求API过程中产生的异常。
+ */
+ @JvmSynthetic
+ public suspend fun setSpecialTitle(specialTitle: String, duration: Duration)
+
+
+
/**
* 向此成员发送消息。
*
diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt
index 3d618dd..c7efa77 100644
--- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt
+++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt
@@ -183,6 +183,37 @@ internal abstract class OneBotMemberImpl(
).requestDataBy(bot)
}
+ override suspend fun setSpecialTitle(specialTitle: String?) {
+ setSpecialTitle0(specialTitle, null)
+ }
+
+ override suspend fun setSpecialTitle(specialTitle: String, duration: Long, timeUnit: TimeUnit) {
+ if (duration < 0L) {
+ setSpecialTitle0(specialTitle, null)
+ } else {
+ setSpecialTitle0(specialTitle, timeUnit.toSeconds(duration))
+ }
+ }
+
+ override suspend fun setSpecialTitle(specialTitle: String, duration: Duration) {
+ val seconds = duration.inWholeSeconds
+
+ if (seconds < 0L) {
+ setSpecialTitle0(specialTitle, null)
+ } else {
+ setSpecialTitle0(specialTitle, seconds)
+ }
+ }
+
+ private suspend fun setSpecialTitle0(specialTitle: String?, duration: Long?) {
+ SetGroupSpecialTitleApi.create(
+ groupId = groupIdOrFailure,
+ userId = id,
+ specialTitle = specialTitle,
+ duration = duration
+ ).requestDataBy(bot)
+ }
+
override suspend fun setNick(newNick: String?) {
SetGroupCardApi.create(
groupId = groupIdOrFailure,
diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/api/GetGroupMemberInfoApi.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/api/GetGroupMemberInfoApi.kt
index d35b033..af529e5 100644
--- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/api/GetGroupMemberInfoApi.kt
+++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/api/GetGroupMemberInfoApi.kt
@@ -109,20 +109,20 @@ public data class GetGroupMemberInfoResult @ApiResultConstructor constructor(
@SerialName("user_id")
public val userId: LongID,
public val nickname: String,
- public val card: String,
- public val sex: String,
- public val age: Int,
- public val area: String,
+ public val card: String = "",
+ public val sex: String = "unknown",
+ public val age: Int = -1,
+ public val area: String = "",
@SerialName("join_time")
- public val joinTime: Int,
+ public val joinTime: Int = -1,
@SerialName("last_sent_time")
- public val lastSentTime: Int,
- public val level: String,
- public val role: String,
- public val unfriendly: Boolean,
- public val title: String,
+ public val lastSentTime: Int = -1,
+ public val level: String = "",
+ public val role: String = "member",
+ public val unfriendly: Boolean = false,
+ public val title: String = "",
@SerialName("title_expire_time")
- public val titleExpireTime: Int,
+ public val titleExpireTime: Int = -1,
@SerialName("card_changeable")
- public val cardChangeable: Boolean,
+ public val cardChangeable: Boolean = false,
)