@iflyrpa/actions 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +247 -14
- package/dist/index.mjs +247 -14
- package/package.json +1 -1
- package/src/actions/baijiahaoPublish/mock.ts +3 -5
- package/src/actions/getToutiaoConfig/index.ts +72 -0
- package/src/actions/searchToutiaoTopicList/index.ts +38 -0
- package/src/actions/toutiaoPublish/index.ts +17 -3
- package/src/actions/toutiaoPublish/mock.ts +206 -8
- package/src/actions/weitoutiaoPublish/mock.ts +4 -4
- package/src/index.ts +12 -0
- package/src/types.ts +37 -0
package/dist/index.cjs
CHANGED
|
@@ -21753,7 +21753,7 @@ const replaceImgSrc = (html, callback) => {
|
|
|
21753
21753
|
return lastedHtml;
|
|
21754
21754
|
};
|
|
21755
21755
|
|
|
21756
|
-
const errnoMap = {
|
|
21756
|
+
const errnoMap$1 = {
|
|
21757
21757
|
20040706: "\u6B63\u6587\u548C\u5C01\u9762\u56FE\u7247\u63A8\u8350\u4F7F\u752820M\u4EE5\u5185\u7684jpg\u548Cpng\u56FE\u7247",
|
|
21758
21758
|
20040084: "\u6B63\u6587\u548C\u5C01\u9762\u56FE\u7247\u63A8\u8350\u4F7F\u752820M\u4EE5\u5185\u7684jpg\u548Cpng\u56FE\u7247",
|
|
21759
21759
|
20050004: "\u53D1\u5E03\u6B21\u6570\u7528\u5C3D\uFF0C\u8BF7\u660E\u5929\u518D\u8BD5",
|
|
@@ -21766,6 +21766,7 @@ const errnoMap = {
|
|
|
21766
21766
|
401100032: "\u4E0D\u652F\u6301\u8BE5\u5A92\u8D44\u7C7B\u578B\uFF0C\u8BF7\u68C0\u67E5\u56FE\u7247\uFF08\u4F8B\u5982\uFF1A\u7248\u6743\uFF09"
|
|
21767
21767
|
};
|
|
21768
21768
|
const mockAction$5 = async (task, params) => {
|
|
21769
|
+
const { baijiahaoSingleCover, baijiahaoMultCover, baijiahaoCoverType } = params.settingInfo;
|
|
21769
21770
|
const tmpCachePath = task.getTmpPath();
|
|
21770
21771
|
const api = axios$1.create({
|
|
21771
21772
|
headers: {
|
|
@@ -21776,7 +21777,7 @@ const mockAction$5 = async (task, params) => {
|
|
|
21776
21777
|
api.interceptors.response.use(
|
|
21777
21778
|
(response) => {
|
|
21778
21779
|
if (response.data.errno !== 0) {
|
|
21779
|
-
const errmsg = errnoMap[response.data.errno] || response.config.defaultErrorMsg || response.data.errmsg || "Unknown error";
|
|
21780
|
+
const errmsg = errnoMap$1[response.data.errno] || response.config.defaultErrorMsg || response.data.errmsg || "Unknown error";
|
|
21780
21781
|
task.logger.error(errmsg);
|
|
21781
21782
|
return Promise.reject(new Error(errmsg));
|
|
21782
21783
|
}
|
|
@@ -21841,7 +21842,7 @@ const mockAction$5 = async (task, params) => {
|
|
|
21841
21842
|
if (vertical_cover) {
|
|
21842
21843
|
vertical_cover = (await uploadImages([vertical_cover]))[0].bos_url;
|
|
21843
21844
|
}
|
|
21844
|
-
const horizontalCoverUrl =
|
|
21845
|
+
const horizontalCoverUrl = baijiahaoCoverType === "single" ? [baijiahaoSingleCover] : baijiahaoMultCover;
|
|
21845
21846
|
const horizontalCoverRes = await uploadImages(horizontalCoverUrl);
|
|
21846
21847
|
const cover_images = horizontalCoverRes.map((item) => ({
|
|
21847
21848
|
src: item.bos_url,
|
|
@@ -21854,7 +21855,7 @@ const mockAction$5 = async (task, params) => {
|
|
|
21854
21855
|
}));
|
|
21855
21856
|
const isAi = params.settingInfo.baijiahaoIsAi.includes("isAi");
|
|
21856
21857
|
const activityList = params.settingInfo.baijiahaoSelectActivityCache;
|
|
21857
|
-
const cover_layout =
|
|
21858
|
+
const cover_layout = baijiahaoCoverType === "single" ? "one" : "three";
|
|
21858
21859
|
const activity_list = [
|
|
21859
21860
|
...activityList.length > 0 ? [{ id: `task_${activityList[0]}`, is_checked: 1 }] : [],
|
|
21860
21861
|
...isAi ? [{ id: "aigc_bjh_status", is_checked: 1 }] : []
|
|
@@ -21920,19 +21921,245 @@ const getBaijiahaoActivity = async (task, params) => {
|
|
|
21920
21921
|
return res.data.data.list;
|
|
21921
21922
|
};
|
|
21922
21923
|
|
|
21924
|
+
const getToutiaoConfig = async (task, params) => {
|
|
21925
|
+
task.logger.info("\u83B7\u53D6\u5934\u6761\u53D1\u5E03\u914D\u7F6E\u7684\u8BDD\u9898\u4FE1\u606F\u3001\u4F4D\u7F6E\u4FE1\u606F\u548C\u539F\u521B\u9996\u53D1\u4FE1\u606F");
|
|
21926
|
+
const api = axios$1.create({
|
|
21927
|
+
headers: {
|
|
21928
|
+
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
|
|
21929
|
+
referer: "https://mp.toutiao.com/profile_v4/graphic/publish"
|
|
21930
|
+
}
|
|
21931
|
+
});
|
|
21932
|
+
const getSuggestWords = async () => {
|
|
21933
|
+
try {
|
|
21934
|
+
const res = await api({
|
|
21935
|
+
method: "get",
|
|
21936
|
+
url: "https://mp.toutiao.com/mp/agw/creator_helper/suggest_words",
|
|
21937
|
+
params: { type: 2, words: "" }
|
|
21938
|
+
});
|
|
21939
|
+
return res.data.code === 0 ? res.data.hots : [];
|
|
21940
|
+
} catch (error) {
|
|
21941
|
+
return [];
|
|
21942
|
+
}
|
|
21943
|
+
};
|
|
21944
|
+
const getCityDistrict = async () => {
|
|
21945
|
+
try {
|
|
21946
|
+
const res = await api.get(
|
|
21947
|
+
"https://mp.toutiao.com/toutiao/normandy/mp/city_district/"
|
|
21948
|
+
);
|
|
21949
|
+
return res.data.status === 0 ? res.data.data : null;
|
|
21950
|
+
} catch (error) {
|
|
21951
|
+
return null;
|
|
21952
|
+
}
|
|
21953
|
+
};
|
|
21954
|
+
const getUserRights = async () => {
|
|
21955
|
+
try {
|
|
21956
|
+
const res = await api.get("https://mp.toutiao.com/mp/agw/creator_project/get_benefit_page_info");
|
|
21957
|
+
return res.data.code === 0 ? res.data.data.benefit_level_info_list : [];
|
|
21958
|
+
} catch (error) {
|
|
21959
|
+
return [];
|
|
21960
|
+
}
|
|
21961
|
+
};
|
|
21962
|
+
const [suggestWords, cityDistrict, userRights] = await Promise.all([
|
|
21963
|
+
getSuggestWords(),
|
|
21964
|
+
getCityDistrict(),
|
|
21965
|
+
getUserRights()
|
|
21966
|
+
]);
|
|
21967
|
+
return { suggestWords, cityDistrict, userRights };
|
|
21968
|
+
};
|
|
21969
|
+
|
|
21970
|
+
const searchToutiaoTopicList = async (task, params) => {
|
|
21971
|
+
task.logger.info("\u641C\u7D22\u5934\u6761\u8BDD\u9898");
|
|
21972
|
+
const api = axios$1.create({
|
|
21973
|
+
headers: {
|
|
21974
|
+
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
|
|
21975
|
+
referer: "https://mp.toutiao.com/profile_v4/graphic/publish"
|
|
21976
|
+
}
|
|
21977
|
+
});
|
|
21978
|
+
try {
|
|
21979
|
+
const res = await api({
|
|
21980
|
+
method: "get",
|
|
21981
|
+
url: "https://mp.toutiao.com/mp/agw/creator_helper/suggest_words",
|
|
21982
|
+
params: { type: 2, words: params.searchValue }
|
|
21983
|
+
});
|
|
21984
|
+
if (res.data.code === 0) {
|
|
21985
|
+
return params.searchValue ? res.data.recents : res.data.hots;
|
|
21986
|
+
}
|
|
21987
|
+
return [];
|
|
21988
|
+
} catch (error) {
|
|
21989
|
+
return [];
|
|
21990
|
+
}
|
|
21991
|
+
};
|
|
21992
|
+
|
|
21993
|
+
const COVER_TYPE = {
|
|
21994
|
+
no: 1,
|
|
21995
|
+
single: 2,
|
|
21996
|
+
multiple: 3
|
|
21997
|
+
};
|
|
21998
|
+
const errnoMap = {
|
|
21999
|
+
20004020: "\u56FE\u7247\u4E0A\u4F20\u51FA\u73B0\u95EE\u9898\uFF0C\u8BF7\u91CD\u65B0\u7ED1\u5B9A\u8D26\u53F7\u540E\u518D\u5C1D\u8BD5",
|
|
22000
|
+
7115: "\u6B63\u6587\u548C\u5C01\u9762\u56FE\u7247\u63A8\u8350\u4F7F\u752820M\u4EE5\u5185\u7684jpg\u548Cpng\u56FE\u7247",
|
|
22001
|
+
100006: "\u6587\u7AE0\u53D1\u5E03\u51FA\u73B0\u95EE\u9898\uFF0C\u8BF7\u91CD\u65B0\u7ED1\u5B9A\u8D26\u53F7\u540E\u518D\u5C1D\u8BD5",
|
|
22002
|
+
3101: "\u7F51\u7EDC\u73AF\u5883\u6709\u95EE\u9898\uFF0C\u9700\u8981\u53BB\u5E73\u53F0\u5B8C\u6210\u9A8C\u8BC1",
|
|
22003
|
+
2007: "\u6587\u7AE0\u53D1\u5E03\u51FA\u73B0\u95EE\u9898\uFF0C\u58F0\u660E\u539F\u521B\u65F6\uFF0C\u6B63\u6587\u5B57\u6570\u9700\u5927\u4E8E300\u5B57",
|
|
22004
|
+
1053: "\u6B63\u6587\u548C\u5C01\u9762\u56FE\u7247\u63A8\u8350\u4F7F\u752820M\u4EE5\u5185\u7684jpg\u548Cpng\u56FE\u7247",
|
|
22005
|
+
2005: "\u65E0\u58F0\u660E\u539F\u521B\u6743\u9650\uFF0C\u8BF7\u53D6\u6D88\u539F\u521B\u58F0\u660E\u6216\u7533\u8BF7\u539F\u521B\u6743\u9650\u540E\u518D\u5C1D\u8BD5"
|
|
22006
|
+
};
|
|
21923
22007
|
const mockAction$4 = async (task, params) => {
|
|
21924
|
-
|
|
22008
|
+
const { toutiaoSingleCover, toutiaoMultCover, toutiaoCoverType, toutiaoOriginal } = params.settingInfo;
|
|
22009
|
+
const tmpCachePath = task.getTmpPath();
|
|
21925
22010
|
const api = axios$1.create({
|
|
21926
22011
|
headers: {
|
|
21927
|
-
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";")
|
|
22012
|
+
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
|
|
22013
|
+
origin: "https://mp.toutiao.com",
|
|
22014
|
+
referer: "https://mp.toutiao.com/profile_v4/graphic/publish"
|
|
21928
22015
|
}
|
|
21929
22016
|
});
|
|
21930
|
-
|
|
21931
|
-
|
|
22017
|
+
api.interceptors.response.use(
|
|
22018
|
+
(response) => {
|
|
22019
|
+
if (response.data.code !== 0) {
|
|
22020
|
+
const errmsg = errnoMap[response.data.code] || response.config.defaultErrorMsg || response.data.message || "Unknown error";
|
|
22021
|
+
task.logger.error(errmsg);
|
|
22022
|
+
return Promise.reject(new Error(errmsg));
|
|
22023
|
+
}
|
|
22024
|
+
return response;
|
|
22025
|
+
},
|
|
22026
|
+
(error) => {
|
|
22027
|
+
return Promise.reject(error);
|
|
22028
|
+
}
|
|
21932
22029
|
);
|
|
21933
|
-
|
|
21934
|
-
|
|
21935
|
-
|
|
22030
|
+
await api({
|
|
22031
|
+
method: "get",
|
|
22032
|
+
url: "https://mp.toutiao.com/mp/agw/creator_center/user_info",
|
|
22033
|
+
defaultErrorMsg: "\u767B\u5F55\u5931\u6548"
|
|
22034
|
+
});
|
|
22035
|
+
const uploadImages = async (images) => {
|
|
22036
|
+
const localImages = await Promise.all(
|
|
22037
|
+
images.map((url) => {
|
|
22038
|
+
const fileName = getFilenameFromUrl(url);
|
|
22039
|
+
return downloadImage(url, path__default.join(tmpCachePath, fileName));
|
|
22040
|
+
})
|
|
22041
|
+
);
|
|
22042
|
+
return await Promise.all(
|
|
22043
|
+
localImages.map(async (image) => {
|
|
22044
|
+
const formData = new FormData$2();
|
|
22045
|
+
formData.append("image", fs__default.createReadStream(image));
|
|
22046
|
+
const response = await api({
|
|
22047
|
+
method: "post",
|
|
22048
|
+
url: "https://mp.toutiao.com/spice/image?upload_source=20020003&aid=1231&device_platform=web",
|
|
22049
|
+
data: formData,
|
|
22050
|
+
defaultErrorMsg: "\u4E0A\u4F20\u5934\u6761\u53F7\u56FE\u7247\u5931\u8D25"
|
|
22051
|
+
});
|
|
22052
|
+
return response.data.data;
|
|
22053
|
+
})
|
|
22054
|
+
);
|
|
22055
|
+
};
|
|
22056
|
+
const originContentImages = extractImgTag(params.content);
|
|
22057
|
+
const targetContentImages = await uploadImages(originContentImages);
|
|
22058
|
+
const content = replaceImgSrc(params.content, (dom) => {
|
|
22059
|
+
if (dom.attribs.src) {
|
|
22060
|
+
const idx = originContentImages.findIndex((it) => it === dom.attribs.src);
|
|
22061
|
+
dom.attribs.src = targetContentImages[idx].image_url;
|
|
22062
|
+
dom.attribs.web_uri = targetContentImages[idx].image_uri;
|
|
22063
|
+
dom.attribs.img_width = targetContentImages[idx].image_width.toString();
|
|
22064
|
+
dom.attribs.image_height = targetContentImages[idx].image_height.toString();
|
|
22065
|
+
dom.attribs.image_type = targetContentImages[idx].image_type.toString();
|
|
22066
|
+
dom.attribs.mime_type = targetContentImages[idx].image_mime_type;
|
|
22067
|
+
}
|
|
22068
|
+
return dom;
|
|
22069
|
+
});
|
|
22070
|
+
const coverUrl = toutiaoCoverType === "single" ? [toutiaoSingleCover] : toutiaoCoverType === "multiple" ? toutiaoMultCover : [];
|
|
22071
|
+
const coverRes = await uploadImages(coverUrl);
|
|
22072
|
+
const isSingleTitle = params.settingInfo.toutiaoTitleType === "single";
|
|
22073
|
+
const location = params.settingInfo.toutiaoLocation;
|
|
22074
|
+
const topics = params.settingInfo.toutiaoTopic || [];
|
|
22075
|
+
const multiTitleData = params.settingInfo.subTitles.map((title) => ({
|
|
22076
|
+
id: "0",
|
|
22077
|
+
visibility_level: 0,
|
|
22078
|
+
source: "author",
|
|
22079
|
+
old_source: "author",
|
|
22080
|
+
text: title,
|
|
22081
|
+
version: "author",
|
|
22082
|
+
ai_title: ""
|
|
22083
|
+
}));
|
|
22084
|
+
const topicContent = topics.map(
|
|
22085
|
+
(topic) => `<p><a class="tteditor-forum" data-name="${topic.word}" data-id="${topic.id}" data-concern-id="${topic.id}">#${topic.word}#</a ></p >`
|
|
22086
|
+
).join("");
|
|
22087
|
+
const extraData = {
|
|
22088
|
+
content_word_cnt: params.settingInfo.cntWord,
|
|
22089
|
+
is_multi_title: isSingleTitle ? 0 : 1,
|
|
22090
|
+
sub_titles: isSingleTitle ? [] : multiTitleData,
|
|
22091
|
+
gd_ext: {
|
|
22092
|
+
entrance: "",
|
|
22093
|
+
from_page: "publisher_mp",
|
|
22094
|
+
enter_from: "PC",
|
|
22095
|
+
device_platform: "mp",
|
|
22096
|
+
is_message: 0
|
|
22097
|
+
},
|
|
22098
|
+
tuwen_wtt_trans_flag: "0",
|
|
22099
|
+
info_source: {
|
|
22100
|
+
source_type: 5,
|
|
22101
|
+
source_link: "",
|
|
22102
|
+
time_format: "",
|
|
22103
|
+
position: {}
|
|
22104
|
+
},
|
|
22105
|
+
...location ? { city: location.label, city_code: location.value } : null
|
|
22106
|
+
};
|
|
22107
|
+
const publishData = {
|
|
22108
|
+
article_type: 0,
|
|
22109
|
+
source: 0,
|
|
22110
|
+
search_creation_info: '{"searchTopOne": 0, "abstract": "", "clue_id": ""}',
|
|
22111
|
+
title_id: "",
|
|
22112
|
+
educluecard: "",
|
|
22113
|
+
origin_debut_check_pgc_normal: 1,
|
|
22114
|
+
is_fans_article: 0,
|
|
22115
|
+
govern_forward: 0,
|
|
22116
|
+
praise: 0,
|
|
22117
|
+
disable_praise: 0,
|
|
22118
|
+
tree_plan_article: 0,
|
|
22119
|
+
star_order_id: "",
|
|
22120
|
+
star_order_name: "",
|
|
22121
|
+
customer_nick_name: "",
|
|
22122
|
+
activity_tag: 0,
|
|
22123
|
+
trends_writing_tag: 0,
|
|
22124
|
+
is_refute_rumor: 0,
|
|
22125
|
+
save: params.saveType === "publish" ? 1 : 0,
|
|
22126
|
+
timer_status: 0,
|
|
22127
|
+
timer_time: "",
|
|
22128
|
+
title: params.title,
|
|
22129
|
+
content: content + topicContent,
|
|
22130
|
+
extra: JSON.stringify(extraData),
|
|
22131
|
+
mp_editor_stat: toutiaoCoverType === "no" ? "{}" : '{"image": %d}',
|
|
22132
|
+
draft_form_data: JSON.stringify({
|
|
22133
|
+
coverType: COVER_TYPE[toutiaoCoverType]
|
|
22134
|
+
}),
|
|
22135
|
+
pgc_feed_covers: JSON.stringify(
|
|
22136
|
+
coverRes.map((item) => ({
|
|
22137
|
+
id: "",
|
|
22138
|
+
url: item.image_url,
|
|
22139
|
+
uri: item.image_uri,
|
|
22140
|
+
ic_uri: "",
|
|
22141
|
+
thumb_widt: item.image_width,
|
|
22142
|
+
thumb_heigh: item.image_height,
|
|
22143
|
+
extra: {
|
|
22144
|
+
from_content_uri: "",
|
|
22145
|
+
from_content: "0"
|
|
22146
|
+
}
|
|
22147
|
+
}))
|
|
22148
|
+
),
|
|
22149
|
+
article_ad_type: params.settingInfo.toutiaoAd === "yes" ? 3 : 2,
|
|
22150
|
+
claim_origin: toutiaoOriginal.includes("original") ? 1 : 0,
|
|
22151
|
+
claim_exclusive: toutiaoOriginal.includes("exclusive") ? 1 : 0
|
|
22152
|
+
};
|
|
22153
|
+
const publishResult = await api({
|
|
22154
|
+
method: "post",
|
|
22155
|
+
url: "https://mp.toutiao.com/mp/agw/article/publish?source=mp&type=article&aid=1",
|
|
22156
|
+
data: publishData,
|
|
22157
|
+
headers: {
|
|
22158
|
+
"content-type": "application/x-www-form-urlencoded"
|
|
22159
|
+
},
|
|
22160
|
+
defaultErrorMsg: "\u6587\u7AE0\u53D1\u5E03\u51FA\u73B0\u95EE\u9898\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D"
|
|
22161
|
+
});
|
|
22162
|
+
return publishResult.data.data.pgc_id;
|
|
21936
22163
|
};
|
|
21937
22164
|
|
|
21938
22165
|
const toutiaoPublish = async (task, params) => {
|
|
@@ -21949,9 +22176,7 @@ const mockAction$3 = async (task, params) => {
|
|
|
21949
22176
|
referer: "https://mp.toutiao.com/profile_v4/graphic/publish"
|
|
21950
22177
|
}
|
|
21951
22178
|
});
|
|
21952
|
-
const userInfoRes = await api.get(
|
|
21953
|
-
"https://mp.toutiao.com/mp/agw/creator_center/user_info"
|
|
21954
|
-
);
|
|
22179
|
+
const userInfoRes = await api.get("https://mp.toutiao.com/mp/agw/creator_center/user_info");
|
|
21955
22180
|
if (userInfoRes.data.code !== 0) {
|
|
21956
22181
|
throw new Error("\u767B\u5F55\u5931\u6548");
|
|
21957
22182
|
}
|
|
@@ -22508,6 +22733,14 @@ class Action {
|
|
|
22508
22733
|
constructor(task) {
|
|
22509
22734
|
this.task = task;
|
|
22510
22735
|
}
|
|
22736
|
+
// 搜索头条话题列表
|
|
22737
|
+
searchToutiaoTopicList(params) {
|
|
22738
|
+
return searchToutiaoTopicList(this.task, params);
|
|
22739
|
+
}
|
|
22740
|
+
// 获取头条配置
|
|
22741
|
+
getToutiaoConfig(params) {
|
|
22742
|
+
return getToutiaoConfig(this.task, params);
|
|
22743
|
+
}
|
|
22511
22744
|
// 百家号发布
|
|
22512
22745
|
baijiahaoPublish(params) {
|
|
22513
22746
|
return baijiahaoPublish(this.task, params);
|
package/dist/index.mjs
CHANGED
|
@@ -21734,7 +21734,7 @@ const replaceImgSrc = (html, callback) => {
|
|
|
21734
21734
|
return lastedHtml;
|
|
21735
21735
|
};
|
|
21736
21736
|
|
|
21737
|
-
const errnoMap = {
|
|
21737
|
+
const errnoMap$1 = {
|
|
21738
21738
|
20040706: "\u6B63\u6587\u548C\u5C01\u9762\u56FE\u7247\u63A8\u8350\u4F7F\u752820M\u4EE5\u5185\u7684jpg\u548Cpng\u56FE\u7247",
|
|
21739
21739
|
20040084: "\u6B63\u6587\u548C\u5C01\u9762\u56FE\u7247\u63A8\u8350\u4F7F\u752820M\u4EE5\u5185\u7684jpg\u548Cpng\u56FE\u7247",
|
|
21740
21740
|
20050004: "\u53D1\u5E03\u6B21\u6570\u7528\u5C3D\uFF0C\u8BF7\u660E\u5929\u518D\u8BD5",
|
|
@@ -21747,6 +21747,7 @@ const errnoMap = {
|
|
|
21747
21747
|
401100032: "\u4E0D\u652F\u6301\u8BE5\u5A92\u8D44\u7C7B\u578B\uFF0C\u8BF7\u68C0\u67E5\u56FE\u7247\uFF08\u4F8B\u5982\uFF1A\u7248\u6743\uFF09"
|
|
21748
21748
|
};
|
|
21749
21749
|
const mockAction$5 = async (task, params) => {
|
|
21750
|
+
const { baijiahaoSingleCover, baijiahaoMultCover, baijiahaoCoverType } = params.settingInfo;
|
|
21750
21751
|
const tmpCachePath = task.getTmpPath();
|
|
21751
21752
|
const api = axios$1.create({
|
|
21752
21753
|
headers: {
|
|
@@ -21757,7 +21758,7 @@ const mockAction$5 = async (task, params) => {
|
|
|
21757
21758
|
api.interceptors.response.use(
|
|
21758
21759
|
(response) => {
|
|
21759
21760
|
if (response.data.errno !== 0) {
|
|
21760
|
-
const errmsg = errnoMap[response.data.errno] || response.config.defaultErrorMsg || response.data.errmsg || "Unknown error";
|
|
21761
|
+
const errmsg = errnoMap$1[response.data.errno] || response.config.defaultErrorMsg || response.data.errmsg || "Unknown error";
|
|
21761
21762
|
task.logger.error(errmsg);
|
|
21762
21763
|
return Promise.reject(new Error(errmsg));
|
|
21763
21764
|
}
|
|
@@ -21822,7 +21823,7 @@ const mockAction$5 = async (task, params) => {
|
|
|
21822
21823
|
if (vertical_cover) {
|
|
21823
21824
|
vertical_cover = (await uploadImages([vertical_cover]))[0].bos_url;
|
|
21824
21825
|
}
|
|
21825
|
-
const horizontalCoverUrl =
|
|
21826
|
+
const horizontalCoverUrl = baijiahaoCoverType === "single" ? [baijiahaoSingleCover] : baijiahaoMultCover;
|
|
21826
21827
|
const horizontalCoverRes = await uploadImages(horizontalCoverUrl);
|
|
21827
21828
|
const cover_images = horizontalCoverRes.map((item) => ({
|
|
21828
21829
|
src: item.bos_url,
|
|
@@ -21835,7 +21836,7 @@ const mockAction$5 = async (task, params) => {
|
|
|
21835
21836
|
}));
|
|
21836
21837
|
const isAi = params.settingInfo.baijiahaoIsAi.includes("isAi");
|
|
21837
21838
|
const activityList = params.settingInfo.baijiahaoSelectActivityCache;
|
|
21838
|
-
const cover_layout =
|
|
21839
|
+
const cover_layout = baijiahaoCoverType === "single" ? "one" : "three";
|
|
21839
21840
|
const activity_list = [
|
|
21840
21841
|
...activityList.length > 0 ? [{ id: `task_${activityList[0]}`, is_checked: 1 }] : [],
|
|
21841
21842
|
...isAi ? [{ id: "aigc_bjh_status", is_checked: 1 }] : []
|
|
@@ -21901,19 +21902,245 @@ const getBaijiahaoActivity = async (task, params) => {
|
|
|
21901
21902
|
return res.data.data.list;
|
|
21902
21903
|
};
|
|
21903
21904
|
|
|
21905
|
+
const getToutiaoConfig = async (task, params) => {
|
|
21906
|
+
task.logger.info("\u83B7\u53D6\u5934\u6761\u53D1\u5E03\u914D\u7F6E\u7684\u8BDD\u9898\u4FE1\u606F\u3001\u4F4D\u7F6E\u4FE1\u606F\u548C\u539F\u521B\u9996\u53D1\u4FE1\u606F");
|
|
21907
|
+
const api = axios$1.create({
|
|
21908
|
+
headers: {
|
|
21909
|
+
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
|
|
21910
|
+
referer: "https://mp.toutiao.com/profile_v4/graphic/publish"
|
|
21911
|
+
}
|
|
21912
|
+
});
|
|
21913
|
+
const getSuggestWords = async () => {
|
|
21914
|
+
try {
|
|
21915
|
+
const res = await api({
|
|
21916
|
+
method: "get",
|
|
21917
|
+
url: "https://mp.toutiao.com/mp/agw/creator_helper/suggest_words",
|
|
21918
|
+
params: { type: 2, words: "" }
|
|
21919
|
+
});
|
|
21920
|
+
return res.data.code === 0 ? res.data.hots : [];
|
|
21921
|
+
} catch (error) {
|
|
21922
|
+
return [];
|
|
21923
|
+
}
|
|
21924
|
+
};
|
|
21925
|
+
const getCityDistrict = async () => {
|
|
21926
|
+
try {
|
|
21927
|
+
const res = await api.get(
|
|
21928
|
+
"https://mp.toutiao.com/toutiao/normandy/mp/city_district/"
|
|
21929
|
+
);
|
|
21930
|
+
return res.data.status === 0 ? res.data.data : null;
|
|
21931
|
+
} catch (error) {
|
|
21932
|
+
return null;
|
|
21933
|
+
}
|
|
21934
|
+
};
|
|
21935
|
+
const getUserRights = async () => {
|
|
21936
|
+
try {
|
|
21937
|
+
const res = await api.get("https://mp.toutiao.com/mp/agw/creator_project/get_benefit_page_info");
|
|
21938
|
+
return res.data.code === 0 ? res.data.data.benefit_level_info_list : [];
|
|
21939
|
+
} catch (error) {
|
|
21940
|
+
return [];
|
|
21941
|
+
}
|
|
21942
|
+
};
|
|
21943
|
+
const [suggestWords, cityDistrict, userRights] = await Promise.all([
|
|
21944
|
+
getSuggestWords(),
|
|
21945
|
+
getCityDistrict(),
|
|
21946
|
+
getUserRights()
|
|
21947
|
+
]);
|
|
21948
|
+
return { suggestWords, cityDistrict, userRights };
|
|
21949
|
+
};
|
|
21950
|
+
|
|
21951
|
+
const searchToutiaoTopicList = async (task, params) => {
|
|
21952
|
+
task.logger.info("\u641C\u7D22\u5934\u6761\u8BDD\u9898");
|
|
21953
|
+
const api = axios$1.create({
|
|
21954
|
+
headers: {
|
|
21955
|
+
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
|
|
21956
|
+
referer: "https://mp.toutiao.com/profile_v4/graphic/publish"
|
|
21957
|
+
}
|
|
21958
|
+
});
|
|
21959
|
+
try {
|
|
21960
|
+
const res = await api({
|
|
21961
|
+
method: "get",
|
|
21962
|
+
url: "https://mp.toutiao.com/mp/agw/creator_helper/suggest_words",
|
|
21963
|
+
params: { type: 2, words: params.searchValue }
|
|
21964
|
+
});
|
|
21965
|
+
if (res.data.code === 0) {
|
|
21966
|
+
return params.searchValue ? res.data.recents : res.data.hots;
|
|
21967
|
+
}
|
|
21968
|
+
return [];
|
|
21969
|
+
} catch (error) {
|
|
21970
|
+
return [];
|
|
21971
|
+
}
|
|
21972
|
+
};
|
|
21973
|
+
|
|
21974
|
+
const COVER_TYPE = {
|
|
21975
|
+
no: 1,
|
|
21976
|
+
single: 2,
|
|
21977
|
+
multiple: 3
|
|
21978
|
+
};
|
|
21979
|
+
const errnoMap = {
|
|
21980
|
+
20004020: "\u56FE\u7247\u4E0A\u4F20\u51FA\u73B0\u95EE\u9898\uFF0C\u8BF7\u91CD\u65B0\u7ED1\u5B9A\u8D26\u53F7\u540E\u518D\u5C1D\u8BD5",
|
|
21981
|
+
7115: "\u6B63\u6587\u548C\u5C01\u9762\u56FE\u7247\u63A8\u8350\u4F7F\u752820M\u4EE5\u5185\u7684jpg\u548Cpng\u56FE\u7247",
|
|
21982
|
+
100006: "\u6587\u7AE0\u53D1\u5E03\u51FA\u73B0\u95EE\u9898\uFF0C\u8BF7\u91CD\u65B0\u7ED1\u5B9A\u8D26\u53F7\u540E\u518D\u5C1D\u8BD5",
|
|
21983
|
+
3101: "\u7F51\u7EDC\u73AF\u5883\u6709\u95EE\u9898\uFF0C\u9700\u8981\u53BB\u5E73\u53F0\u5B8C\u6210\u9A8C\u8BC1",
|
|
21984
|
+
2007: "\u6587\u7AE0\u53D1\u5E03\u51FA\u73B0\u95EE\u9898\uFF0C\u58F0\u660E\u539F\u521B\u65F6\uFF0C\u6B63\u6587\u5B57\u6570\u9700\u5927\u4E8E300\u5B57",
|
|
21985
|
+
1053: "\u6B63\u6587\u548C\u5C01\u9762\u56FE\u7247\u63A8\u8350\u4F7F\u752820M\u4EE5\u5185\u7684jpg\u548Cpng\u56FE\u7247",
|
|
21986
|
+
2005: "\u65E0\u58F0\u660E\u539F\u521B\u6743\u9650\uFF0C\u8BF7\u53D6\u6D88\u539F\u521B\u58F0\u660E\u6216\u7533\u8BF7\u539F\u521B\u6743\u9650\u540E\u518D\u5C1D\u8BD5"
|
|
21987
|
+
};
|
|
21904
21988
|
const mockAction$4 = async (task, params) => {
|
|
21905
|
-
|
|
21989
|
+
const { toutiaoSingleCover, toutiaoMultCover, toutiaoCoverType, toutiaoOriginal } = params.settingInfo;
|
|
21990
|
+
const tmpCachePath = task.getTmpPath();
|
|
21906
21991
|
const api = axios$1.create({
|
|
21907
21992
|
headers: {
|
|
21908
|
-
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";")
|
|
21993
|
+
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
|
|
21994
|
+
origin: "https://mp.toutiao.com",
|
|
21995
|
+
referer: "https://mp.toutiao.com/profile_v4/graphic/publish"
|
|
21909
21996
|
}
|
|
21910
21997
|
});
|
|
21911
|
-
|
|
21912
|
-
|
|
21998
|
+
api.interceptors.response.use(
|
|
21999
|
+
(response) => {
|
|
22000
|
+
if (response.data.code !== 0) {
|
|
22001
|
+
const errmsg = errnoMap[response.data.code] || response.config.defaultErrorMsg || response.data.message || "Unknown error";
|
|
22002
|
+
task.logger.error(errmsg);
|
|
22003
|
+
return Promise.reject(new Error(errmsg));
|
|
22004
|
+
}
|
|
22005
|
+
return response;
|
|
22006
|
+
},
|
|
22007
|
+
(error) => {
|
|
22008
|
+
return Promise.reject(error);
|
|
22009
|
+
}
|
|
21913
22010
|
);
|
|
21914
|
-
|
|
21915
|
-
|
|
21916
|
-
|
|
22011
|
+
await api({
|
|
22012
|
+
method: "get",
|
|
22013
|
+
url: "https://mp.toutiao.com/mp/agw/creator_center/user_info",
|
|
22014
|
+
defaultErrorMsg: "\u767B\u5F55\u5931\u6548"
|
|
22015
|
+
});
|
|
22016
|
+
const uploadImages = async (images) => {
|
|
22017
|
+
const localImages = await Promise.all(
|
|
22018
|
+
images.map((url) => {
|
|
22019
|
+
const fileName = getFilenameFromUrl(url);
|
|
22020
|
+
return downloadImage(url, path$1.join(tmpCachePath, fileName));
|
|
22021
|
+
})
|
|
22022
|
+
);
|
|
22023
|
+
return await Promise.all(
|
|
22024
|
+
localImages.map(async (image) => {
|
|
22025
|
+
const formData = new FormData$2();
|
|
22026
|
+
formData.append("image", fs$1.createReadStream(image));
|
|
22027
|
+
const response = await api({
|
|
22028
|
+
method: "post",
|
|
22029
|
+
url: "https://mp.toutiao.com/spice/image?upload_source=20020003&aid=1231&device_platform=web",
|
|
22030
|
+
data: formData,
|
|
22031
|
+
defaultErrorMsg: "\u4E0A\u4F20\u5934\u6761\u53F7\u56FE\u7247\u5931\u8D25"
|
|
22032
|
+
});
|
|
22033
|
+
return response.data.data;
|
|
22034
|
+
})
|
|
22035
|
+
);
|
|
22036
|
+
};
|
|
22037
|
+
const originContentImages = extractImgTag(params.content);
|
|
22038
|
+
const targetContentImages = await uploadImages(originContentImages);
|
|
22039
|
+
const content = replaceImgSrc(params.content, (dom) => {
|
|
22040
|
+
if (dom.attribs.src) {
|
|
22041
|
+
const idx = originContentImages.findIndex((it) => it === dom.attribs.src);
|
|
22042
|
+
dom.attribs.src = targetContentImages[idx].image_url;
|
|
22043
|
+
dom.attribs.web_uri = targetContentImages[idx].image_uri;
|
|
22044
|
+
dom.attribs.img_width = targetContentImages[idx].image_width.toString();
|
|
22045
|
+
dom.attribs.image_height = targetContentImages[idx].image_height.toString();
|
|
22046
|
+
dom.attribs.image_type = targetContentImages[idx].image_type.toString();
|
|
22047
|
+
dom.attribs.mime_type = targetContentImages[idx].image_mime_type;
|
|
22048
|
+
}
|
|
22049
|
+
return dom;
|
|
22050
|
+
});
|
|
22051
|
+
const coverUrl = toutiaoCoverType === "single" ? [toutiaoSingleCover] : toutiaoCoverType === "multiple" ? toutiaoMultCover : [];
|
|
22052
|
+
const coverRes = await uploadImages(coverUrl);
|
|
22053
|
+
const isSingleTitle = params.settingInfo.toutiaoTitleType === "single";
|
|
22054
|
+
const location = params.settingInfo.toutiaoLocation;
|
|
22055
|
+
const topics = params.settingInfo.toutiaoTopic || [];
|
|
22056
|
+
const multiTitleData = params.settingInfo.subTitles.map((title) => ({
|
|
22057
|
+
id: "0",
|
|
22058
|
+
visibility_level: 0,
|
|
22059
|
+
source: "author",
|
|
22060
|
+
old_source: "author",
|
|
22061
|
+
text: title,
|
|
22062
|
+
version: "author",
|
|
22063
|
+
ai_title: ""
|
|
22064
|
+
}));
|
|
22065
|
+
const topicContent = topics.map(
|
|
22066
|
+
(topic) => `<p><a class="tteditor-forum" data-name="${topic.word}" data-id="${topic.id}" data-concern-id="${topic.id}">#${topic.word}#</a ></p >`
|
|
22067
|
+
).join("");
|
|
22068
|
+
const extraData = {
|
|
22069
|
+
content_word_cnt: params.settingInfo.cntWord,
|
|
22070
|
+
is_multi_title: isSingleTitle ? 0 : 1,
|
|
22071
|
+
sub_titles: isSingleTitle ? [] : multiTitleData,
|
|
22072
|
+
gd_ext: {
|
|
22073
|
+
entrance: "",
|
|
22074
|
+
from_page: "publisher_mp",
|
|
22075
|
+
enter_from: "PC",
|
|
22076
|
+
device_platform: "mp",
|
|
22077
|
+
is_message: 0
|
|
22078
|
+
},
|
|
22079
|
+
tuwen_wtt_trans_flag: "0",
|
|
22080
|
+
info_source: {
|
|
22081
|
+
source_type: 5,
|
|
22082
|
+
source_link: "",
|
|
22083
|
+
time_format: "",
|
|
22084
|
+
position: {}
|
|
22085
|
+
},
|
|
22086
|
+
...location ? { city: location.label, city_code: location.value } : null
|
|
22087
|
+
};
|
|
22088
|
+
const publishData = {
|
|
22089
|
+
article_type: 0,
|
|
22090
|
+
source: 0,
|
|
22091
|
+
search_creation_info: '{"searchTopOne": 0, "abstract": "", "clue_id": ""}',
|
|
22092
|
+
title_id: "",
|
|
22093
|
+
educluecard: "",
|
|
22094
|
+
origin_debut_check_pgc_normal: 1,
|
|
22095
|
+
is_fans_article: 0,
|
|
22096
|
+
govern_forward: 0,
|
|
22097
|
+
praise: 0,
|
|
22098
|
+
disable_praise: 0,
|
|
22099
|
+
tree_plan_article: 0,
|
|
22100
|
+
star_order_id: "",
|
|
22101
|
+
star_order_name: "",
|
|
22102
|
+
customer_nick_name: "",
|
|
22103
|
+
activity_tag: 0,
|
|
22104
|
+
trends_writing_tag: 0,
|
|
22105
|
+
is_refute_rumor: 0,
|
|
22106
|
+
save: params.saveType === "publish" ? 1 : 0,
|
|
22107
|
+
timer_status: 0,
|
|
22108
|
+
timer_time: "",
|
|
22109
|
+
title: params.title,
|
|
22110
|
+
content: content + topicContent,
|
|
22111
|
+
extra: JSON.stringify(extraData),
|
|
22112
|
+
mp_editor_stat: toutiaoCoverType === "no" ? "{}" : '{"image": %d}',
|
|
22113
|
+
draft_form_data: JSON.stringify({
|
|
22114
|
+
coverType: COVER_TYPE[toutiaoCoverType]
|
|
22115
|
+
}),
|
|
22116
|
+
pgc_feed_covers: JSON.stringify(
|
|
22117
|
+
coverRes.map((item) => ({
|
|
22118
|
+
id: "",
|
|
22119
|
+
url: item.image_url,
|
|
22120
|
+
uri: item.image_uri,
|
|
22121
|
+
ic_uri: "",
|
|
22122
|
+
thumb_widt: item.image_width,
|
|
22123
|
+
thumb_heigh: item.image_height,
|
|
22124
|
+
extra: {
|
|
22125
|
+
from_content_uri: "",
|
|
22126
|
+
from_content: "0"
|
|
22127
|
+
}
|
|
22128
|
+
}))
|
|
22129
|
+
),
|
|
22130
|
+
article_ad_type: params.settingInfo.toutiaoAd === "yes" ? 3 : 2,
|
|
22131
|
+
claim_origin: toutiaoOriginal.includes("original") ? 1 : 0,
|
|
22132
|
+
claim_exclusive: toutiaoOriginal.includes("exclusive") ? 1 : 0
|
|
22133
|
+
};
|
|
22134
|
+
const publishResult = await api({
|
|
22135
|
+
method: "post",
|
|
22136
|
+
url: "https://mp.toutiao.com/mp/agw/article/publish?source=mp&type=article&aid=1",
|
|
22137
|
+
data: publishData,
|
|
22138
|
+
headers: {
|
|
22139
|
+
"content-type": "application/x-www-form-urlencoded"
|
|
22140
|
+
},
|
|
22141
|
+
defaultErrorMsg: "\u6587\u7AE0\u53D1\u5E03\u51FA\u73B0\u95EE\u9898\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D"
|
|
22142
|
+
});
|
|
22143
|
+
return publishResult.data.data.pgc_id;
|
|
21917
22144
|
};
|
|
21918
22145
|
|
|
21919
22146
|
const toutiaoPublish = async (task, params) => {
|
|
@@ -21930,9 +22157,7 @@ const mockAction$3 = async (task, params) => {
|
|
|
21930
22157
|
referer: "https://mp.toutiao.com/profile_v4/graphic/publish"
|
|
21931
22158
|
}
|
|
21932
22159
|
});
|
|
21933
|
-
const userInfoRes = await api.get(
|
|
21934
|
-
"https://mp.toutiao.com/mp/agw/creator_center/user_info"
|
|
21935
|
-
);
|
|
22160
|
+
const userInfoRes = await api.get("https://mp.toutiao.com/mp/agw/creator_center/user_info");
|
|
21936
22161
|
if (userInfoRes.data.code !== 0) {
|
|
21937
22162
|
throw new Error("\u767B\u5F55\u5931\u6548");
|
|
21938
22163
|
}
|
|
@@ -22489,6 +22714,14 @@ class Action {
|
|
|
22489
22714
|
constructor(task) {
|
|
22490
22715
|
this.task = task;
|
|
22491
22716
|
}
|
|
22717
|
+
// 搜索头条话题列表
|
|
22718
|
+
searchToutiaoTopicList(params) {
|
|
22719
|
+
return searchToutiaoTopicList(this.task, params);
|
|
22720
|
+
}
|
|
22721
|
+
// 获取头条配置
|
|
22722
|
+
getToutiaoConfig(params) {
|
|
22723
|
+
return getToutiaoConfig(this.task, params);
|
|
22724
|
+
}
|
|
22492
22725
|
// 百家号发布
|
|
22493
22726
|
baijiahaoPublish(params) {
|
|
22494
22727
|
return baijiahaoPublish(this.task, params);
|
package/package.json
CHANGED
|
@@ -34,6 +34,7 @@ const errnoMap: Record<number, string> = {
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export const mockAction: PublishAction = async (task, params) => {
|
|
37
|
+
const { baijiahaoSingleCover, baijiahaoMultCover, baijiahaoCoverType } = params.settingInfo;
|
|
37
38
|
const tmpCachePath = task.getTmpPath();
|
|
38
39
|
|
|
39
40
|
const api = axios.create({
|
|
@@ -137,10 +138,7 @@ export const mockAction: PublishAction = async (task, params) => {
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
// 4. 上传横版封面
|
|
140
|
-
const horizontalCoverUrl =
|
|
141
|
-
params.settingInfo.baijiahaoCoverType === "single"
|
|
142
|
-
? [params.settingInfo.baijiahaoSingleCover]
|
|
143
|
-
: params.settingInfo.baijiahaoMultCover;
|
|
141
|
+
const horizontalCoverUrl = baijiahaoCoverType === "single" ? [baijiahaoSingleCover] : baijiahaoMultCover;
|
|
144
142
|
const horizontalCoverRes = await uploadImages(horizontalCoverUrl);
|
|
145
143
|
const cover_images = horizontalCoverRes.map((item) => ({
|
|
146
144
|
src: item.bos_url,
|
|
@@ -155,7 +153,7 @@ export const mockAction: PublishAction = async (task, params) => {
|
|
|
155
153
|
// 5. 构造发布数据
|
|
156
154
|
const isAi = params.settingInfo.baijiahaoIsAi.includes("isAi");
|
|
157
155
|
const activityList = params.settingInfo.baijiahaoSelectActivityCache;
|
|
158
|
-
const cover_layout =
|
|
156
|
+
const cover_layout = baijiahaoCoverType === "single" ? "one" : "three";
|
|
159
157
|
|
|
160
158
|
const activity_list = [
|
|
161
159
|
...(activityList.length > 0 ? [{ id: `task_${activityList[0]}`, is_checked: 1 }] : []),
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
|
|
3
|
+
import type { CommonAction, CookiesSetDetails } from "@iflyrpa/share";
|
|
4
|
+
import type { ActiomCommonParams, Toutiao } from "../../types";
|
|
5
|
+
|
|
6
|
+
export interface GetToutiaoConfigParams extends Omit<ActiomCommonParams, "cookies"> {
|
|
7
|
+
cookies: Partial<CookiesSetDetails>[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface GetToutiaoConfigResult {
|
|
11
|
+
suggestWords: Toutiao.Topic[];
|
|
12
|
+
cityDistrict: Toutiao.CityDistrict | null;
|
|
13
|
+
userRights: Toutiao.UserRight[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type PublishAction = CommonAction<GetToutiaoConfigParams, GetToutiaoConfigResult>;
|
|
17
|
+
|
|
18
|
+
export const getToutiaoConfig: PublishAction = async (task, params) => {
|
|
19
|
+
task.logger.info("获取头条发布配置的话题信息、位置信息和原创首发信息");
|
|
20
|
+
|
|
21
|
+
const api = axios.create({
|
|
22
|
+
headers: {
|
|
23
|
+
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
|
|
24
|
+
referer: "https://mp.toutiao.com/profile_v4/graphic/publish",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const getSuggestWords = async () => {
|
|
29
|
+
try {
|
|
30
|
+
const res = await api<{ code: number; hots: Toutiao.Topic[] }>({
|
|
31
|
+
method: "get",
|
|
32
|
+
url: "https://mp.toutiao.com/mp/agw/creator_helper/suggest_words",
|
|
33
|
+
params: { type: 2, words: "" },
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return res.data.code === 0 ? res.data.hots : [];
|
|
37
|
+
} catch (error) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const getCityDistrict = async () => {
|
|
43
|
+
try {
|
|
44
|
+
const res = await api.get<{ status: number; data: Toutiao.CityDistrict }>(
|
|
45
|
+
"https://mp.toutiao.com/toutiao/normandy/mp/city_district/",
|
|
46
|
+
);
|
|
47
|
+
return res.data.status === 0 ? res.data.data : null;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const getUserRights = async () => {
|
|
54
|
+
try {
|
|
55
|
+
const res = await api.get<{
|
|
56
|
+
code: number;
|
|
57
|
+
data: { benefit_level_info_list: Toutiao.UserRight[] };
|
|
58
|
+
}>("https://mp.toutiao.com/mp/agw/creator_project/get_benefit_page_info");
|
|
59
|
+
return res.data.code === 0 ? res.data.data.benefit_level_info_list : [];
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const [suggestWords, cityDistrict, userRights] = await Promise.all([
|
|
66
|
+
getSuggestWords(),
|
|
67
|
+
getCityDistrict(),
|
|
68
|
+
getUserRights(),
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
return { suggestWords, cityDistrict, userRights };
|
|
72
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
|
|
3
|
+
import type { CommonAction, CookiesSetDetails } from "@iflyrpa/share";
|
|
4
|
+
import type { ActiomCommonParams, Toutiao } from "../../types";
|
|
5
|
+
|
|
6
|
+
export interface SearchToutiaoTopicListParams extends Omit<ActiomCommonParams, "cookies"> {
|
|
7
|
+
cookies: Partial<CookiesSetDetails>[];
|
|
8
|
+
searchValue: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type PublishAction = CommonAction<SearchToutiaoTopicListParams, Toutiao.Topic[]>;
|
|
12
|
+
|
|
13
|
+
export const searchToutiaoTopicList: PublishAction = async (task, params) => {
|
|
14
|
+
task.logger.info("搜索头条话题");
|
|
15
|
+
|
|
16
|
+
const api = axios.create({
|
|
17
|
+
headers: {
|
|
18
|
+
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
|
|
19
|
+
referer: "https://mp.toutiao.com/profile_v4/graphic/publish",
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const res = await api<{ code: number; recents: Toutiao.Topic[]; hots: Toutiao.Topic[] }>({
|
|
25
|
+
method: "get",
|
|
26
|
+
url: "https://mp.toutiao.com/mp/agw/creator_helper/suggest_words",
|
|
27
|
+
params: { type: 2, words: params.searchValue },
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (res.data.code === 0) {
|
|
31
|
+
return params.searchValue ? res.data.recents : res.data.hots;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return [];
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -2,12 +2,26 @@ import type { CommonAction, CookiesSetDetails } from "@iflyrpa/share";
|
|
|
2
2
|
import type { ActiomCommonParams } from "../../types";
|
|
3
3
|
import { mockAction } from "./mock";
|
|
4
4
|
|
|
5
|
-
export interface ToutiaoPublishParams
|
|
6
|
-
|
|
5
|
+
export interface ToutiaoPublishParams extends Omit<ActiomCommonParams, "cookies"> {
|
|
6
|
+
saveType: "draft" | "publish"; // 保存成草稿 / 发布
|
|
7
7
|
cookies: Partial<CookiesSetDetails>[];
|
|
8
|
+
title: string;
|
|
9
|
+
content: string;
|
|
10
|
+
settingInfo: {
|
|
11
|
+
toutiaoCoverType: "single" | "multiple" | "no";
|
|
12
|
+
toutiaoTitleType: "single" | "multiple";
|
|
13
|
+
toutiaoSingleCover: string;
|
|
14
|
+
toutiaoMultCover: string[];
|
|
15
|
+
toutiaoAd: string; // 广告配置 - 投放广告/不投放广告
|
|
16
|
+
toutiaoOriginal: string; // 作品声明
|
|
17
|
+
toutiaoLocation?: { label: string; value: string }; // 位置
|
|
18
|
+
toutiaoTopic: { id: string; word: string }[]; // 话题
|
|
19
|
+
cntWord: number;
|
|
20
|
+
subTitles: string[]; // 多标题
|
|
21
|
+
};
|
|
8
22
|
}
|
|
9
23
|
|
|
10
|
-
export type PublishAction = CommonAction<ToutiaoPublishParams>;
|
|
24
|
+
export type PublishAction = CommonAction<ToutiaoPublishParams, string>;
|
|
11
25
|
|
|
12
26
|
export const toutiaoPublish: PublishAction = async (task, params) => {
|
|
13
27
|
task.logger.info("开始头条发布");
|
|
@@ -1,24 +1,222 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { downloadImage, getFilenameFromUrl } from "@iflyrpa/share";
|
|
4
|
-
import axios from "axios";
|
|
4
|
+
import axios, { type AxiosResponse } from "axios";
|
|
5
5
|
import FormData from "form-data";
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
import type { PublishAction, ToutiaoPublishParams } from ".";
|
|
8
|
+
import type { Toutiao } from "../../types";
|
|
9
|
+
import { extractImgTag, replaceImgSrc } from "../../utils";
|
|
10
|
+
|
|
11
|
+
interface CommonResponse<T = unknown> {
|
|
12
|
+
data: T;
|
|
13
|
+
code: number;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const COVER_TYPE: Record<ToutiaoPublishParams["settingInfo"]["toutiaoCoverType"], number> = {
|
|
18
|
+
no: 1,
|
|
19
|
+
single: 2,
|
|
20
|
+
multiple: 3,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const errnoMap: Record<number, string> = {
|
|
24
|
+
20004020: "图片上传出现问题,请重新绑定账号后再尝试",
|
|
25
|
+
7115: "正文和封面图片推荐使用20M以内的jpg和png图片",
|
|
26
|
+
100006: "文章发布出现问题,请重新绑定账号后再尝试",
|
|
27
|
+
3101: "网络环境有问题,需要去平台完成验证",
|
|
28
|
+
2007: "文章发布出现问题,声明原创时,正文字数需大于300字",
|
|
29
|
+
1053: "正文和封面图片推荐使用20M以内的jpg和png图片",
|
|
30
|
+
2005: "无声明原创权限,请取消原创声明或申请原创权限后再尝试",
|
|
31
|
+
};
|
|
7
32
|
|
|
8
33
|
export const mockAction: PublishAction = async (task, params) => {
|
|
34
|
+
const { toutiaoSingleCover, toutiaoMultCover, toutiaoCoverType, toutiaoOriginal } = params.settingInfo;
|
|
9
35
|
const tmpCachePath = task.getTmpPath();
|
|
10
36
|
|
|
11
37
|
const api = axios.create({
|
|
12
38
|
headers: {
|
|
13
39
|
cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
|
|
40
|
+
origin: "https://mp.toutiao.com",
|
|
41
|
+
referer: "https://mp.toutiao.com/profile_v4/graphic/publish",
|
|
14
42
|
},
|
|
15
43
|
});
|
|
16
44
|
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
45
|
+
// 添加响应拦截器
|
|
46
|
+
api.interceptors.response.use(
|
|
47
|
+
(response: AxiosResponse<CommonResponse>) => {
|
|
48
|
+
// 检查响应中的 errno 字段
|
|
49
|
+
if (response.data.code !== 0) {
|
|
50
|
+
const errmsg =
|
|
51
|
+
errnoMap[response.data.code] || response.config.defaultErrorMsg || response.data.message || "Unknown error";
|
|
52
|
+
|
|
53
|
+
task.logger.error(errmsg);
|
|
54
|
+
|
|
55
|
+
return Promise.reject(new Error(errmsg));
|
|
56
|
+
}
|
|
57
|
+
// 如果 errno 为 0,返回响应数据
|
|
58
|
+
return response;
|
|
59
|
+
},
|
|
60
|
+
(error) => {
|
|
61
|
+
// 处理响应错误
|
|
62
|
+
return Promise.reject(error);
|
|
63
|
+
},
|
|
20
64
|
);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
65
|
+
|
|
66
|
+
// 0. 校验登录
|
|
67
|
+
await api<{ code: number }>({
|
|
68
|
+
method: "get",
|
|
69
|
+
url: "https://mp.toutiao.com/mp/agw/creator_center/user_info",
|
|
70
|
+
defaultErrorMsg: "登录失效",
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const uploadImages = async (images: string[]) => {
|
|
74
|
+
// 下载图片到本地
|
|
75
|
+
const localImages = await Promise.all(
|
|
76
|
+
images.map((url) => {
|
|
77
|
+
const fileName = getFilenameFromUrl(url);
|
|
78
|
+
return downloadImage(url, path.join(tmpCachePath, fileName));
|
|
79
|
+
}),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return await Promise.all(
|
|
83
|
+
localImages.map(async (image) => {
|
|
84
|
+
const formData = new FormData();
|
|
85
|
+
formData.append("image", fs.createReadStream(image));
|
|
86
|
+
|
|
87
|
+
const response = await api<{ data: Toutiao.ImageData }>({
|
|
88
|
+
method: "post",
|
|
89
|
+
url: "https://mp.toutiao.com/spice/image?upload_source=20020003&aid=1231&device_platform=web",
|
|
90
|
+
data: formData,
|
|
91
|
+
defaultErrorMsg: "上传头条号图片失败",
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return response.data.data;
|
|
95
|
+
}),
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// 1. 提取并上传正文中的图片
|
|
100
|
+
const originContentImages = extractImgTag(params.content);
|
|
101
|
+
const targetContentImages = await uploadImages(originContentImages);
|
|
102
|
+
// 2. 替换正文中的图片
|
|
103
|
+
const content = replaceImgSrc(params.content, (dom) => {
|
|
104
|
+
if (dom.attribs.src) {
|
|
105
|
+
const idx = originContentImages.findIndex((it) => it === dom.attribs.src);
|
|
106
|
+
dom.attribs.src = targetContentImages[idx].image_url;
|
|
107
|
+
dom.attribs.web_uri = targetContentImages[idx].image_uri;
|
|
108
|
+
dom.attribs.img_width = targetContentImages[idx].image_width.toString();
|
|
109
|
+
dom.attribs.image_height = targetContentImages[idx].image_height.toString();
|
|
110
|
+
dom.attribs.image_type = targetContentImages[idx].image_type.toString();
|
|
111
|
+
dom.attribs.mime_type = targetContentImages[idx].image_mime_type;
|
|
112
|
+
}
|
|
113
|
+
return dom;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// 3. 上传横版封面
|
|
117
|
+
const coverUrl =
|
|
118
|
+
toutiaoCoverType === "single" ? [toutiaoSingleCover] : toutiaoCoverType === "multiple" ? toutiaoMultCover : [];
|
|
119
|
+
const coverRes = await uploadImages(coverUrl);
|
|
120
|
+
|
|
121
|
+
// 4. 构造发布数据
|
|
122
|
+
const isSingleTitle = params.settingInfo.toutiaoTitleType === "single";
|
|
123
|
+
const location = params.settingInfo.toutiaoLocation;
|
|
124
|
+
const topics = params.settingInfo.toutiaoTopic || [];
|
|
125
|
+
|
|
126
|
+
const multiTitleData = params.settingInfo.subTitles.map((title) => ({
|
|
127
|
+
id: "0",
|
|
128
|
+
visibility_level: 0,
|
|
129
|
+
source: "author",
|
|
130
|
+
old_source: "author",
|
|
131
|
+
text: title,
|
|
132
|
+
version: "author",
|
|
133
|
+
ai_title: "",
|
|
134
|
+
}));
|
|
135
|
+
|
|
136
|
+
const topicContent = topics
|
|
137
|
+
.map(
|
|
138
|
+
(topic) =>
|
|
139
|
+
`<p><a class="tteditor-forum" data-name="${topic.word}" data-id="${topic.id}" data-concern-id="${topic.id}">#${topic.word}#</a ></p >`,
|
|
140
|
+
)
|
|
141
|
+
.join("");
|
|
142
|
+
|
|
143
|
+
const extraData = {
|
|
144
|
+
content_word_cnt: params.settingInfo.cntWord,
|
|
145
|
+
is_multi_title: isSingleTitle ? 0 : 1,
|
|
146
|
+
sub_titles: isSingleTitle ? [] : multiTitleData,
|
|
147
|
+
gd_ext: {
|
|
148
|
+
entrance: "",
|
|
149
|
+
from_page: "publisher_mp",
|
|
150
|
+
enter_from: "PC",
|
|
151
|
+
device_platform: "mp",
|
|
152
|
+
is_message: 0,
|
|
153
|
+
},
|
|
154
|
+
tuwen_wtt_trans_flag: "0",
|
|
155
|
+
info_source: {
|
|
156
|
+
source_type: 5,
|
|
157
|
+
source_link: "",
|
|
158
|
+
time_format: "",
|
|
159
|
+
position: {},
|
|
160
|
+
},
|
|
161
|
+
...(location ? { city: location.label, city_code: location.value } : null),
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const publishData = {
|
|
165
|
+
article_type: 0,
|
|
166
|
+
source: 0,
|
|
167
|
+
search_creation_info: '{"searchTopOne": 0, "abstract": "", "clue_id": ""}',
|
|
168
|
+
title_id: "",
|
|
169
|
+
educluecard: "",
|
|
170
|
+
origin_debut_check_pgc_normal: 1,
|
|
171
|
+
is_fans_article: 0,
|
|
172
|
+
govern_forward: 0,
|
|
173
|
+
praise: 0,
|
|
174
|
+
disable_praise: 0,
|
|
175
|
+
tree_plan_article: 0,
|
|
176
|
+
star_order_id: "",
|
|
177
|
+
star_order_name: "",
|
|
178
|
+
customer_nick_name: "",
|
|
179
|
+
activity_tag: 0,
|
|
180
|
+
trends_writing_tag: 0,
|
|
181
|
+
is_refute_rumor: 0,
|
|
182
|
+
save: params.saveType === "publish" ? 1 : 0,
|
|
183
|
+
timer_status: 0,
|
|
184
|
+
timer_time: "",
|
|
185
|
+
title: params.title,
|
|
186
|
+
content: content + topicContent,
|
|
187
|
+
extra: JSON.stringify(extraData),
|
|
188
|
+
mp_editor_stat: toutiaoCoverType === "no" ? "{}" : '{"image": %d}',
|
|
189
|
+
draft_form_data: JSON.stringify({
|
|
190
|
+
coverType: COVER_TYPE[toutiaoCoverType],
|
|
191
|
+
}),
|
|
192
|
+
pgc_feed_covers: JSON.stringify(
|
|
193
|
+
coverRes.map((item) => ({
|
|
194
|
+
id: "",
|
|
195
|
+
url: item.image_url,
|
|
196
|
+
uri: item.image_uri,
|
|
197
|
+
ic_uri: "",
|
|
198
|
+
thumb_widt: item.image_width,
|
|
199
|
+
thumb_heigh: item.image_height,
|
|
200
|
+
extra: {
|
|
201
|
+
from_content_uri: "",
|
|
202
|
+
from_content: "0",
|
|
203
|
+
},
|
|
204
|
+
})),
|
|
205
|
+
),
|
|
206
|
+
article_ad_type: params.settingInfo.toutiaoAd === "yes" ? 3 : 2,
|
|
207
|
+
claim_origin: toutiaoOriginal.includes("original") ? 1 : 0,
|
|
208
|
+
claim_exclusive: toutiaoOriginal.includes("exclusive") ? 1 : 0,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const publishResult = await api<{ data: { pgc_id: string } }>({
|
|
212
|
+
method: "post",
|
|
213
|
+
url: "https://mp.toutiao.com/mp/agw/article/publish?source=mp&type=article&aid=1",
|
|
214
|
+
data: publishData,
|
|
215
|
+
headers: {
|
|
216
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
217
|
+
},
|
|
218
|
+
defaultErrorMsg: "文章发布出现问题,请联系客服",
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
return publishResult.data.data.pgc_id;
|
|
24
222
|
};
|
|
@@ -3,7 +3,9 @@ import path from "node:path";
|
|
|
3
3
|
import { downloadImage, getFilenameFromUrl } from "@iflyrpa/share";
|
|
4
4
|
import axios from "axios";
|
|
5
5
|
import FormData from "form-data";
|
|
6
|
+
|
|
6
7
|
import type { PublishAction } from ".";
|
|
8
|
+
import type { Toutiao } from "../../types";
|
|
7
9
|
|
|
8
10
|
export const mockAction: PublishAction = async (task, params) => {
|
|
9
11
|
const tmpCachePath = task.getTmpPath();
|
|
@@ -17,9 +19,7 @@ export const mockAction: PublishAction = async (task, params) => {
|
|
|
17
19
|
});
|
|
18
20
|
|
|
19
21
|
// 0. 校验登录
|
|
20
|
-
const userInfoRes = await api.get<{ code: number }>(
|
|
21
|
-
"https://mp.toutiao.com/mp/agw/creator_center/user_info",
|
|
22
|
-
);
|
|
22
|
+
const userInfoRes = await api.get<{ code: number }>("https://mp.toutiao.com/mp/agw/creator_center/user_info");
|
|
23
23
|
if (userInfoRes.data.code !== 0) {
|
|
24
24
|
throw new Error("登录失效");
|
|
25
25
|
}
|
|
@@ -39,7 +39,7 @@ export const mockAction: PublishAction = async (task, params) => {
|
|
|
39
39
|
const formData = new FormData();
|
|
40
40
|
formData.append("image", fs.createReadStream(it));
|
|
41
41
|
|
|
42
|
-
const response = await api<{ data:
|
|
42
|
+
const response = await api<{ data: Toutiao.ImageData }>({
|
|
43
43
|
method: "post",
|
|
44
44
|
url: "https://mp.toutiao.com/spice/image?upload_source=20020003&aid=1231&device_platform=web",
|
|
45
45
|
data: formData,
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { AutomateTask } from "@iflyrpa/share";
|
|
2
2
|
import { type BaijiahaoPublishParams, baijiahaoPublish } from "./actions/baijiahaoPublish";
|
|
3
3
|
import { type GetBaijiahaoActivityParams, getBaijiahaoActivity } from "./actions/getBaijiahaoActivity";
|
|
4
|
+
import { type GetToutiaoConfigParams, getToutiaoConfig } from "./actions/getToutiaoConfig";
|
|
5
|
+
import { type SearchToutiaoTopicListParams, searchToutiaoTopicList } from "./actions/searchToutiaoTopicList";
|
|
4
6
|
import { type ToutiaoPublishParams, toutiaoPublish } from "./actions/toutiaoPublish";
|
|
5
7
|
import { type WeitoutiaoPublishParams, weitoutiaoPublish } from "./actions/weitoutiaoPublish";
|
|
6
8
|
import { type WeixinPublishParams, weixinPublish } from "./actions/weixinPublish";
|
|
@@ -10,6 +12,16 @@ import { type XiaohongshuPublishParams, xiaohongshuPublish } from "./actions/xia
|
|
|
10
12
|
export class Action {
|
|
11
13
|
constructor(private task: AutomateTask) {}
|
|
12
14
|
|
|
15
|
+
// 搜索头条话题列表
|
|
16
|
+
searchToutiaoTopicList(params: SearchToutiaoTopicListParams) {
|
|
17
|
+
return searchToutiaoTopicList(this.task, params);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// 获取头条配置
|
|
21
|
+
getToutiaoConfig(params: GetToutiaoConfigParams) {
|
|
22
|
+
return getToutiaoConfig(this.task, params);
|
|
23
|
+
}
|
|
24
|
+
|
|
13
25
|
// 百家号发布
|
|
14
26
|
baijiahaoPublish(params: BaijiahaoPublishParams) {
|
|
15
27
|
return baijiahaoPublish(this.task, params);
|
package/src/types.ts
CHANGED
|
@@ -18,3 +18,40 @@ export interface WeiXinCropResult {
|
|
|
18
18
|
width: number;
|
|
19
19
|
height: number;
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
export namespace Toutiao {
|
|
23
|
+
export interface Topic {
|
|
24
|
+
concern_id: string;
|
|
25
|
+
id: string;
|
|
26
|
+
talk_count: string;
|
|
27
|
+
talk_count_str: string;
|
|
28
|
+
type: number;
|
|
29
|
+
word: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface CityDistrict {
|
|
33
|
+
gps_location: {
|
|
34
|
+
city_name: string;
|
|
35
|
+
city_code: string;
|
|
36
|
+
district_name: string;
|
|
37
|
+
district_code: string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface UserRight {
|
|
42
|
+
benefit_list: Array<unknown>;
|
|
43
|
+
describe: string;
|
|
44
|
+
fans_num_threshold: number;
|
|
45
|
+
level: number;
|
|
46
|
+
type: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ImageData {
|
|
50
|
+
image_url: string;
|
|
51
|
+
image_uri: string;
|
|
52
|
+
image_width: string;
|
|
53
|
+
image_height: string;
|
|
54
|
+
image_type: string;
|
|
55
|
+
image_mime_type: string;
|
|
56
|
+
}
|
|
57
|
+
}
|