Misskey → Twitter 크로스포스팅 (With an Image)
from Hyun1008.log
#NodeJS
중간에 노드 서버가 하나 있어야 하긴 합니다.
미스키에서 노트를 하면, 웹훅을 통해 그 노트 정보를 중간 서버에 전송하고, 그 서버에서 데이터를 적당히 가공해서 트위터로 보내 주는 거거든요.
기존 크로스포스터를 안 쓰는 이유는
- 원본 미스키로의 url 또는 자기 서비스 해시태그가 달려 있음
- 파일을 첨부할 수 없음
그래서, 직접 만드는 김에 파일 첨부 기능도 제작했습니다.
미스키 노트에 파일이 첨부되어 있으면 웹훅으로 들어오는 요청에서 URL을 읽을 수 있습니다. 그걸 바탕으로 파일을 업로드 할거예요.
그런데 Misskey는 WebP 위주로 파일을 올려버리고, 트위터는 WebP를 제외하고 파일을 첨부합니다. 그래서 이것도 한번 png로의 변환 과정을 거쳐야 해요.
const { TwitterApi } = require('twitter-api-v2');
const axios = require('axios');
const sharp = require('sharp');
//....
app.post('/misskey', (req, res) => {
let misEvent = req.body
const twitterClient = new TwitterApi({
appKey: '',
appSecret: '',
accessToken: '',
accessSecret: '',
})
console.log(misEvent)
if (misEvent.body.note.files.length == 0 && misEvent.body.note.text) {
async function myfunction() {
(async () => {
try {
const tweet = await twitterClient.v2.tweet(misEvent.body.note.text.substring(0, 140));
console.log('Tweet posted successfully:', tweet);
res.json({ok: true})
} catch (error) {
console.error('Error posting tweet:', error);
res.json({ok: true})
}
})();
console.log('Inside of myfunction');
}
myfunction()
} else if (misEvent.body.note.files.length > 0 && misEvent.body.note.text) {
var url = misEvent.body.note.files[0].url
async function myfunction2() {
(async () => {
try {
const downStream = await axios({
method: 'GET',
responseType: 'arraybuffer',
url: url,
}).catch(function (error) {
res.send({error:error});
});
const img = await sharp(downStream.data).toFormat('png').toBuffer(); // webp → png
const mediaId = await twitterClient.v1.uploadMedia(img, { mimeType: 'png'});
const tweet = await twitterClient.v2.tweet({text: misEvent.body.note.text.substring(0, 140), media: { media_ids: [mediaId] }});
console.log('Tweet posted successfully:', tweet);
} catch (error) {
console.error('Error posting tweet:', error);
}
})();
console.log('Inside of myfunction');
}
myfunction2()
res.json({ok: true})
} else { //Text값이 없는 노트(리노트 같은 거)일 때...
res.json({ok: true})
}
})