koishi-plugin-githubsth 1.0.2-beta1 → 1.0.2-test2

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.
@@ -1,2 +1,2 @@
1
1
  import { Context } from 'koishi';
2
- export declare function apply(ctx: Context, config: any): void;
2
+ export declare function apply(ctx: Context): void;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.apply = apply;
4
- function apply(ctx, config) {
4
+ function apply(ctx) {
5
5
  const logger = ctx.logger('githubsth');
6
6
  const repoRegex = /^[\w-]+\/[\w-\.]+$/;
7
7
  const validEvents = [
@@ -9,12 +9,11 @@ function apply(ctx, config) {
9
9
  'pull_request_review', 'star', 'fork', 'release',
10
10
  'discussion', 'workflow_run'
11
11
  ];
12
- const defaultConfigEvents = config.defaultEvents || ['push', 'issues', 'issue_comment', 'pull_request', 'pull_request_review', 'release', 'star', 'fork'];
13
12
  ctx.command('githubsth.subscribe <repo> [events:text]', '订阅 GitHub 仓库')
14
13
  .alias('gh.sub')
15
14
  .usage(`
16
15
  订阅 GitHub 仓库通知。
17
- 如果不指定事件,默认订阅: ${defaultConfigEvents.join(', ')}
16
+ 如果不指定事件,默认订阅: push, issues, issue_comment, pull_request, pull_request_review, release, star, fork
18
17
 
19
18
  可选事件:
20
19
  - push: 代码推送
@@ -59,7 +58,7 @@ gh.sub koishijs/koishi push,issues,star
59
58
  }
60
59
  else {
61
60
  // Default events
62
- events = [...defaultConfigEvents];
61
+ events = ['push', 'issues', 'issue_comment', 'pull_request', 'pull_request_review', 'release', 'star', 'fork'];
63
62
  }
64
63
  try {
65
64
  // Check if subscription exists
package/lib/config.d.ts CHANGED
@@ -9,8 +9,6 @@ export interface Config {
9
9
  defaultOwner?: string;
10
10
  defaultRepo?: string;
11
11
  debug: boolean;
12
- logUnhandledEvents: boolean;
13
- defaultEvents: string[];
14
12
  rules?: Rule[];
15
13
  }
16
14
  export declare const Config: Schema<Config>;
package/lib/config.js CHANGED
@@ -6,10 +6,6 @@ exports.Config = koishi_1.Schema.object({
6
6
  defaultOwner: koishi_1.Schema.string().description('默认仓库拥有者'),
7
7
  defaultRepo: koishi_1.Schema.string().description('默认仓库名称'),
8
8
  debug: koishi_1.Schema.boolean().default(false).description('启用调试模式,输出详细日志'),
9
- logUnhandledEvents: koishi_1.Schema.boolean().default(false).description('是否记录未处理的 Webhook 事件 (Unknown events)'),
10
- defaultEvents: koishi_1.Schema.array(koishi_1.Schema.string())
11
- .default(['push', 'issues', 'issue_comment', 'pull_request', 'pull_request_review', 'release', 'star', 'fork'])
12
- .description('默认订阅事件列表 (当不指定事件时使用)'),
13
9
  rules: koishi_1.Schema.array(koishi_1.Schema.object({
14
10
  repo: koishi_1.Schema.string().required(),
15
11
  channelId: koishi_1.Schema.string().required(),
@@ -10,6 +10,5 @@ export declare class Notifier extends Service {
10
10
  constructor(ctx: Context, config: Config);
11
11
  private registerListeners;
12
12
  private handleEvent;
13
- private patchPayloadForEvent;
14
13
  private sendMessage;
15
14
  }
@@ -56,15 +56,9 @@ class Notifier extends koishi_1.Service {
56
56
  eventType = 'discussion';
57
57
  else if (payload.workflow_run)
58
58
  eventType = 'workflow_run';
59
- // Handle raw star event if it has repository info directly
60
- else if (payload.repository && (payload.action === 'created' || payload.action === 'started'))
61
- eventType = 'star';
62
59
  if (eventType !== 'unknown') {
63
60
  this.handleEvent(eventType, payload);
64
61
  }
65
- else if (this.config.logUnhandledEvents) {
66
- this.ctx.logger('githubsth').info(`Unhandled payload structure. Keys: ${Object.keys(payload).join(', ')}`);
67
- }
68
62
  }
69
63
  });
70
64
  }
@@ -86,58 +80,18 @@ class Notifier extends koishi_1.Service {
86
80
  if (!repoName && realPayload.pull_request?.base?.repo?.full_name) {
87
81
  repoName = realPayload.pull_request.base.repo.full_name;
88
82
  }
89
- // Special handling for 'star' event (which might be 'watch' event with action 'started')
90
- // The payload might be missing repository info in the main object but have it in the original session payload
91
- if (!repoName && event === 'star') {
92
- // Sometimes the repository info is at the root of the payload, not inside 'payload' property
93
- if (payload.repository?.full_name) {
94
- repoName = payload.repository.full_name;
95
- }
96
- }
97
83
  if (!repoName) {
98
84
  if (this.config.debug) {
99
- this.ctx.logger('githubsth').warn(`Missing repo info for event: ${event}. Keys: ${Object.keys(realPayload).join(', ')}`);
85
+ this.ctx.logger('githubsth').warn(`Missing repo info for event: ${event}`);
86
+ this.ctx.logger('notifier').warn(`Event ${event} missing repository info. Keys: ${Object.keys(realPayload).join(', ')}`);
100
87
  }
101
- else if (this.config.logUnhandledEvents) {
102
- // Log at warning level if repo info is missing and logUnhandledEvents is on
88
+ else {
89
+ // Log at warning level even in production if repo info is missing, as this is a critical failure
90
+ // But only log keys to avoid leaking sensitive data
103
91
  this.ctx.logger('githubsth').warn(`Missing repo info for event: ${event}. Keys: ${Object.keys(realPayload).join(', ')}`);
104
92
  }
105
93
  return;
106
94
  }
107
- // Patch realPayload with extracted repo info if missing
108
- // This is crucial for formatter to work correctly as it expects repository object
109
- if (!realPayload.repository) {
110
- realPayload.repository = { full_name: repoName };
111
- }
112
- else if (!realPayload.repository.full_name) {
113
- realPayload.repository.full_name = repoName;
114
- }
115
- // Patch realPayload with sender info if missing (e.g. issues event)
116
- if (!realPayload.sender) {
117
- if (realPayload.issue?.user) {
118
- realPayload.sender = realPayload.issue.user;
119
- }
120
- else if (realPayload.pull_request?.user) {
121
- realPayload.sender = realPayload.pull_request.user;
122
- }
123
- else if (realPayload.discussion?.user) {
124
- realPayload.sender = realPayload.discussion.user;
125
- }
126
- else if (realPayload.pusher) {
127
- realPayload.sender = { login: realPayload.pusher.name || 'Pusher' };
128
- }
129
- else {
130
- // Fallback sender
131
- realPayload.sender = { login: 'GitHub' };
132
- }
133
- }
134
- // Comprehensive patching for specific events to prevent formatter crashes
135
- try {
136
- this.patchPayloadForEvent(event, realPayload, repoName);
137
- }
138
- catch (e) {
139
- this.ctx.logger('githubsth').warn(`Failed to patch payload for ${event}:`, e);
140
- }
141
95
  if (this.config.debug) {
142
96
  this.ctx.logger('githubsth').info(`Processing event ${event} for ${repoName}`);
143
97
  this.ctx.logger('notifier').info(`Received event ${event} for ${repoName}`);
@@ -172,9 +126,6 @@ class Notifier extends koishi_1.Service {
172
126
  this.ctx.logger('githubsth').info(`No matching rules for ${repoName} (event: ${event})`);
173
127
  this.ctx.logger('notifier').debug(`No matching rules for ${repoName} (event: ${event})`);
174
128
  }
175
- else if (this.config.logUnhandledEvents) {
176
- this.ctx.logger('githubsth').warn(`No matching rules for ${repoName} (event: ${event})`);
177
- }
178
129
  return;
179
130
  }
180
131
  if (this.config.debug) {
@@ -187,160 +138,50 @@ class Notifier extends koishi_1.Service {
187
138
  this.ctx.logger('notifier').warn('Formatter service not available');
188
139
  return;
189
140
  }
190
- try {
191
- switch (event) {
192
- case 'push':
193
- message = this.ctx.githubsthFormatter.formatPush(realPayload);
194
- break;
195
- case 'issues':
196
- message = this.ctx.githubsthFormatter.formatIssue(realPayload);
197
- break;
198
- case 'pull_request':
199
- message = this.ctx.githubsthFormatter.formatPullRequest(realPayload);
200
- break;
201
- case 'star':
202
- message = this.ctx.githubsthFormatter.formatStar(realPayload);
203
- break;
204
- case 'fork':
205
- message = this.ctx.githubsthFormatter.formatFork(realPayload);
206
- break;
207
- case 'release':
208
- message = this.ctx.githubsthFormatter.formatRelease(realPayload);
209
- break;
210
- case 'discussion':
211
- message = this.ctx.githubsthFormatter.formatDiscussion(realPayload);
212
- break;
213
- case 'workflow_run':
214
- message = this.ctx.githubsthFormatter.formatWorkflowRun(realPayload);
215
- break;
216
- case 'issue_comment':
217
- message = this.ctx.githubsthFormatter.formatIssueComment(realPayload);
218
- break;
219
- case 'pull_request_review':
220
- message = this.ctx.githubsthFormatter.formatPullRequestReview(realPayload);
221
- break;
222
- }
223
- }
224
- catch (e) {
225
- this.ctx.logger('githubsth').error(`Error formatting event ${event}:`, e);
226
- if (this.config.debug) {
227
- this.ctx.logger('notifier').error(`Error formatting event ${event}:`, e);
228
- }
229
- return;
230
- }
231
- if (!message) {
232
- if (this.config.debug) {
233
- this.ctx.logger('notifier').debug(`Formatter returned null for event ${event}`);
234
- }
235
- return;
236
- }
237
- for (const rule of matchedRules) {
238
- if (this.config.debug) {
239
- this.ctx.logger('notifier').debug(`Sending message to channel ${rule.channelId} (platform: ${rule.platform || 'any'})`);
240
- }
241
- await this.sendMessage(rule, message);
242
- }
243
- }
244
- patchPayloadForEvent(event, payload, repoName) {
245
- // Ensure sender exists (handled before, but good for type safety)
246
- const defaultUser = { login: 'GitHub', id: 0, avatar_url: '' };
247
- if (!payload.sender)
248
- payload.sender = defaultUser;
249
- // Ensure repository exists (handled before, but good for type safety)
250
- const defaultRepo = { full_name: repoName, stargazers_count: 0, html_url: `https://github.com/${repoName}` };
251
- if (!payload.repository)
252
- payload.repository = defaultRepo;
253
141
  switch (event) {
254
142
  case 'push':
255
- if (!payload.pusher)
256
- payload.pusher = { name: payload.sender.login };
257
- if (!payload.commits)
258
- payload.commits = [];
259
- if (!payload.ref)
260
- payload.ref = 'refs/heads/unknown';
261
- if (!payload.compare)
262
- payload.compare = '';
263
- // Ensure author exists in commits
264
- if (payload.commits.length > 0) {
265
- payload.commits.forEach((c) => {
266
- if (!c.author)
267
- c.author = { name: 'Unknown' };
268
- if (!c.id)
269
- c.id = '0000000';
270
- if (!c.message)
271
- c.message = 'No message';
272
- });
273
- }
143
+ message = this.ctx.githubsthFormatter.formatPush(realPayload);
274
144
  break;
275
145
  case 'issues':
276
- if (!payload.action)
277
- payload.action = 'updated';
278
- if (!payload.issue)
279
- payload.issue = { number: 0, title: 'Unknown Issue', html_url: '', user: payload.sender };
280
- // Ensure user exists in issue
281
- if (!payload.issue.user)
282
- payload.issue.user = payload.sender;
146
+ message = this.ctx.githubsthFormatter.formatIssue(realPayload);
283
147
  break;
284
148
  case 'pull_request':
285
- if (!payload.action)
286
- payload.action = 'updated';
287
- if (!payload.pull_request)
288
- payload.pull_request = { number: 0, title: 'Unknown PR', state: 'unknown', html_url: '', user: payload.sender };
289
- if (!payload.pull_request.user)
290
- payload.pull_request.user = payload.sender;
149
+ message = this.ctx.githubsthFormatter.formatPullRequest(realPayload);
291
150
  break;
292
151
  case 'star':
293
- if (!payload.action)
294
- payload.action = 'created';
295
- if (payload.repository && payload.repository.stargazers_count === undefined) {
296
- payload.repository.stargazers_count = '?';
297
- }
152
+ message = this.ctx.githubsthFormatter.formatStar(realPayload);
298
153
  break;
299
154
  case 'fork':
300
- if (!payload.forkee)
301
- payload.forkee = { full_name: 'unknown/fork' };
155
+ message = this.ctx.githubsthFormatter.formatFork(realPayload);
302
156
  break;
303
157
  case 'release':
304
- if (!payload.action)
305
- payload.action = 'published';
306
- if (!payload.release)
307
- payload.release = { tag_name: 'unknown', name: 'Unknown Release', html_url: '' };
158
+ message = this.ctx.githubsthFormatter.formatRelease(realPayload);
308
159
  break;
309
160
  case 'discussion':
310
- if (!payload.action)
311
- payload.action = 'updated';
312
- if (!payload.discussion)
313
- payload.discussion = { number: 0, title: 'Unknown Discussion', html_url: '', user: payload.sender };
314
- if (!payload.discussion.user)
315
- payload.discussion.user = payload.sender;
161
+ message = this.ctx.githubsthFormatter.formatDiscussion(realPayload);
316
162
  break;
317
163
  case 'workflow_run':
318
- if (!payload.action)
319
- payload.action = 'completed';
320
- if (!payload.workflow_run)
321
- payload.workflow_run = { conclusion: 'unknown', name: 'Unknown Workflow', head_branch: 'unknown', html_url: '' };
164
+ message = this.ctx.githubsthFormatter.formatWorkflowRun(realPayload);
322
165
  break;
323
166
  case 'issue_comment':
324
- if (!payload.action)
325
- payload.action = 'created';
326
- if (!payload.issue)
327
- payload.issue = { number: 0, title: 'Unknown Issue', html_url: '', user: payload.sender };
328
- if (!payload.comment)
329
- payload.comment = { body: '', html_url: '' };
330
- if (!payload.issue.user)
331
- payload.issue.user = payload.sender;
167
+ message = this.ctx.githubsthFormatter.formatIssueComment(realPayload);
332
168
  break;
333
169
  case 'pull_request_review':
334
- if (!payload.action)
335
- payload.action = 'submitted';
336
- if (!payload.pull_request)
337
- payload.pull_request = { number: 0, title: 'Unknown PR', html_url: '', user: payload.sender };
338
- if (!payload.review)
339
- payload.review = { state: 'unknown', html_url: '' };
340
- if (!payload.pull_request.user)
341
- payload.pull_request.user = payload.sender;
170
+ message = this.ctx.githubsthFormatter.formatPullRequestReview(realPayload);
342
171
  break;
343
172
  }
173
+ if (!message) {
174
+ if (this.config.debug) {
175
+ this.ctx.logger('notifier').debug(`Formatter returned null for event ${event}`);
176
+ }
177
+ return;
178
+ }
179
+ for (const rule of matchedRules) {
180
+ if (this.config.debug) {
181
+ this.ctx.logger('notifier').debug(`Sending message to channel ${rule.channelId} (platform: ${rule.platform || 'any'})`);
182
+ }
183
+ await this.sendMessage(rule, message);
184
+ }
344
185
  }
345
186
  async sendMessage(rule, message) {
346
187
  // Find suitable bots
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-githubsth",
3
- "version": "1.0.2-beta1",
3
+ "version": "1.0.2-test2",
4
4
  "description": "Github Subscriptions Notifications, push notifications for GitHub subscriptions For koishi",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",