Tiny Tiny RSS: Community

Need help for plugin with starred item

Hello guys,

I’m starting to really like what I got with my instance of TT RSS. I’m now working on the details and I would like to use the “star” button" to work like a “share to” one.
I want this because I think, especially on the Android client, that it’s a little long to use the “press long” (or use the “three dot button”), then tap “share” and finally tap on the service I need.

So I would like to make a plugin to share every item I mark via the “Star” button to something (mail the article link to someone for example).

I tried to work with the cache_starred_images plugin but it takes several minutes to make it work (without mentioning the fact that I don’t understand half of what is written in this plugin… noob problem).
I also tried with IFTTT and it’s kind of the same. It takes several minutes and I’m not a big fan of using a third party service so I’m searching for an in-house solution.

Anybody has an idea on how to do so ?

Thanks

You can actually share any feed you want, including the Starred feed, so no extra coding should be necessary. Take a look at the wiki:

https://tt-rss.org/wiki/GeneratedFeeds

e: Do keep in mind that Starred articles are handled differently in TT-RSS. They are never purged. If you “publish” an article it shows in the Published feed, which allows others to subscribe to your shared articles. Eventually those articles are purged during the normal maintenance. If you re-purpose the Starred feed for that, the articles you share will never be purged. Not necessarily a big deal, but it is something you should be aware of.

e2: Sorry, I missed where you want to share beyond just publishing to a feed. If you want the Android app to handle the “star” button differently that’s going to be more involved. If you want the server to intercept articles being starred and then email them to a specific address, that could be done. But coding a plugin on the server so the mobile app prompts you for an email address is going to be more challenging. My advice would be just to have people subscribe to one of your shared feeds or just learn to deal with a long press. (I don’t know about Android, but on iOS a long press triggers in 300 ms… That’s not exactly a long period of time to wait, is it?)

Thanks for your answer.

First, I don’t need a prompt to ask me who I want to send the mail to. It would always be to the same user (I already hace the php code for that, using phpmailer).
So I just need the php code for the expression “If article is starred then”. I understand that it won’t be so easy, that’s why I’m asking to the big guys :wink:

And I know that long press isn’t so long (even on Android). It’s just that it would be so useful to push the “Star” button and done instead of needing 3 taps, including a long one. I suggest the “plugin way” for that and not a code modification server-side or android app-side because I do understand that there are not so many people out there with the same need.

Okay… That simplifies it a bit.

So what you’ll want is to keep just the HOOK_HOUSE_KEEPING code from the cache_starred_images plugin.

You’ll simplify the init() method to just have:

$this->host = $host;
$host->add_hook($host::HOOK_HOUSE_KEEPING, $this);

Everything from lines 100-228 can probably go. Then you’ll update the hook_house_keeping method. Change lines 51 and 65 to use your plugin’s own, unique name for the plugin data (so your plugin knows which articles its already processed). Next, on line 73 you’ll see the comment actual housekeeping and below that you’ll replace the existing code with your own to send a link or whatever to the recipient.

You might want to consider structuring your plugin so that every time it’s run it collects all the newly shared articles and puts them in a single email, versus one email per shared article. Email providers are somewhat picky with spam, etc. and sending multiple emails in rapid succession is likely to trigger spam flags.

As I mentioned above, starred articles are never purged, just something to keep in mind. If your instance is shared, be aware that other users could possibly spam the recipient’s account.

he could also easily rework it to work on published articles instead which would be more fitting, i think

the button is also right there in the android app

Thanks. I don’t have an Android device so I wasn’t sure if that was an option.

OP: You should definitely use that, just re-work the database query to get published versus marked articles.

Thanks fox and JustAMacUser

I’ll try to rework the cache_starred_images plugin with your advices.

Just to be sure, when you say “re-work the database query to get published versus marked articles” that just means replace

WHERE ref_id = ttrss_entries.id AND
				marked = true AND
				site_url != '' AND 
			    ttrss_user_entries.owner_uid = ? AND

by

WHERE ref_id = ttrss_entries.id AND
				published= true AND
				site_url != '' AND 
			    ttrss_user_entries.owner_uid = ? AND

?

Yup.

/20chars…

Thanks again.

Another noob question : where do I set debug mode “on”, or at least see echo results ?

Nothing in the Event log in the Preferences of TT RSS website. I guess it’s because it only show errors but I have no results for my plugin and no way to debug using at least echo.

that depends on where you’re debugging

  1. there’s Debug::log() you can check other plugins using it for examples
  2. there’s user_error(“something”, E_USER_NOTICE)
  3. there’s always echo which you’re going to see in the console output if your plugin is invoked by the updater, for example

1 & 2 go to tt-rss event log, it doesn’t have to be an error, necessarily

Thanks again. I used 2 and it helped me to make it work.

Just out of curiosity, sometimes it works within seconds and other times it needs several minutes (it should be the same for the cached_starred_images plugin). It’s absolutely fine for my usage but I would like to understand.

The maintenance hooks runs when the daemon is done processing feed updates. By default that means a minimum of 2 minutes.

OK. Thanks for the information… and for everything.

Hello,

I have one last question about this : is there away to unpublishe the article I published after mail has been sent ? That would “clean” the published articles category as I use it.
I saw a start of a clue here but can’t find a way to write the plugin part by myself.

update ttrss_user_entries set published = false where int_id = ...

Thanks a lot for the help.

I tried with several kind of lines of code and the best I could have was :

$usth = $this->pdo->prepare("UPDATE ttrss_entries SET published = false WHERE id = ?");
$usth->execute([$line['id']]);

with ERROR :

Uncaught PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'published' in 'field list' in /var/www/ttrss/plugins.local/published_to_share/init.php:211 Stack trace: #0 /var/www/ttrss/plugins.local/published_to_share/init.php(211): PDOStatement->execute(Array) #1 /var/www/ttrss/classes/pluginhost.php(132): published_to_share->hook_house_keeping('') #2 /var/www/ttrss/classes/rssutils.php(1493): PluginHost->run_hooks(24, 'hook_house_keep...', '') #3 /var/www/ttrss/classes/rssutils.php(174): RSSUtils::housekeeping_user('1') #4 /var/www/ttrss/update.php(250): RSSUtils::update_daemon_common(50) #5 {main} thrown

Does anyone have an idea on how to fix this ?

Look at the database, took me 30 sec to find the column is in ttrss_user_entries

tl;dr

The published state is stored in ttrss_user_entries, you can see this by looking at the schema (see the schema directory in the root of the installation).

Long version:

I don’t have the complete code of your plugin, but if you have the row IDs in an array, it might be better to use PDO’s bindParam() method and then loop the execute() call. There will be a performance improvement by only creating the statement once and calling it with a new value in the variable.

For example:

$stmt = $this->pdo->prepare("UPDATE ttrss_user_entries SET published = false WHERE id = :id");
$stmt->bindParam(":id", $id, PDO::PARAM_INT);

foreach ($ids as $id) {
	$stmt->execute();
}

You could also use WHERE id IN (?,?,?) and skip the loop altogether. This method probably provides the best performance, but either would be better than re-creating the statement in a loop. Personally, I like the first method better because I find creating the exact amount of question marks in the IN clause to be ugly, but that’s just my preference.

I tried the first solution but couldn’t make it work. But the second did :slight_smile:

Thanks a lot for your help