Open TomCasavant opened 1 year ago
Thanks for reporting-- this was working at some point (this switch case should handle it) but this code got heavily refactored a couple times in August/September, so probably without tests available something got broken.
Looks like there must have been problems w/ the update activity at some point and it was switched to create
oof, I wish I had documented more thoroughly what I was seeing there, because that seems like a mistake.
I'm not an expert on the Mastodon codebase but it appears that edits get broadcast as "Update" objects with a special array for the id
and the to
and cc
set to the original post id, which is interesting:
https://github.com/mastodon/mastodon/blob/c86ad4566003f15f2f4f2499efd36f20b62737ab/app/workers/activitypub/status_update_distribution_worker.rb#L18-L28
That line has been in there for 9 months though so if it was working before I doubt that's what broke it, I'm not sure how mastodon interprets a 'create' notice on an object that already exists
Yeah, I mean I'm just working from memory at this point since that was a stage of the project where I was working on it entirely on my own and doing extremely slipshod manual QA. I can take a stab at reproducing doing things "the Mastodon way" and see if that gets interop fixed for now.
(Also once we can confirm it works, getting tests set up for some degree of reproducibility, which is actually on my todo list to scaffold this evening, as I finally have a free night at home)
https://community.nodebb.org/post/101114
It turns out that just sending the Update(Note) activity was not enough, the underlying object needed to also have the updated field set in order to Mastodon to process the update. My guess is Mastodon checks that field and only processes the note if the value is greater than the last known value.
I think this might be the issue (I haven't had the opportunity to test it yet)
It works!
Probably needs a lot of cleanup and I'm not sure when I'll get the time to fully test it so here's what I have working if anyone wants to beat me to it
async function createUpdateMessage(bookmark, account, domain, db) {
const guid = await db.getGuidForBookmarkId(bookmark.id);
const guidCreate = crypto.randomBytes(16).toString('hex');
let note;
const updatedBookmark = bookmark;
console.log(bookmark.description)
updatedBookmark.title = escapeHTML(bookmark.title);
updatedBookmark.description = bookmark.description;
console.log(updatedBookmark.description)
let linkedTags = '';
if (bookmark.tags && bookmark.tags.length > 0) {
linkedTags = bookmark.tags
?.split(' ')
.map((tag) => {
const tagName = tag.slice(1);
return `<a href="https://${domain}/tagged/${tagName}" class="mention hashtag" rel="tag nofollow noopener noreferrer">${tag}</a>`;
})
.join(' ');
}
if (updatedBookmark.description?.trim().length > 0) {
updatedBookmark.description = `<br/>${updatedBookmark.description?.trim().replace('\n', '<br/>') || ''}`;
}
if (linkedTags.trim().length > 0) {
linkedTags = `<p>${linkedTags}</p>`;
}
if (guid === undefined) {
// If the bookmark was created but not published to ActivityPub, create a new note
note = createNoteObject(bookmark, account, domain);
await createMessage(note, bookmark.id, account, domain, db);
} else {
// Fetch the existing note object
const existingMessage = await db.getMessage(guid);
const existingNote = existingMessage ? JSON.parse(existingMessage.message) : null;
const publishedDate = existingNote.published;
//console.log(existingNote);
note = {
id: `https://${domain}/m/${guid}`,
type: 'Note',
attributedTo: `https://${domain}/u/${account}`,
content: `<p><strong><a href="${updatedBookmark.url}" rel="nofollow noopener noreferrer">${replaceEmptyText(
updatedBookmark.title,
updatedBookmark.url,
)}</a></strong>${updatedBookmark.description}</p>`,
published: publishedDate, // Keep the original published date
updated: new Date().toISOString(), // Set the updated date to now
to: [`https://${domain}/u/${account}/followers/`, 'https://www.w3.org/ns/activitystreams#Public'],
tag: []
};
bookmark.tags?.split(' ').forEach((tag) => {
const tagName = tag.slice(1);
note.tag.push({
type: 'Hashtag',
href: `https://${domain}/tagged/${tagName}`,
name: tag,
});
});
// Update the note in the database
await db.updateNoteByGuid(guid, note);
}
const updateMessage = {
'@context': ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'],
summary: `${account} updated the bookmark`,
id: `https://${domain}/m/${guidCreate}`,
type: 'Update',
actor: `https://${domain}/u/${account}`,
object: note.id ? note : `https://${domain}/m/${guid}`,
};
console.log(updateMessage);
//print(err);
return updateMessage;
}
I edited this bookmark: https://tomcasavant.glitch.me/bookmark/19 to correct "twee" to "tweet" and that doesn't seem to have been edited in the actual activity. I assume ActivityPub has some sort of 'edit' endpoint that needs to be hit or something?