From 0e6e0fab999459292af01c492ad4e4d8822ec349 Mon Sep 17 00:00:00 2001 From: v0n5ai Date: Sun, 29 Jun 2025 21:12:28 +0900 Subject: [PATCH 1/2] Add files via upload --- lib/Plagger/Plugin/Publish/Slack.pm | 137 ++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 lib/Plagger/Plugin/Publish/Slack.pm diff --git a/lib/Plagger/Plugin/Publish/Slack.pm b/lib/Plagger/Plugin/Publish/Slack.pm new file mode 100644 index 00000000..eb979446 --- /dev/null +++ b/lib/Plagger/Plugin/Publish/Slack.pm @@ -0,0 +1,137 @@ +package Plagger::Plugin::Publish::Slack; +use strict; +use base qw( Plagger::Plugin ); +use LWP::UserAgent; +use JSON; +use Encode; + +# プラグインのバージョン +our $VERSION = '0.01'; + +sub register { + my($self, $context) = @_; + $context->register_hook( + $self, + 'publish.entry' => \&publish, + ); +} + +# config.yamlで利用可能な設定を定義する +sub MungeConfig { + my ($self, $conf) = @_; + + # webhook_urlは必須項目 + die "Notify::Slack: 'webhook_url' is required in your config.yaml" + unless $conf->{webhook_url}; +} + +sub publish { + my($self, $context, $args) = @_; + my $entry = $args->{entry}; + + # Slack設定を取得 + my $webhook_url = $self->conf->{webhook_url} || ''; + my $channel = $self->conf->{channel} || '#general'; + my $username = $self->conf->{username} || 'Plagger Bot'; + my $icon_emoji = $self->conf->{icon_emoji} || ':newspaper:'; + + return unless $webhook_url; + + # エントリの内容を安全に取得 + my $title = eval { $entry->title } || 'No Title'; + my $body = eval { $entry->body } || 'No Body'; + my $author = eval { $entry->author } || 'Unknown Author'; + my $date = eval { $entry->date } || 'Unknown Date'; + my $link = eval { $entry->link } || ''; + + # authorを文字列に変換(オブジェクトの場合) + if (ref($author)) { + $author = "$author"; + } + + # dateを文字列に変換(オブジェクトの場合) + if (ref($date)) { + $date = "$date"; + } + + # タグ情報を安全に取得 + my $tags = ''; + if (ref($entry) && $entry->can('tags')) { + my $tag_list = eval { $entry->tags }; + if ($tag_list && ref($tag_list) eq 'ARRAY') { + $tags = join(', ', @$tag_list); + } + } + + # Slackメッセージを構築 + my $message = { + channel => $channel, + username => $username, + icon_emoji => $icon_emoji, + text => "📰 *$title*", + attachments => [ + { + color => "good", + fields => [ + { + title => "著者", + value => $author, + short => 1 + }, + { + title => "日付", + value => $date, + short => 1 + } + ], + text => substr($body, 0, 1000) . (length($body) > 1000 ? "..." : ""), + footer => $tags ? "タグ: $tags" : undef + } + ] + }; + + # リンクがある場合は追加 + if ($link) { + push @{$message->{attachments}[0]{fields}}, { + title => "リンク", + value => $link, + short => 0 + }; + } + + # Slackに投稿 + my $ua = LWP::UserAgent->new; + $ua->timeout(10); + + # JSONエンコードを安全に行う + my $json_content; + eval { + $json_content = encode_json($message); + }; + if ($@) { + $context->log(error => "JSONエンコードエラー: $@"); + # フォールバック: シンプルなメッセージを送信 + $json_content = encode_json({ + channel => $channel, + username => $username, + icon_emoji => $icon_emoji, + text => "📰 *$title*\n$link" + }); + } + + # ここでUTF-8にエンコード + $json_content = Encode::encode('UTF-8', $json_content); + + my $response = $ua->post($webhook_url, + Content_Type => 'application/json', + Content => $json_content + ); + + if ($response->is_success) { + $context->log(info => "Slackに投稿しました: $title"); + } else { + $context->log(error => "Slack投稿エラー: " . $response->status_line); + } +} + +1; From 927c26bf9481311c61a35649d232a14f706fafb0 Mon Sep 17 00:00:00 2001 From: v0n5ai Date: Fri, 2 Jan 2026 10:48:20 +0900 Subject: [PATCH 2/2] Create README.md --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..b434615f --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +https://github.com/bonsai/plagger + + + +add Publish::Slack +https://github.com/miyagawa/plagger/pull/13 + + + + +add Filter::LLM + +- module: Filter::LLM + config: + api_key: YOUR_API_KEY + # デフォルトをFlashにして節約、特定のフィードだけProにする + model: gemini-1.5-flash + rules: + - title_match: "重要論文" + model: gemini-1.5-pro