@line-harness/sdk 0.2.2 → 0.2.4
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.
- package/dist/index.cjs +19 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.mjs +18 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -10
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
BroadcastsResource: () => BroadcastsResource,
|
|
25
25
|
FormsResource: () => FormsResource,
|
|
26
26
|
FriendsResource: () => FriendsResource,
|
|
27
|
+
ImagesResource: () => ImagesResource,
|
|
27
28
|
LineHarness: () => LineHarness,
|
|
28
29
|
LineHarnessError: () => LineHarnessError,
|
|
29
30
|
RichMenusResource: () => RichMenusResource,
|
|
@@ -109,6 +110,7 @@ var FriendsResource = class {
|
|
|
109
110
|
if (params?.limit !== void 0) query.set("limit", String(params.limit));
|
|
110
111
|
if (params?.offset !== void 0) query.set("offset", String(params.offset));
|
|
111
112
|
if (params?.tagId) query.set("tagId", params.tagId);
|
|
113
|
+
if (params?.search) query.set("search", params.search);
|
|
112
114
|
const accountId = params?.accountId ?? this.defaultAccountId;
|
|
113
115
|
if (accountId) query.set("lineAccountId", accountId);
|
|
114
116
|
const qs = query.toString();
|
|
@@ -406,6 +408,20 @@ var StaffResource = class {
|
|
|
406
408
|
}
|
|
407
409
|
};
|
|
408
410
|
|
|
411
|
+
// src/resources/images.ts
|
|
412
|
+
var ImagesResource = class {
|
|
413
|
+
constructor(http) {
|
|
414
|
+
this.http = http;
|
|
415
|
+
}
|
|
416
|
+
async upload(input) {
|
|
417
|
+
const res = await this.http.post("/api/images", input);
|
|
418
|
+
return res.data;
|
|
419
|
+
}
|
|
420
|
+
async delete(key) {
|
|
421
|
+
await this.http.delete(`/api/images/${key}`);
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
|
|
409
425
|
// src/delay.ts
|
|
410
426
|
var MULTIPLIERS = {
|
|
411
427
|
m: 1,
|
|
@@ -488,6 +504,7 @@ var LineHarness = class {
|
|
|
488
504
|
forms;
|
|
489
505
|
adPlatforms;
|
|
490
506
|
staff;
|
|
507
|
+
images;
|
|
491
508
|
apiUrl;
|
|
492
509
|
defaultAccountId;
|
|
493
510
|
workflows;
|
|
@@ -514,6 +531,7 @@ var LineHarness = class {
|
|
|
514
531
|
this.forms = new FormsResource(http);
|
|
515
532
|
this.adPlatforms = new AdPlatformsResource(http);
|
|
516
533
|
this.staff = new StaffResource(http);
|
|
534
|
+
this.images = new ImagesResource(http);
|
|
517
535
|
this.workflows = new Workflows(this.friends, this.scenarios, this.broadcasts);
|
|
518
536
|
this.createStepScenario = this.workflows.createStepScenario.bind(this.workflows);
|
|
519
537
|
this.broadcastText = this.workflows.broadcastText.bind(this.workflows);
|
|
@@ -542,6 +560,7 @@ var LineHarness = class {
|
|
|
542
560
|
BroadcastsResource,
|
|
543
561
|
FormsResource,
|
|
544
562
|
FriendsResource,
|
|
563
|
+
ImagesResource,
|
|
545
564
|
LineHarness,
|
|
546
565
|
LineHarnessError,
|
|
547
566
|
RichMenusResource,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/resources/friends.ts","../src/resources/tags.ts","../src/resources/scenarios.ts","../src/resources/broadcasts.ts","../src/resources/rich-menus.ts","../src/resources/tracked-links.ts","../src/resources/forms.ts","../src/resources/ad-platforms.ts","../src/resources/staff.ts","../src/delay.ts","../src/workflows.ts","../src/client.ts"],"sourcesContent":["export { LineHarness } from './client.js'\nexport { LineHarnessError } from './errors.js'\nexport { parseDelay } from './delay.js'\n\n// Resource classes (for advanced usage / type narrowing)\nexport { FriendsResource } from './resources/friends.js'\nexport { TagsResource } from './resources/tags.js'\nexport { ScenariosResource } from './resources/scenarios.js'\nexport { BroadcastsResource } from './resources/broadcasts.js'\nexport { RichMenusResource } from './resources/rich-menus.js'\nexport { TrackedLinksResource } from './resources/tracked-links.js'\nexport { FormsResource } from './resources/forms.js'\nexport { AdPlatformsResource } from './resources/ad-platforms.js'\nexport { StaffResource } from './resources/staff.js'\n\n// All types\nexport type {\n LineHarnessConfig,\n ApiResponse,\n PaginatedData,\n ScenarioTriggerType,\n MessageType,\n BroadcastStatus,\n Friend,\n FriendListParams,\n Tag,\n CreateTagInput,\n Scenario,\n ScenarioListItem,\n ScenarioWithSteps,\n ScenarioStep,\n CreateScenarioInput,\n CreateStepInput,\n UpdateScenarioInput,\n UpdateStepInput,\n FriendScenarioEnrollment,\n Broadcast,\n CreateBroadcastInput,\n UpdateBroadcastInput,\n SegmentRule,\n SegmentCondition,\n StepDefinition,\n RichMenu,\n RichMenuBounds,\n RichMenuAction,\n RichMenuArea,\n CreateRichMenuInput,\n TrackedLink,\n LinkClick,\n TrackedLinkWithClicks,\n CreateTrackedLinkInput,\n FormField,\n Form,\n CreateFormInput,\n UpdateFormInput,\n FormSubmission,\n StaffRole,\n StaffMember,\n StaffProfile,\n CreateStaffInput,\n UpdateStaffInput,\n} from './types.js'\n\nexport type {\n AdPlatform,\n AdConversionLog,\n CreateAdPlatformInput,\n UpdateAdPlatformInput,\n} from './resources/ad-platforms.js'\n","export class LineHarnessError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly endpoint: string,\n ) {\n super(message)\n this.name = 'LineHarnessError'\n }\n}\n","import { LineHarnessError } from './errors.js'\n\ninterface HttpClientConfig {\n baseUrl: string\n apiKey: string\n timeout: number\n}\n\nexport class HttpClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n private readonly timeout: number\n\n constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '')\n this.apiKey = config.apiKey\n this.timeout = config.timeout\n }\n\n async get<T = unknown>(path: string): Promise<T> {\n return this.request<T>('GET', path)\n }\n\n async post<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('POST', path, body)\n }\n\n async put<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PUT', path, body)\n }\n\n async patch<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PATCH', path, body)\n }\n\n async delete<T = unknown>(path: string): Promise<T> {\n return this.request<T>('DELETE', path)\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n }\n\n const options: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeout),\n }\n\n if (body !== undefined) {\n options.body = JSON.stringify(body)\n }\n\n const res = await fetch(url, options)\n\n if (!res.ok) {\n let errorMessage = `HTTP ${res.status}`\n try {\n const errorBody = (await res.json()) as { error?: string }\n if (errorBody.error) errorMessage = errorBody.error\n } catch {\n // ignore parse errors\n }\n throw new LineHarnessError(errorMessage, res.status, `${method} ${path}`)\n }\n\n return res.json() as Promise<T>\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, PaginatedData, Friend, FriendListParams, MessageType } from '../types.js'\n\nexport class FriendsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: FriendListParams): Promise<PaginatedData<Friend>> {\n const query = new URLSearchParams()\n if (params?.limit !== undefined) query.set('limit', String(params.limit))\n if (params?.offset !== undefined) query.set('offset', String(params.offset))\n if (params?.tagId) query.set('tagId', params.tagId)\n const accountId = params?.accountId ?? this.defaultAccountId\n if (accountId) query.set('lineAccountId', accountId)\n const qs = query.toString()\n const path = qs ? `/api/friends?${qs}` : '/api/friends'\n const res = await this.http.get<ApiResponse<PaginatedData<Friend>>>(path)\n return res.data\n }\n\n async get(id: string): Promise<Friend> {\n const res = await this.http.get<ApiResponse<Friend>>(`/api/friends/${id}`)\n return res.data\n }\n\n async count(): Promise<number> {\n const res = await this.http.get<ApiResponse<{ count: number }>>('/api/friends/count')\n return res.data.count\n }\n\n async addTag(friendId: string, tagId: string): Promise<void> {\n await this.http.post(`/api/friends/${friendId}/tags`, { tagId })\n }\n\n async removeTag(friendId: string, tagId: string): Promise<void> {\n await this.http.delete(`/api/friends/${friendId}/tags/${tagId}`)\n }\n\n async sendMessage(friendId: string, content: string, messageType: MessageType = 'text', altText?: string): Promise<{ messageId: string }> {\n const res = await this.http.post<ApiResponse<{ messageId: string }>>(`/api/friends/${friendId}/messages`, {\n messageType,\n content,\n ...(altText ? { altText } : {}),\n })\n return res.data\n }\n\n async setMetadata(friendId: string, fields: Record<string, unknown>): Promise<Friend> {\n const res = await this.http.put<ApiResponse<Friend>>(`/api/friends/${friendId}/metadata`, fields)\n return res.data\n }\n\n async setRichMenu(friendId: string, richMenuId: string): Promise<void> {\n await this.http.post(`/api/friends/${friendId}/rich-menu`, { richMenuId })\n }\n\n async removeRichMenu(friendId: string): Promise<void> {\n await this.http.delete(`/api/friends/${friendId}/rich-menu`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, Tag, CreateTagInput } from '../types.js'\n\nexport class TagsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Tag[]> {\n const res = await this.http.get<ApiResponse<Tag[]>>('/api/tags')\n return res.data\n }\n\n async create(input: CreateTagInput): Promise<Tag> {\n const res = await this.http.post<ApiResponse<Tag>>('/api/tags', input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/tags/${id}`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type {\n ApiResponse,\n Scenario,\n ScenarioListItem,\n ScenarioWithSteps,\n ScenarioStep,\n CreateScenarioInput,\n CreateStepInput,\n UpdateScenarioInput,\n UpdateStepInput,\n FriendScenarioEnrollment,\n} from '../types.js'\n\nexport class ScenariosResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: { accountId?: string }): Promise<ScenarioListItem[]> {\n const accountId = params?.accountId ?? this.defaultAccountId\n const query = accountId ? `?lineAccountId=${accountId}` : ''\n const res = await this.http.get<ApiResponse<ScenarioListItem[]>>(`/api/scenarios${query}`)\n return res.data\n }\n\n async get(id: string): Promise<ScenarioWithSteps> {\n const res = await this.http.get<ApiResponse<ScenarioWithSteps>>(`/api/scenarios/${id}`)\n return res.data\n }\n\n async create(input: CreateScenarioInput & { lineAccountId?: string }): Promise<Scenario> {\n const body = { ...input }\n if (!body.lineAccountId && this.defaultAccountId) {\n body.lineAccountId = this.defaultAccountId\n }\n const res = await this.http.post<ApiResponse<Scenario>>('/api/scenarios', body)\n return res.data\n }\n\n async update(id: string, input: UpdateScenarioInput): Promise<Scenario> {\n const res = await this.http.put<ApiResponse<Scenario>>(`/api/scenarios/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/scenarios/${id}`)\n }\n\n async addStep(scenarioId: string, input: CreateStepInput): Promise<ScenarioStep> {\n const res = await this.http.post<ApiResponse<ScenarioStep>>(`/api/scenarios/${scenarioId}/steps`, input)\n return res.data\n }\n\n async updateStep(scenarioId: string, stepId: string, input: UpdateStepInput): Promise<ScenarioStep> {\n const res = await this.http.put<ApiResponse<ScenarioStep>>(`/api/scenarios/${scenarioId}/steps/${stepId}`, input)\n return res.data\n }\n\n async deleteStep(scenarioId: string, stepId: string): Promise<void> {\n await this.http.delete(`/api/scenarios/${scenarioId}/steps/${stepId}`)\n }\n\n async enroll(scenarioId: string, friendId: string): Promise<FriendScenarioEnrollment> {\n const res = await this.http.post<ApiResponse<FriendScenarioEnrollment>>(\n `/api/scenarios/${scenarioId}/enroll/${friendId}`\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, Broadcast, CreateBroadcastInput, UpdateBroadcastInput, SegmentCondition } from '../types.js'\n\nexport class BroadcastsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: { accountId?: string }): Promise<Broadcast[]> {\n const accountId = params?.accountId ?? this.defaultAccountId\n const query = accountId ? `?lineAccountId=${accountId}` : ''\n const res = await this.http.get<ApiResponse<Broadcast[]>>(`/api/broadcasts${query}`)\n return res.data\n }\n\n async get(id: string): Promise<Broadcast> {\n const res = await this.http.get<ApiResponse<Broadcast>>(`/api/broadcasts/${id}`)\n return res.data\n }\n\n async create(input: CreateBroadcastInput & { lineAccountId?: string }): Promise<Broadcast> {\n const body = { ...input }\n if (!body.lineAccountId && this.defaultAccountId) {\n body.lineAccountId = this.defaultAccountId\n }\n const res = await this.http.post<ApiResponse<Broadcast>>('/api/broadcasts', body)\n return res.data\n }\n\n async update(id: string, input: UpdateBroadcastInput): Promise<Broadcast> {\n const res = await this.http.put<ApiResponse<Broadcast>>(`/api/broadcasts/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/broadcasts/${id}`)\n }\n\n async send(id: string): Promise<Broadcast> {\n const res = await this.http.post<ApiResponse<Broadcast>>(`/api/broadcasts/${id}/send`)\n return res.data\n }\n\n async sendToSegment(id: string, conditions: SegmentCondition): Promise<Broadcast> {\n const res = await this.http.post<ApiResponse<Broadcast>>(\n `/api/broadcasts/${id}/send-segment`,\n { conditions },\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, RichMenu, CreateRichMenuInput } from '../types.js'\n\nexport class RichMenusResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<RichMenu[]> {\n const res = await this.http.get<ApiResponse<RichMenu[]>>('/api/rich-menus')\n return res.data\n }\n\n async create(menu: CreateRichMenuInput): Promise<{ richMenuId: string }> {\n const res = await this.http.post<ApiResponse<{ richMenuId: string }>>('/api/rich-menus', menu)\n return res.data\n }\n\n async delete(richMenuId: string): Promise<void> {\n await this.http.delete(`/api/rich-menus/${encodeURIComponent(richMenuId)}`)\n }\n\n async setDefault(richMenuId: string): Promise<void> {\n await this.http.post(`/api/rich-menus/${encodeURIComponent(richMenuId)}/default`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, TrackedLink, TrackedLinkWithClicks, CreateTrackedLinkInput } from '../types.js'\n\nexport class TrackedLinksResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<TrackedLink[]> {\n const res = await this.http.get<ApiResponse<TrackedLink[]>>('/api/tracked-links')\n return res.data\n }\n\n async create(input: CreateTrackedLinkInput): Promise<TrackedLink> {\n const res = await this.http.post<ApiResponse<TrackedLink>>('/api/tracked-links', input)\n return res.data\n }\n\n async get(id: string): Promise<TrackedLinkWithClicks> {\n const res = await this.http.get<ApiResponse<TrackedLinkWithClicks>>(`/api/tracked-links/${id}`)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/tracked-links/${id}`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type {\n ApiResponse,\n Form,\n FormSubmission,\n CreateFormInput,\n UpdateFormInput,\n} from '../types.js'\n\nexport class FormsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Form[]> {\n const res = await this.http.get<ApiResponse<Form[]>>('/api/forms')\n return res.data\n }\n\n async get(id: string): Promise<Form> {\n const res = await this.http.get<ApiResponse<Form>>(`/api/forms/${id}`)\n return res.data\n }\n\n async create(input: CreateFormInput): Promise<Form> {\n const res = await this.http.post<ApiResponse<Form>>('/api/forms', input)\n return res.data\n }\n\n async update(id: string, input: UpdateFormInput): Promise<Form> {\n const res = await this.http.put<ApiResponse<Form>>(`/api/forms/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/forms/${id}`)\n }\n\n async getSubmissions(formId: string): Promise<FormSubmission[]> {\n const res = await this.http.get<ApiResponse<FormSubmission[]>>(\n `/api/forms/${formId}/submissions`,\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse } from '../types.js'\n\nexport interface AdPlatform {\n id: string\n name: string\n displayName: string | null\n config: Record<string, unknown>\n isActive: boolean\n createdAt: string\n updatedAt: string\n}\n\nexport interface AdConversionLog {\n id: string\n adPlatformId: string\n friendId: string\n eventName: string\n clickId: string | null\n clickIdType: string | null\n status: string\n errorMessage: string | null\n createdAt: string\n}\n\nexport interface CreateAdPlatformInput {\n name: 'meta' | 'x' | 'google' | 'tiktok'\n displayName?: string\n config: Record<string, unknown>\n}\n\nexport interface UpdateAdPlatformInput {\n name?: string\n displayName?: string | null\n config?: Record<string, unknown>\n isActive?: boolean\n}\n\nexport class AdPlatformsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<AdPlatform[]> {\n const res = await this.http.get<ApiResponse<AdPlatform[]>>('/api/ad-platforms')\n return res.data\n }\n\n async create(input: CreateAdPlatformInput): Promise<AdPlatform> {\n const res = await this.http.post<ApiResponse<AdPlatform>>('/api/ad-platforms', input)\n return res.data\n }\n\n async update(id: string, input: UpdateAdPlatformInput): Promise<AdPlatform> {\n const res = await this.http.put<ApiResponse<AdPlatform>>(`/api/ad-platforms/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/ad-platforms/${id}`)\n }\n\n async getLogs(id: string, limit?: number): Promise<AdConversionLog[]> {\n const path = limit\n ? `/api/ad-platforms/${id}/logs?limit=${limit}`\n : `/api/ad-platforms/${id}/logs`\n const res = await this.http.get<ApiResponse<AdConversionLog[]>>(path)\n return res.data\n }\n\n async test(platform: string, eventName: string, friendId?: string): Promise<{ message: string }> {\n const res = await this.http.post<ApiResponse<{ message: string }>>('/api/ad-platforms/test', {\n platform,\n eventName,\n friendId,\n })\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, StaffMember, StaffProfile, CreateStaffInput, UpdateStaffInput } from '../types.js'\n\nexport class StaffResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<StaffMember[]> {\n const res = await this.http.get<ApiResponse<StaffMember[]>>('/api/staff')\n return res.data\n }\n\n async get(id: string): Promise<StaffMember> {\n const res = await this.http.get<ApiResponse<StaffMember>>(`/api/staff/${id}`)\n return res.data\n }\n\n async me(): Promise<StaffProfile> {\n const res = await this.http.get<ApiResponse<StaffProfile>>('/api/staff/me')\n return res.data\n }\n\n async create(input: CreateStaffInput): Promise<StaffMember> {\n const res = await this.http.post<ApiResponse<StaffMember>>('/api/staff', input)\n return res.data\n }\n\n async update(id: string, input: UpdateStaffInput): Promise<StaffMember> {\n const res = await this.http.patch<ApiResponse<StaffMember>>(`/api/staff/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/staff/${id}`)\n }\n\n async regenerateKey(id: string): Promise<{ apiKey: string }> {\n const res = await this.http.post<ApiResponse<{ apiKey: string }>>(`/api/staff/${id}/regenerate-key`)\n return res.data\n }\n}\n","const MULTIPLIERS: Record<string, number> = {\n m: 1,\n h: 60,\n d: 1440,\n w: 10080,\n}\n\nexport function parseDelay(input: string): number {\n const match = input.match(/^(\\d+)([mhdw])$/)\n if (!match) {\n throw new Error(`Invalid delay format: \"${input}\". Use format like \"30m\", \"1h\", \"1d\", \"1w\".`)\n }\n return Number(match[1]) * MULTIPLIERS[match[2]]\n}\n","import type { FriendsResource } from './resources/friends.js'\nimport type { ScenariosResource } from './resources/scenarios.js'\nimport type { BroadcastsResource } from './resources/broadcasts.js'\nimport type { StepDefinition, ScenarioTriggerType, ScenarioWithSteps, Broadcast, MessageType, SegmentCondition } from './types.js'\nimport { parseDelay } from './delay.js'\n\nexport class Workflows {\n constructor(\n private readonly friends: FriendsResource,\n private readonly scenarios: ScenariosResource,\n private readonly broadcasts: BroadcastsResource,\n ) {}\n\n async createStepScenario(\n name: string,\n triggerType: ScenarioTriggerType,\n steps: StepDefinition[],\n ): Promise<ScenarioWithSteps> {\n const scenario = await this.scenarios.create({ name, triggerType })\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n await this.scenarios.addStep(scenario.id, {\n stepOrder: i + 1,\n delayMinutes: parseDelay(step.delay),\n messageType: step.type,\n messageContent: step.content,\n })\n }\n\n return this.scenarios.get(scenario.id)\n }\n\n async broadcastText(text: string): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: text.slice(0, 50),\n messageType: 'text',\n messageContent: text,\n targetType: 'all',\n })\n return this.broadcasts.send(broadcast.id)\n }\n\n async broadcastToTag(\n tagId: string,\n messageType: MessageType,\n content: string,\n ): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: content.slice(0, 50),\n messageType,\n messageContent: content,\n targetType: 'tag',\n targetTagId: tagId,\n })\n return this.broadcasts.send(broadcast.id)\n }\n\n async broadcastToSegment(\n messageType: MessageType,\n content: string,\n conditions: SegmentCondition,\n ): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: content.slice(0, 50),\n messageType,\n messageContent: content,\n targetType: 'all',\n })\n return this.broadcasts.sendToSegment(broadcast.id, conditions)\n }\n\n async sendTextToFriend(friendId: string, text: string): Promise<{ messageId: string }> {\n return this.friends.sendMessage(friendId, text, 'text')\n }\n\n async sendFlexToFriend(friendId: string, flexJson: string): Promise<{ messageId: string }> {\n return this.friends.sendMessage(friendId, flexJson, 'flex')\n }\n}\n","import { HttpClient } from './http.js'\nimport { FriendsResource } from './resources/friends.js'\nimport { TagsResource } from './resources/tags.js'\nimport { ScenariosResource } from './resources/scenarios.js'\nimport { BroadcastsResource } from './resources/broadcasts.js'\nimport { RichMenusResource } from './resources/rich-menus.js'\nimport { TrackedLinksResource } from './resources/tracked-links.js'\nimport { FormsResource } from './resources/forms.js'\nimport { AdPlatformsResource } from './resources/ad-platforms.js'\nimport { StaffResource } from './resources/staff.js'\nimport { Workflows } from './workflows.js'\nimport type { LineHarnessConfig, StepDefinition, ScenarioTriggerType, ScenarioWithSteps, Broadcast, MessageType, SegmentCondition } from './types.js'\n\nexport class LineHarness {\n readonly friends: FriendsResource\n readonly tags: TagsResource\n readonly scenarios: ScenariosResource\n readonly broadcasts: BroadcastsResource\n readonly richMenus: RichMenusResource\n readonly trackedLinks: TrackedLinksResource\n readonly forms: FormsResource\n readonly adPlatforms: AdPlatformsResource\n readonly staff: StaffResource\n\n private readonly apiUrl: string\n private readonly defaultAccountId: string | undefined\n private readonly workflows: Workflows\n\n readonly createStepScenario: (name: string, triggerType: ScenarioTriggerType, steps: StepDefinition[]) => Promise<ScenarioWithSteps>\n readonly broadcastText: (text: string) => Promise<Broadcast>\n readonly broadcastToTag: (tagId: string, messageType: MessageType, content: string) => Promise<Broadcast>\n readonly broadcastToSegment: (messageType: MessageType, content: string, conditions: SegmentCondition) => Promise<Broadcast>\n readonly sendTextToFriend: (friendId: string, text: string) => Promise<{ messageId: string }>\n readonly sendFlexToFriend: (friendId: string, flexJson: string) => Promise<{ messageId: string }>\n\n constructor(config: LineHarnessConfig) {\n this.apiUrl = config.apiUrl.replace(/\\/$/, '')\n this.defaultAccountId = config.lineAccountId\n\n const http = new HttpClient({\n baseUrl: this.apiUrl,\n apiKey: config.apiKey,\n timeout: config.timeout ?? 30_000,\n })\n\n this.friends = new FriendsResource(http, this.defaultAccountId)\n this.tags = new TagsResource(http)\n this.scenarios = new ScenariosResource(http, this.defaultAccountId)\n this.broadcasts = new BroadcastsResource(http, this.defaultAccountId)\n this.richMenus = new RichMenusResource(http)\n this.trackedLinks = new TrackedLinksResource(http)\n this.forms = new FormsResource(http)\n this.adPlatforms = new AdPlatformsResource(http)\n this.staff = new StaffResource(http)\n this.workflows = new Workflows(this.friends, this.scenarios, this.broadcasts)\n\n this.createStepScenario = this.workflows.createStepScenario.bind(this.workflows)\n this.broadcastText = this.workflows.broadcastText.bind(this.workflows)\n this.broadcastToTag = this.workflows.broadcastToTag.bind(this.workflows)\n this.broadcastToSegment = this.workflows.broadcastToSegment.bind(this.workflows)\n this.sendTextToFriend = this.workflows.sendTextToFriend.bind(this.workflows)\n this.sendFlexToFriend = this.workflows.sendFlexToFriend.bind(this.workflows)\n }\n\n /**\n * Generate friend-add URL with OAuth (bot_prompt=aggressive)\n * This URL does friend-add + UUID in one step.\n *\n * @param ref - Attribution code (e.g., 'lp-a', 'instagram', 'seminar-0322')\n * @param redirect - URL to redirect after completion\n */\n getAuthUrl(options?: { ref?: string; redirect?: string }): string {\n const url = new URL(`${this.apiUrl}/auth/line`)\n if (options?.ref) url.searchParams.set('ref', options.ref)\n if (options?.redirect) url.searchParams.set('redirect', options.redirect)\n return url.toString()\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/resources/friends.ts","../src/resources/tags.ts","../src/resources/scenarios.ts","../src/resources/broadcasts.ts","../src/resources/rich-menus.ts","../src/resources/tracked-links.ts","../src/resources/forms.ts","../src/resources/ad-platforms.ts","../src/resources/staff.ts","../src/resources/images.ts","../src/delay.ts","../src/workflows.ts","../src/client.ts"],"sourcesContent":["export { LineHarness } from './client.js'\nexport { LineHarnessError } from './errors.js'\nexport { parseDelay } from './delay.js'\n\n// Resource classes (for advanced usage / type narrowing)\nexport { FriendsResource } from './resources/friends.js'\nexport { TagsResource } from './resources/tags.js'\nexport { ScenariosResource } from './resources/scenarios.js'\nexport { BroadcastsResource } from './resources/broadcasts.js'\nexport { RichMenusResource } from './resources/rich-menus.js'\nexport { TrackedLinksResource } from './resources/tracked-links.js'\nexport { FormsResource } from './resources/forms.js'\nexport { AdPlatformsResource } from './resources/ad-platforms.js'\nexport { StaffResource } from './resources/staff.js'\nexport { ImagesResource } from './resources/images.js'\n\n// All types\nexport type {\n LineHarnessConfig,\n ApiResponse,\n PaginatedData,\n ScenarioTriggerType,\n MessageType,\n BroadcastStatus,\n Friend,\n FriendListParams,\n Tag,\n CreateTagInput,\n Scenario,\n ScenarioListItem,\n ScenarioWithSteps,\n ScenarioStep,\n CreateScenarioInput,\n CreateStepInput,\n UpdateScenarioInput,\n UpdateStepInput,\n FriendScenarioEnrollment,\n Broadcast,\n CreateBroadcastInput,\n UpdateBroadcastInput,\n SegmentRule,\n SegmentCondition,\n StepDefinition,\n RichMenu,\n RichMenuBounds,\n RichMenuAction,\n RichMenuArea,\n CreateRichMenuInput,\n TrackedLink,\n LinkClick,\n TrackedLinkWithClicks,\n CreateTrackedLinkInput,\n FormField,\n Form,\n CreateFormInput,\n UpdateFormInput,\n FormSubmission,\n StaffRole,\n StaffMember,\n StaffProfile,\n CreateStaffInput,\n UpdateStaffInput,\n UploadedImage,\n UploadImageInput,\n} from './types.js'\n\nexport type {\n AdPlatform,\n AdConversionLog,\n CreateAdPlatformInput,\n UpdateAdPlatformInput,\n} from './resources/ad-platforms.js'\n","export class LineHarnessError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly endpoint: string,\n ) {\n super(message)\n this.name = 'LineHarnessError'\n }\n}\n","import { LineHarnessError } from './errors.js'\n\ninterface HttpClientConfig {\n baseUrl: string\n apiKey: string\n timeout: number\n}\n\nexport class HttpClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n private readonly timeout: number\n\n constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '')\n this.apiKey = config.apiKey\n this.timeout = config.timeout\n }\n\n async get<T = unknown>(path: string): Promise<T> {\n return this.request<T>('GET', path)\n }\n\n async post<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('POST', path, body)\n }\n\n async put<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PUT', path, body)\n }\n\n async patch<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PATCH', path, body)\n }\n\n async delete<T = unknown>(path: string): Promise<T> {\n return this.request<T>('DELETE', path)\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n }\n\n const options: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeout),\n }\n\n if (body !== undefined) {\n options.body = JSON.stringify(body)\n }\n\n const res = await fetch(url, options)\n\n if (!res.ok) {\n let errorMessage = `HTTP ${res.status}`\n try {\n const errorBody = (await res.json()) as { error?: string }\n if (errorBody.error) errorMessage = errorBody.error\n } catch {\n // ignore parse errors\n }\n throw new LineHarnessError(errorMessage, res.status, `${method} ${path}`)\n }\n\n return res.json() as Promise<T>\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, PaginatedData, Friend, FriendListParams, MessageType } from '../types.js'\n\nexport class FriendsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: FriendListParams): Promise<PaginatedData<Friend>> {\n const query = new URLSearchParams()\n if (params?.limit !== undefined) query.set('limit', String(params.limit))\n if (params?.offset !== undefined) query.set('offset', String(params.offset))\n if (params?.tagId) query.set('tagId', params.tagId)\n if (params?.search) query.set('search', params.search)\n const accountId = params?.accountId ?? this.defaultAccountId\n if (accountId) query.set('lineAccountId', accountId)\n const qs = query.toString()\n const path = qs ? `/api/friends?${qs}` : '/api/friends'\n const res = await this.http.get<ApiResponse<PaginatedData<Friend>>>(path)\n return res.data\n }\n\n async get(id: string): Promise<Friend> {\n const res = await this.http.get<ApiResponse<Friend>>(`/api/friends/${id}`)\n return res.data\n }\n\n async count(): Promise<number> {\n const res = await this.http.get<ApiResponse<{ count: number }>>('/api/friends/count')\n return res.data.count\n }\n\n async addTag(friendId: string, tagId: string): Promise<void> {\n await this.http.post(`/api/friends/${friendId}/tags`, { tagId })\n }\n\n async removeTag(friendId: string, tagId: string): Promise<void> {\n await this.http.delete(`/api/friends/${friendId}/tags/${tagId}`)\n }\n\n async sendMessage(friendId: string, content: string, messageType: MessageType = 'text', altText?: string): Promise<{ messageId: string }> {\n const res = await this.http.post<ApiResponse<{ messageId: string }>>(`/api/friends/${friendId}/messages`, {\n messageType,\n content,\n ...(altText ? { altText } : {}),\n })\n return res.data\n }\n\n async setMetadata(friendId: string, fields: Record<string, unknown>): Promise<Friend> {\n const res = await this.http.put<ApiResponse<Friend>>(`/api/friends/${friendId}/metadata`, fields)\n return res.data\n }\n\n async setRichMenu(friendId: string, richMenuId: string): Promise<void> {\n await this.http.post(`/api/friends/${friendId}/rich-menu`, { richMenuId })\n }\n\n async removeRichMenu(friendId: string): Promise<void> {\n await this.http.delete(`/api/friends/${friendId}/rich-menu`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, Tag, CreateTagInput } from '../types.js'\n\nexport class TagsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Tag[]> {\n const res = await this.http.get<ApiResponse<Tag[]>>('/api/tags')\n return res.data\n }\n\n async create(input: CreateTagInput): Promise<Tag> {\n const res = await this.http.post<ApiResponse<Tag>>('/api/tags', input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/tags/${id}`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type {\n ApiResponse,\n Scenario,\n ScenarioListItem,\n ScenarioWithSteps,\n ScenarioStep,\n CreateScenarioInput,\n CreateStepInput,\n UpdateScenarioInput,\n UpdateStepInput,\n FriendScenarioEnrollment,\n} from '../types.js'\n\nexport class ScenariosResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: { accountId?: string }): Promise<ScenarioListItem[]> {\n const accountId = params?.accountId ?? this.defaultAccountId\n const query = accountId ? `?lineAccountId=${accountId}` : ''\n const res = await this.http.get<ApiResponse<ScenarioListItem[]>>(`/api/scenarios${query}`)\n return res.data\n }\n\n async get(id: string): Promise<ScenarioWithSteps> {\n const res = await this.http.get<ApiResponse<ScenarioWithSteps>>(`/api/scenarios/${id}`)\n return res.data\n }\n\n async create(input: CreateScenarioInput & { lineAccountId?: string }): Promise<Scenario> {\n const body = { ...input }\n if (!body.lineAccountId && this.defaultAccountId) {\n body.lineAccountId = this.defaultAccountId\n }\n const res = await this.http.post<ApiResponse<Scenario>>('/api/scenarios', body)\n return res.data\n }\n\n async update(id: string, input: UpdateScenarioInput): Promise<Scenario> {\n const res = await this.http.put<ApiResponse<Scenario>>(`/api/scenarios/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/scenarios/${id}`)\n }\n\n async addStep(scenarioId: string, input: CreateStepInput): Promise<ScenarioStep> {\n const res = await this.http.post<ApiResponse<ScenarioStep>>(`/api/scenarios/${scenarioId}/steps`, input)\n return res.data\n }\n\n async updateStep(scenarioId: string, stepId: string, input: UpdateStepInput): Promise<ScenarioStep> {\n const res = await this.http.put<ApiResponse<ScenarioStep>>(`/api/scenarios/${scenarioId}/steps/${stepId}`, input)\n return res.data\n }\n\n async deleteStep(scenarioId: string, stepId: string): Promise<void> {\n await this.http.delete(`/api/scenarios/${scenarioId}/steps/${stepId}`)\n }\n\n async enroll(scenarioId: string, friendId: string): Promise<FriendScenarioEnrollment> {\n const res = await this.http.post<ApiResponse<FriendScenarioEnrollment>>(\n `/api/scenarios/${scenarioId}/enroll/${friendId}`\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, Broadcast, CreateBroadcastInput, UpdateBroadcastInput, SegmentCondition } from '../types.js'\n\nexport class BroadcastsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: { accountId?: string }): Promise<Broadcast[]> {\n const accountId = params?.accountId ?? this.defaultAccountId\n const query = accountId ? `?lineAccountId=${accountId}` : ''\n const res = await this.http.get<ApiResponse<Broadcast[]>>(`/api/broadcasts${query}`)\n return res.data\n }\n\n async get(id: string): Promise<Broadcast> {\n const res = await this.http.get<ApiResponse<Broadcast>>(`/api/broadcasts/${id}`)\n return res.data\n }\n\n async create(input: CreateBroadcastInput & { lineAccountId?: string }): Promise<Broadcast> {\n const body = { ...input }\n if (!body.lineAccountId && this.defaultAccountId) {\n body.lineAccountId = this.defaultAccountId\n }\n const res = await this.http.post<ApiResponse<Broadcast>>('/api/broadcasts', body)\n return res.data\n }\n\n async update(id: string, input: UpdateBroadcastInput): Promise<Broadcast> {\n const res = await this.http.put<ApiResponse<Broadcast>>(`/api/broadcasts/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/broadcasts/${id}`)\n }\n\n async send(id: string): Promise<Broadcast> {\n const res = await this.http.post<ApiResponse<Broadcast>>(`/api/broadcasts/${id}/send`)\n return res.data\n }\n\n async sendToSegment(id: string, conditions: SegmentCondition): Promise<Broadcast> {\n const res = await this.http.post<ApiResponse<Broadcast>>(\n `/api/broadcasts/${id}/send-segment`,\n { conditions },\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, RichMenu, CreateRichMenuInput } from '../types.js'\n\nexport class RichMenusResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<RichMenu[]> {\n const res = await this.http.get<ApiResponse<RichMenu[]>>('/api/rich-menus')\n return res.data\n }\n\n async create(menu: CreateRichMenuInput): Promise<{ richMenuId: string }> {\n const res = await this.http.post<ApiResponse<{ richMenuId: string }>>('/api/rich-menus', menu)\n return res.data\n }\n\n async delete(richMenuId: string): Promise<void> {\n await this.http.delete(`/api/rich-menus/${encodeURIComponent(richMenuId)}`)\n }\n\n async setDefault(richMenuId: string): Promise<void> {\n await this.http.post(`/api/rich-menus/${encodeURIComponent(richMenuId)}/default`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, TrackedLink, TrackedLinkWithClicks, CreateTrackedLinkInput } from '../types.js'\n\nexport class TrackedLinksResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<TrackedLink[]> {\n const res = await this.http.get<ApiResponse<TrackedLink[]>>('/api/tracked-links')\n return res.data\n }\n\n async create(input: CreateTrackedLinkInput): Promise<TrackedLink> {\n const res = await this.http.post<ApiResponse<TrackedLink>>('/api/tracked-links', input)\n return res.data\n }\n\n async get(id: string): Promise<TrackedLinkWithClicks> {\n const res = await this.http.get<ApiResponse<TrackedLinkWithClicks>>(`/api/tracked-links/${id}`)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/tracked-links/${id}`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type {\n ApiResponse,\n Form,\n FormSubmission,\n CreateFormInput,\n UpdateFormInput,\n} from '../types.js'\n\nexport class FormsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Form[]> {\n const res = await this.http.get<ApiResponse<Form[]>>('/api/forms')\n return res.data\n }\n\n async get(id: string): Promise<Form> {\n const res = await this.http.get<ApiResponse<Form>>(`/api/forms/${id}`)\n return res.data\n }\n\n async create(input: CreateFormInput): Promise<Form> {\n const res = await this.http.post<ApiResponse<Form>>('/api/forms', input)\n return res.data\n }\n\n async update(id: string, input: UpdateFormInput): Promise<Form> {\n const res = await this.http.put<ApiResponse<Form>>(`/api/forms/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/forms/${id}`)\n }\n\n async getSubmissions(formId: string): Promise<FormSubmission[]> {\n const res = await this.http.get<ApiResponse<FormSubmission[]>>(\n `/api/forms/${formId}/submissions`,\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse } from '../types.js'\n\nexport interface AdPlatform {\n id: string\n name: string\n displayName: string | null\n config: Record<string, unknown>\n isActive: boolean\n createdAt: string\n updatedAt: string\n}\n\nexport interface AdConversionLog {\n id: string\n adPlatformId: string\n friendId: string\n eventName: string\n clickId: string | null\n clickIdType: string | null\n status: string\n errorMessage: string | null\n createdAt: string\n}\n\nexport interface CreateAdPlatformInput {\n name: 'meta' | 'x' | 'google' | 'tiktok'\n displayName?: string\n config: Record<string, unknown>\n}\n\nexport interface UpdateAdPlatformInput {\n name?: string\n displayName?: string | null\n config?: Record<string, unknown>\n isActive?: boolean\n}\n\nexport class AdPlatformsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<AdPlatform[]> {\n const res = await this.http.get<ApiResponse<AdPlatform[]>>('/api/ad-platforms')\n return res.data\n }\n\n async create(input: CreateAdPlatformInput): Promise<AdPlatform> {\n const res = await this.http.post<ApiResponse<AdPlatform>>('/api/ad-platforms', input)\n return res.data\n }\n\n async update(id: string, input: UpdateAdPlatformInput): Promise<AdPlatform> {\n const res = await this.http.put<ApiResponse<AdPlatform>>(`/api/ad-platforms/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/ad-platforms/${id}`)\n }\n\n async getLogs(id: string, limit?: number): Promise<AdConversionLog[]> {\n const path = limit\n ? `/api/ad-platforms/${id}/logs?limit=${limit}`\n : `/api/ad-platforms/${id}/logs`\n const res = await this.http.get<ApiResponse<AdConversionLog[]>>(path)\n return res.data\n }\n\n async test(platform: string, eventName: string, friendId?: string): Promise<{ message: string }> {\n const res = await this.http.post<ApiResponse<{ message: string }>>('/api/ad-platforms/test', {\n platform,\n eventName,\n friendId,\n })\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, StaffMember, StaffProfile, CreateStaffInput, UpdateStaffInput } from '../types.js'\n\nexport class StaffResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<StaffMember[]> {\n const res = await this.http.get<ApiResponse<StaffMember[]>>('/api/staff')\n return res.data\n }\n\n async get(id: string): Promise<StaffMember> {\n const res = await this.http.get<ApiResponse<StaffMember>>(`/api/staff/${id}`)\n return res.data\n }\n\n async me(): Promise<StaffProfile> {\n const res = await this.http.get<ApiResponse<StaffProfile>>('/api/staff/me')\n return res.data\n }\n\n async create(input: CreateStaffInput): Promise<StaffMember> {\n const res = await this.http.post<ApiResponse<StaffMember>>('/api/staff', input)\n return res.data\n }\n\n async update(id: string, input: UpdateStaffInput): Promise<StaffMember> {\n const res = await this.http.patch<ApiResponse<StaffMember>>(`/api/staff/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/staff/${id}`)\n }\n\n async regenerateKey(id: string): Promise<{ apiKey: string }> {\n const res = await this.http.post<ApiResponse<{ apiKey: string }>>(`/api/staff/${id}/regenerate-key`)\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, UploadedImage, UploadImageInput } from '../types.js'\n\nexport class ImagesResource {\n constructor(private readonly http: HttpClient) {}\n\n async upload(input: UploadImageInput): Promise<UploadedImage> {\n const res = await this.http.post<ApiResponse<UploadedImage>>('/api/images', input)\n return res.data\n }\n\n async delete(key: string): Promise<void> {\n await this.http.delete(`/api/images/${key}`)\n }\n}\n","const MULTIPLIERS: Record<string, number> = {\n m: 1,\n h: 60,\n d: 1440,\n w: 10080,\n}\n\nexport function parseDelay(input: string): number {\n const match = input.match(/^(\\d+)([mhdw])$/)\n if (!match) {\n throw new Error(`Invalid delay format: \"${input}\". Use format like \"30m\", \"1h\", \"1d\", \"1w\".`)\n }\n return Number(match[1]) * MULTIPLIERS[match[2]]\n}\n","import type { FriendsResource } from './resources/friends.js'\nimport type { ScenariosResource } from './resources/scenarios.js'\nimport type { BroadcastsResource } from './resources/broadcasts.js'\nimport type { StepDefinition, ScenarioTriggerType, ScenarioWithSteps, Broadcast, MessageType, SegmentCondition } from './types.js'\nimport { parseDelay } from './delay.js'\n\nexport class Workflows {\n constructor(\n private readonly friends: FriendsResource,\n private readonly scenarios: ScenariosResource,\n private readonly broadcasts: BroadcastsResource,\n ) {}\n\n async createStepScenario(\n name: string,\n triggerType: ScenarioTriggerType,\n steps: StepDefinition[],\n ): Promise<ScenarioWithSteps> {\n const scenario = await this.scenarios.create({ name, triggerType })\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n await this.scenarios.addStep(scenario.id, {\n stepOrder: i + 1,\n delayMinutes: parseDelay(step.delay),\n messageType: step.type,\n messageContent: step.content,\n })\n }\n\n return this.scenarios.get(scenario.id)\n }\n\n async broadcastText(text: string): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: text.slice(0, 50),\n messageType: 'text',\n messageContent: text,\n targetType: 'all',\n })\n return this.broadcasts.send(broadcast.id)\n }\n\n async broadcastToTag(\n tagId: string,\n messageType: MessageType,\n content: string,\n ): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: content.slice(0, 50),\n messageType,\n messageContent: content,\n targetType: 'tag',\n targetTagId: tagId,\n })\n return this.broadcasts.send(broadcast.id)\n }\n\n async broadcastToSegment(\n messageType: MessageType,\n content: string,\n conditions: SegmentCondition,\n ): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: content.slice(0, 50),\n messageType,\n messageContent: content,\n targetType: 'all',\n })\n return this.broadcasts.sendToSegment(broadcast.id, conditions)\n }\n\n async sendTextToFriend(friendId: string, text: string): Promise<{ messageId: string }> {\n return this.friends.sendMessage(friendId, text, 'text')\n }\n\n async sendFlexToFriend(friendId: string, flexJson: string): Promise<{ messageId: string }> {\n return this.friends.sendMessage(friendId, flexJson, 'flex')\n }\n}\n","import { HttpClient } from './http.js'\nimport { FriendsResource } from './resources/friends.js'\nimport { TagsResource } from './resources/tags.js'\nimport { ScenariosResource } from './resources/scenarios.js'\nimport { BroadcastsResource } from './resources/broadcasts.js'\nimport { RichMenusResource } from './resources/rich-menus.js'\nimport { TrackedLinksResource } from './resources/tracked-links.js'\nimport { FormsResource } from './resources/forms.js'\nimport { AdPlatformsResource } from './resources/ad-platforms.js'\nimport { StaffResource } from './resources/staff.js'\nimport { ImagesResource } from './resources/images.js'\nimport { Workflows } from './workflows.js'\nimport type { LineHarnessConfig, StepDefinition, ScenarioTriggerType, ScenarioWithSteps, Broadcast, MessageType, SegmentCondition } from './types.js'\n\nexport class LineHarness {\n readonly friends: FriendsResource\n readonly tags: TagsResource\n readonly scenarios: ScenariosResource\n readonly broadcasts: BroadcastsResource\n readonly richMenus: RichMenusResource\n readonly trackedLinks: TrackedLinksResource\n readonly forms: FormsResource\n readonly adPlatforms: AdPlatformsResource\n readonly staff: StaffResource\n readonly images: ImagesResource\n\n private readonly apiUrl: string\n private readonly defaultAccountId: string | undefined\n private readonly workflows: Workflows\n\n readonly createStepScenario: (name: string, triggerType: ScenarioTriggerType, steps: StepDefinition[]) => Promise<ScenarioWithSteps>\n readonly broadcastText: (text: string) => Promise<Broadcast>\n readonly broadcastToTag: (tagId: string, messageType: MessageType, content: string) => Promise<Broadcast>\n readonly broadcastToSegment: (messageType: MessageType, content: string, conditions: SegmentCondition) => Promise<Broadcast>\n readonly sendTextToFriend: (friendId: string, text: string) => Promise<{ messageId: string }>\n readonly sendFlexToFriend: (friendId: string, flexJson: string) => Promise<{ messageId: string }>\n\n constructor(config: LineHarnessConfig) {\n this.apiUrl = config.apiUrl.replace(/\\/$/, '')\n this.defaultAccountId = config.lineAccountId\n\n const http = new HttpClient({\n baseUrl: this.apiUrl,\n apiKey: config.apiKey,\n timeout: config.timeout ?? 30_000,\n })\n\n this.friends = new FriendsResource(http, this.defaultAccountId)\n this.tags = new TagsResource(http)\n this.scenarios = new ScenariosResource(http, this.defaultAccountId)\n this.broadcasts = new BroadcastsResource(http, this.defaultAccountId)\n this.richMenus = new RichMenusResource(http)\n this.trackedLinks = new TrackedLinksResource(http)\n this.forms = new FormsResource(http)\n this.adPlatforms = new AdPlatformsResource(http)\n this.staff = new StaffResource(http)\n this.images = new ImagesResource(http)\n this.workflows = new Workflows(this.friends, this.scenarios, this.broadcasts)\n\n this.createStepScenario = this.workflows.createStepScenario.bind(this.workflows)\n this.broadcastText = this.workflows.broadcastText.bind(this.workflows)\n this.broadcastToTag = this.workflows.broadcastToTag.bind(this.workflows)\n this.broadcastToSegment = this.workflows.broadcastToSegment.bind(this.workflows)\n this.sendTextToFriend = this.workflows.sendTextToFriend.bind(this.workflows)\n this.sendFlexToFriend = this.workflows.sendFlexToFriend.bind(this.workflows)\n }\n\n /**\n * Generate friend-add URL with OAuth (bot_prompt=aggressive)\n * This URL does friend-add + UUID in one step.\n *\n * @param ref - Attribution code (e.g., 'lp-a', 'instagram', 'seminar-0322')\n * @param redirect - URL to redirect after completion\n */\n getAuthUrl(options?: { ref?: string; redirect?: string }): string {\n const url = new URL(`${this.apiUrl}/auth/line`)\n if (options?.ref) url.searchParams.set('ref', options.ref)\n if (options?.redirect) url.searchParams.set('redirect', options.redirect)\n return url.toString()\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -53,6 +53,7 @@ interface FriendListParams {
|
|
|
53
53
|
limit?: number;
|
|
54
54
|
offset?: number;
|
|
55
55
|
tagId?: string;
|
|
56
|
+
search?: string;
|
|
56
57
|
accountId?: string;
|
|
57
58
|
}
|
|
58
59
|
interface Tag {
|
|
@@ -340,6 +341,21 @@ interface StepDefinition {
|
|
|
340
341
|
type: MessageType;
|
|
341
342
|
content: string;
|
|
342
343
|
}
|
|
344
|
+
interface UploadedImage {
|
|
345
|
+
id: string;
|
|
346
|
+
key: string;
|
|
347
|
+
url: string;
|
|
348
|
+
mimeType: string;
|
|
349
|
+
size: number;
|
|
350
|
+
}
|
|
351
|
+
interface UploadImageInput {
|
|
352
|
+
/** Base64-encoded image data (with or without data URI prefix) */
|
|
353
|
+
data: string;
|
|
354
|
+
/** MIME type, e.g. "image/png". Defaults to "image/png" */
|
|
355
|
+
mimeType?: string;
|
|
356
|
+
/** Optional original filename */
|
|
357
|
+
filename?: string;
|
|
358
|
+
}
|
|
343
359
|
|
|
344
360
|
declare class FriendsResource {
|
|
345
361
|
private readonly http;
|
|
@@ -491,6 +507,13 @@ declare class StaffResource {
|
|
|
491
507
|
}>;
|
|
492
508
|
}
|
|
493
509
|
|
|
510
|
+
declare class ImagesResource {
|
|
511
|
+
private readonly http;
|
|
512
|
+
constructor(http: HttpClient);
|
|
513
|
+
upload(input: UploadImageInput): Promise<UploadedImage>;
|
|
514
|
+
delete(key: string): Promise<void>;
|
|
515
|
+
}
|
|
516
|
+
|
|
494
517
|
declare class LineHarness {
|
|
495
518
|
readonly friends: FriendsResource;
|
|
496
519
|
readonly tags: TagsResource;
|
|
@@ -501,6 +524,7 @@ declare class LineHarness {
|
|
|
501
524
|
readonly forms: FormsResource;
|
|
502
525
|
readonly adPlatforms: AdPlatformsResource;
|
|
503
526
|
readonly staff: StaffResource;
|
|
527
|
+
readonly images: ImagesResource;
|
|
504
528
|
private readonly apiUrl;
|
|
505
529
|
private readonly defaultAccountId;
|
|
506
530
|
private readonly workflows;
|
|
@@ -536,4 +560,4 @@ declare class LineHarnessError extends Error {
|
|
|
536
560
|
|
|
537
561
|
declare function parseDelay(input: string): number;
|
|
538
562
|
|
|
539
|
-
export { type AdConversionLog, type AdPlatform, AdPlatformsResource, type ApiResponse, type Broadcast, type BroadcastStatus, BroadcastsResource, type CreateAdPlatformInput, type CreateBroadcastInput, type CreateFormInput, type CreateRichMenuInput, type CreateScenarioInput, type CreateStaffInput, type CreateStepInput, type CreateTagInput, type CreateTrackedLinkInput, type Form, type FormField, type FormSubmission, FormsResource, type Friend, type FriendListParams, type FriendScenarioEnrollment, FriendsResource, LineHarness, type LineHarnessConfig, LineHarnessError, type LinkClick, type MessageType, type PaginatedData, type RichMenu, type RichMenuAction, type RichMenuArea, type RichMenuBounds, RichMenusResource, type Scenario, type ScenarioListItem, type ScenarioStep, type ScenarioTriggerType, type ScenarioWithSteps, ScenariosResource, type SegmentCondition, type SegmentRule, type StaffMember, type StaffProfile, StaffResource, type StaffRole, type StepDefinition, type Tag, TagsResource, type TrackedLink, type TrackedLinkWithClicks, TrackedLinksResource, type UpdateAdPlatformInput, type UpdateBroadcastInput, type UpdateFormInput, type UpdateScenarioInput, type UpdateStaffInput, type UpdateStepInput, parseDelay };
|
|
563
|
+
export { type AdConversionLog, type AdPlatform, AdPlatformsResource, type ApiResponse, type Broadcast, type BroadcastStatus, BroadcastsResource, type CreateAdPlatformInput, type CreateBroadcastInput, type CreateFormInput, type CreateRichMenuInput, type CreateScenarioInput, type CreateStaffInput, type CreateStepInput, type CreateTagInput, type CreateTrackedLinkInput, type Form, type FormField, type FormSubmission, FormsResource, type Friend, type FriendListParams, type FriendScenarioEnrollment, FriendsResource, ImagesResource, LineHarness, type LineHarnessConfig, LineHarnessError, type LinkClick, type MessageType, type PaginatedData, type RichMenu, type RichMenuAction, type RichMenuArea, type RichMenuBounds, RichMenusResource, type Scenario, type ScenarioListItem, type ScenarioStep, type ScenarioTriggerType, type ScenarioWithSteps, ScenariosResource, type SegmentCondition, type SegmentRule, type StaffMember, type StaffProfile, StaffResource, type StaffRole, type StepDefinition, type Tag, TagsResource, type TrackedLink, type TrackedLinkWithClicks, TrackedLinksResource, type UpdateAdPlatformInput, type UpdateBroadcastInput, type UpdateFormInput, type UpdateScenarioInput, type UpdateStaffInput, type UpdateStepInput, type UploadImageInput, type UploadedImage, parseDelay };
|
package/dist/index.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ interface FriendListParams {
|
|
|
53
53
|
limit?: number;
|
|
54
54
|
offset?: number;
|
|
55
55
|
tagId?: string;
|
|
56
|
+
search?: string;
|
|
56
57
|
accountId?: string;
|
|
57
58
|
}
|
|
58
59
|
interface Tag {
|
|
@@ -340,6 +341,21 @@ interface StepDefinition {
|
|
|
340
341
|
type: MessageType;
|
|
341
342
|
content: string;
|
|
342
343
|
}
|
|
344
|
+
interface UploadedImage {
|
|
345
|
+
id: string;
|
|
346
|
+
key: string;
|
|
347
|
+
url: string;
|
|
348
|
+
mimeType: string;
|
|
349
|
+
size: number;
|
|
350
|
+
}
|
|
351
|
+
interface UploadImageInput {
|
|
352
|
+
/** Base64-encoded image data (with or without data URI prefix) */
|
|
353
|
+
data: string;
|
|
354
|
+
/** MIME type, e.g. "image/png". Defaults to "image/png" */
|
|
355
|
+
mimeType?: string;
|
|
356
|
+
/** Optional original filename */
|
|
357
|
+
filename?: string;
|
|
358
|
+
}
|
|
343
359
|
|
|
344
360
|
declare class FriendsResource {
|
|
345
361
|
private readonly http;
|
|
@@ -491,6 +507,13 @@ declare class StaffResource {
|
|
|
491
507
|
}>;
|
|
492
508
|
}
|
|
493
509
|
|
|
510
|
+
declare class ImagesResource {
|
|
511
|
+
private readonly http;
|
|
512
|
+
constructor(http: HttpClient);
|
|
513
|
+
upload(input: UploadImageInput): Promise<UploadedImage>;
|
|
514
|
+
delete(key: string): Promise<void>;
|
|
515
|
+
}
|
|
516
|
+
|
|
494
517
|
declare class LineHarness {
|
|
495
518
|
readonly friends: FriendsResource;
|
|
496
519
|
readonly tags: TagsResource;
|
|
@@ -501,6 +524,7 @@ declare class LineHarness {
|
|
|
501
524
|
readonly forms: FormsResource;
|
|
502
525
|
readonly adPlatforms: AdPlatformsResource;
|
|
503
526
|
readonly staff: StaffResource;
|
|
527
|
+
readonly images: ImagesResource;
|
|
504
528
|
private readonly apiUrl;
|
|
505
529
|
private readonly defaultAccountId;
|
|
506
530
|
private readonly workflows;
|
|
@@ -536,4 +560,4 @@ declare class LineHarnessError extends Error {
|
|
|
536
560
|
|
|
537
561
|
declare function parseDelay(input: string): number;
|
|
538
562
|
|
|
539
|
-
export { type AdConversionLog, type AdPlatform, AdPlatformsResource, type ApiResponse, type Broadcast, type BroadcastStatus, BroadcastsResource, type CreateAdPlatformInput, type CreateBroadcastInput, type CreateFormInput, type CreateRichMenuInput, type CreateScenarioInput, type CreateStaffInput, type CreateStepInput, type CreateTagInput, type CreateTrackedLinkInput, type Form, type FormField, type FormSubmission, FormsResource, type Friend, type FriendListParams, type FriendScenarioEnrollment, FriendsResource, LineHarness, type LineHarnessConfig, LineHarnessError, type LinkClick, type MessageType, type PaginatedData, type RichMenu, type RichMenuAction, type RichMenuArea, type RichMenuBounds, RichMenusResource, type Scenario, type ScenarioListItem, type ScenarioStep, type ScenarioTriggerType, type ScenarioWithSteps, ScenariosResource, type SegmentCondition, type SegmentRule, type StaffMember, type StaffProfile, StaffResource, type StaffRole, type StepDefinition, type Tag, TagsResource, type TrackedLink, type TrackedLinkWithClicks, TrackedLinksResource, type UpdateAdPlatformInput, type UpdateBroadcastInput, type UpdateFormInput, type UpdateScenarioInput, type UpdateStaffInput, type UpdateStepInput, parseDelay };
|
|
563
|
+
export { type AdConversionLog, type AdPlatform, AdPlatformsResource, type ApiResponse, type Broadcast, type BroadcastStatus, BroadcastsResource, type CreateAdPlatformInput, type CreateBroadcastInput, type CreateFormInput, type CreateRichMenuInput, type CreateScenarioInput, type CreateStaffInput, type CreateStepInput, type CreateTagInput, type CreateTrackedLinkInput, type Form, type FormField, type FormSubmission, FormsResource, type Friend, type FriendListParams, type FriendScenarioEnrollment, FriendsResource, ImagesResource, LineHarness, type LineHarnessConfig, LineHarnessError, type LinkClick, type MessageType, type PaginatedData, type RichMenu, type RichMenuAction, type RichMenuArea, type RichMenuBounds, RichMenusResource, type Scenario, type ScenarioListItem, type ScenarioStep, type ScenarioTriggerType, type ScenarioWithSteps, ScenariosResource, type SegmentCondition, type SegmentRule, type StaffMember, type StaffProfile, StaffResource, type StaffRole, type StepDefinition, type Tag, TagsResource, type TrackedLink, type TrackedLinkWithClicks, TrackedLinksResource, type UpdateAdPlatformInput, type UpdateBroadcastInput, type UpdateFormInput, type UpdateScenarioInput, type UpdateStaffInput, type UpdateStepInput, type UploadImageInput, type UploadedImage, parseDelay };
|
package/dist/index.mjs
CHANGED
|
@@ -72,6 +72,7 @@ var FriendsResource = class {
|
|
|
72
72
|
if (params?.limit !== void 0) query.set("limit", String(params.limit));
|
|
73
73
|
if (params?.offset !== void 0) query.set("offset", String(params.offset));
|
|
74
74
|
if (params?.tagId) query.set("tagId", params.tagId);
|
|
75
|
+
if (params?.search) query.set("search", params.search);
|
|
75
76
|
const accountId = params?.accountId ?? this.defaultAccountId;
|
|
76
77
|
if (accountId) query.set("lineAccountId", accountId);
|
|
77
78
|
const qs = query.toString();
|
|
@@ -369,6 +370,20 @@ var StaffResource = class {
|
|
|
369
370
|
}
|
|
370
371
|
};
|
|
371
372
|
|
|
373
|
+
// src/resources/images.ts
|
|
374
|
+
var ImagesResource = class {
|
|
375
|
+
constructor(http) {
|
|
376
|
+
this.http = http;
|
|
377
|
+
}
|
|
378
|
+
async upload(input) {
|
|
379
|
+
const res = await this.http.post("/api/images", input);
|
|
380
|
+
return res.data;
|
|
381
|
+
}
|
|
382
|
+
async delete(key) {
|
|
383
|
+
await this.http.delete(`/api/images/${key}`);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
|
|
372
387
|
// src/delay.ts
|
|
373
388
|
var MULTIPLIERS = {
|
|
374
389
|
m: 1,
|
|
@@ -451,6 +466,7 @@ var LineHarness = class {
|
|
|
451
466
|
forms;
|
|
452
467
|
adPlatforms;
|
|
453
468
|
staff;
|
|
469
|
+
images;
|
|
454
470
|
apiUrl;
|
|
455
471
|
defaultAccountId;
|
|
456
472
|
workflows;
|
|
@@ -477,6 +493,7 @@ var LineHarness = class {
|
|
|
477
493
|
this.forms = new FormsResource(http);
|
|
478
494
|
this.adPlatforms = new AdPlatformsResource(http);
|
|
479
495
|
this.staff = new StaffResource(http);
|
|
496
|
+
this.images = new ImagesResource(http);
|
|
480
497
|
this.workflows = new Workflows(this.friends, this.scenarios, this.broadcasts);
|
|
481
498
|
this.createStepScenario = this.workflows.createStepScenario.bind(this.workflows);
|
|
482
499
|
this.broadcastText = this.workflows.broadcastText.bind(this.workflows);
|
|
@@ -504,6 +521,7 @@ export {
|
|
|
504
521
|
BroadcastsResource,
|
|
505
522
|
FormsResource,
|
|
506
523
|
FriendsResource,
|
|
524
|
+
ImagesResource,
|
|
507
525
|
LineHarness,
|
|
508
526
|
LineHarnessError,
|
|
509
527
|
RichMenusResource,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/friends.ts","../src/resources/tags.ts","../src/resources/scenarios.ts","../src/resources/broadcasts.ts","../src/resources/rich-menus.ts","../src/resources/tracked-links.ts","../src/resources/forms.ts","../src/resources/ad-platforms.ts","../src/resources/staff.ts","../src/delay.ts","../src/workflows.ts","../src/client.ts"],"sourcesContent":["export class LineHarnessError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly endpoint: string,\n ) {\n super(message)\n this.name = 'LineHarnessError'\n }\n}\n","import { LineHarnessError } from './errors.js'\n\ninterface HttpClientConfig {\n baseUrl: string\n apiKey: string\n timeout: number\n}\n\nexport class HttpClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n private readonly timeout: number\n\n constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '')\n this.apiKey = config.apiKey\n this.timeout = config.timeout\n }\n\n async get<T = unknown>(path: string): Promise<T> {\n return this.request<T>('GET', path)\n }\n\n async post<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('POST', path, body)\n }\n\n async put<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PUT', path, body)\n }\n\n async patch<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PATCH', path, body)\n }\n\n async delete<T = unknown>(path: string): Promise<T> {\n return this.request<T>('DELETE', path)\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n }\n\n const options: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeout),\n }\n\n if (body !== undefined) {\n options.body = JSON.stringify(body)\n }\n\n const res = await fetch(url, options)\n\n if (!res.ok) {\n let errorMessage = `HTTP ${res.status}`\n try {\n const errorBody = (await res.json()) as { error?: string }\n if (errorBody.error) errorMessage = errorBody.error\n } catch {\n // ignore parse errors\n }\n throw new LineHarnessError(errorMessage, res.status, `${method} ${path}`)\n }\n\n return res.json() as Promise<T>\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, PaginatedData, Friend, FriendListParams, MessageType } from '../types.js'\n\nexport class FriendsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: FriendListParams): Promise<PaginatedData<Friend>> {\n const query = new URLSearchParams()\n if (params?.limit !== undefined) query.set('limit', String(params.limit))\n if (params?.offset !== undefined) query.set('offset', String(params.offset))\n if (params?.tagId) query.set('tagId', params.tagId)\n const accountId = params?.accountId ?? this.defaultAccountId\n if (accountId) query.set('lineAccountId', accountId)\n const qs = query.toString()\n const path = qs ? `/api/friends?${qs}` : '/api/friends'\n const res = await this.http.get<ApiResponse<PaginatedData<Friend>>>(path)\n return res.data\n }\n\n async get(id: string): Promise<Friend> {\n const res = await this.http.get<ApiResponse<Friend>>(`/api/friends/${id}`)\n return res.data\n }\n\n async count(): Promise<number> {\n const res = await this.http.get<ApiResponse<{ count: number }>>('/api/friends/count')\n return res.data.count\n }\n\n async addTag(friendId: string, tagId: string): Promise<void> {\n await this.http.post(`/api/friends/${friendId}/tags`, { tagId })\n }\n\n async removeTag(friendId: string, tagId: string): Promise<void> {\n await this.http.delete(`/api/friends/${friendId}/tags/${tagId}`)\n }\n\n async sendMessage(friendId: string, content: string, messageType: MessageType = 'text', altText?: string): Promise<{ messageId: string }> {\n const res = await this.http.post<ApiResponse<{ messageId: string }>>(`/api/friends/${friendId}/messages`, {\n messageType,\n content,\n ...(altText ? { altText } : {}),\n })\n return res.data\n }\n\n async setMetadata(friendId: string, fields: Record<string, unknown>): Promise<Friend> {\n const res = await this.http.put<ApiResponse<Friend>>(`/api/friends/${friendId}/metadata`, fields)\n return res.data\n }\n\n async setRichMenu(friendId: string, richMenuId: string): Promise<void> {\n await this.http.post(`/api/friends/${friendId}/rich-menu`, { richMenuId })\n }\n\n async removeRichMenu(friendId: string): Promise<void> {\n await this.http.delete(`/api/friends/${friendId}/rich-menu`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, Tag, CreateTagInput } from '../types.js'\n\nexport class TagsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Tag[]> {\n const res = await this.http.get<ApiResponse<Tag[]>>('/api/tags')\n return res.data\n }\n\n async create(input: CreateTagInput): Promise<Tag> {\n const res = await this.http.post<ApiResponse<Tag>>('/api/tags', input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/tags/${id}`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type {\n ApiResponse,\n Scenario,\n ScenarioListItem,\n ScenarioWithSteps,\n ScenarioStep,\n CreateScenarioInput,\n CreateStepInput,\n UpdateScenarioInput,\n UpdateStepInput,\n FriendScenarioEnrollment,\n} from '../types.js'\n\nexport class ScenariosResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: { accountId?: string }): Promise<ScenarioListItem[]> {\n const accountId = params?.accountId ?? this.defaultAccountId\n const query = accountId ? `?lineAccountId=${accountId}` : ''\n const res = await this.http.get<ApiResponse<ScenarioListItem[]>>(`/api/scenarios${query}`)\n return res.data\n }\n\n async get(id: string): Promise<ScenarioWithSteps> {\n const res = await this.http.get<ApiResponse<ScenarioWithSteps>>(`/api/scenarios/${id}`)\n return res.data\n }\n\n async create(input: CreateScenarioInput & { lineAccountId?: string }): Promise<Scenario> {\n const body = { ...input }\n if (!body.lineAccountId && this.defaultAccountId) {\n body.lineAccountId = this.defaultAccountId\n }\n const res = await this.http.post<ApiResponse<Scenario>>('/api/scenarios', body)\n return res.data\n }\n\n async update(id: string, input: UpdateScenarioInput): Promise<Scenario> {\n const res = await this.http.put<ApiResponse<Scenario>>(`/api/scenarios/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/scenarios/${id}`)\n }\n\n async addStep(scenarioId: string, input: CreateStepInput): Promise<ScenarioStep> {\n const res = await this.http.post<ApiResponse<ScenarioStep>>(`/api/scenarios/${scenarioId}/steps`, input)\n return res.data\n }\n\n async updateStep(scenarioId: string, stepId: string, input: UpdateStepInput): Promise<ScenarioStep> {\n const res = await this.http.put<ApiResponse<ScenarioStep>>(`/api/scenarios/${scenarioId}/steps/${stepId}`, input)\n return res.data\n }\n\n async deleteStep(scenarioId: string, stepId: string): Promise<void> {\n await this.http.delete(`/api/scenarios/${scenarioId}/steps/${stepId}`)\n }\n\n async enroll(scenarioId: string, friendId: string): Promise<FriendScenarioEnrollment> {\n const res = await this.http.post<ApiResponse<FriendScenarioEnrollment>>(\n `/api/scenarios/${scenarioId}/enroll/${friendId}`\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, Broadcast, CreateBroadcastInput, UpdateBroadcastInput, SegmentCondition } from '../types.js'\n\nexport class BroadcastsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: { accountId?: string }): Promise<Broadcast[]> {\n const accountId = params?.accountId ?? this.defaultAccountId\n const query = accountId ? `?lineAccountId=${accountId}` : ''\n const res = await this.http.get<ApiResponse<Broadcast[]>>(`/api/broadcasts${query}`)\n return res.data\n }\n\n async get(id: string): Promise<Broadcast> {\n const res = await this.http.get<ApiResponse<Broadcast>>(`/api/broadcasts/${id}`)\n return res.data\n }\n\n async create(input: CreateBroadcastInput & { lineAccountId?: string }): Promise<Broadcast> {\n const body = { ...input }\n if (!body.lineAccountId && this.defaultAccountId) {\n body.lineAccountId = this.defaultAccountId\n }\n const res = await this.http.post<ApiResponse<Broadcast>>('/api/broadcasts', body)\n return res.data\n }\n\n async update(id: string, input: UpdateBroadcastInput): Promise<Broadcast> {\n const res = await this.http.put<ApiResponse<Broadcast>>(`/api/broadcasts/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/broadcasts/${id}`)\n }\n\n async send(id: string): Promise<Broadcast> {\n const res = await this.http.post<ApiResponse<Broadcast>>(`/api/broadcasts/${id}/send`)\n return res.data\n }\n\n async sendToSegment(id: string, conditions: SegmentCondition): Promise<Broadcast> {\n const res = await this.http.post<ApiResponse<Broadcast>>(\n `/api/broadcasts/${id}/send-segment`,\n { conditions },\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, RichMenu, CreateRichMenuInput } from '../types.js'\n\nexport class RichMenusResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<RichMenu[]> {\n const res = await this.http.get<ApiResponse<RichMenu[]>>('/api/rich-menus')\n return res.data\n }\n\n async create(menu: CreateRichMenuInput): Promise<{ richMenuId: string }> {\n const res = await this.http.post<ApiResponse<{ richMenuId: string }>>('/api/rich-menus', menu)\n return res.data\n }\n\n async delete(richMenuId: string): Promise<void> {\n await this.http.delete(`/api/rich-menus/${encodeURIComponent(richMenuId)}`)\n }\n\n async setDefault(richMenuId: string): Promise<void> {\n await this.http.post(`/api/rich-menus/${encodeURIComponent(richMenuId)}/default`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, TrackedLink, TrackedLinkWithClicks, CreateTrackedLinkInput } from '../types.js'\n\nexport class TrackedLinksResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<TrackedLink[]> {\n const res = await this.http.get<ApiResponse<TrackedLink[]>>('/api/tracked-links')\n return res.data\n }\n\n async create(input: CreateTrackedLinkInput): Promise<TrackedLink> {\n const res = await this.http.post<ApiResponse<TrackedLink>>('/api/tracked-links', input)\n return res.data\n }\n\n async get(id: string): Promise<TrackedLinkWithClicks> {\n const res = await this.http.get<ApiResponse<TrackedLinkWithClicks>>(`/api/tracked-links/${id}`)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/tracked-links/${id}`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type {\n ApiResponse,\n Form,\n FormSubmission,\n CreateFormInput,\n UpdateFormInput,\n} from '../types.js'\n\nexport class FormsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Form[]> {\n const res = await this.http.get<ApiResponse<Form[]>>('/api/forms')\n return res.data\n }\n\n async get(id: string): Promise<Form> {\n const res = await this.http.get<ApiResponse<Form>>(`/api/forms/${id}`)\n return res.data\n }\n\n async create(input: CreateFormInput): Promise<Form> {\n const res = await this.http.post<ApiResponse<Form>>('/api/forms', input)\n return res.data\n }\n\n async update(id: string, input: UpdateFormInput): Promise<Form> {\n const res = await this.http.put<ApiResponse<Form>>(`/api/forms/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/forms/${id}`)\n }\n\n async getSubmissions(formId: string): Promise<FormSubmission[]> {\n const res = await this.http.get<ApiResponse<FormSubmission[]>>(\n `/api/forms/${formId}/submissions`,\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse } from '../types.js'\n\nexport interface AdPlatform {\n id: string\n name: string\n displayName: string | null\n config: Record<string, unknown>\n isActive: boolean\n createdAt: string\n updatedAt: string\n}\n\nexport interface AdConversionLog {\n id: string\n adPlatformId: string\n friendId: string\n eventName: string\n clickId: string | null\n clickIdType: string | null\n status: string\n errorMessage: string | null\n createdAt: string\n}\n\nexport interface CreateAdPlatformInput {\n name: 'meta' | 'x' | 'google' | 'tiktok'\n displayName?: string\n config: Record<string, unknown>\n}\n\nexport interface UpdateAdPlatformInput {\n name?: string\n displayName?: string | null\n config?: Record<string, unknown>\n isActive?: boolean\n}\n\nexport class AdPlatformsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<AdPlatform[]> {\n const res = await this.http.get<ApiResponse<AdPlatform[]>>('/api/ad-platforms')\n return res.data\n }\n\n async create(input: CreateAdPlatformInput): Promise<AdPlatform> {\n const res = await this.http.post<ApiResponse<AdPlatform>>('/api/ad-platforms', input)\n return res.data\n }\n\n async update(id: string, input: UpdateAdPlatformInput): Promise<AdPlatform> {\n const res = await this.http.put<ApiResponse<AdPlatform>>(`/api/ad-platforms/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/ad-platforms/${id}`)\n }\n\n async getLogs(id: string, limit?: number): Promise<AdConversionLog[]> {\n const path = limit\n ? `/api/ad-platforms/${id}/logs?limit=${limit}`\n : `/api/ad-platforms/${id}/logs`\n const res = await this.http.get<ApiResponse<AdConversionLog[]>>(path)\n return res.data\n }\n\n async test(platform: string, eventName: string, friendId?: string): Promise<{ message: string }> {\n const res = await this.http.post<ApiResponse<{ message: string }>>('/api/ad-platforms/test', {\n platform,\n eventName,\n friendId,\n })\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, StaffMember, StaffProfile, CreateStaffInput, UpdateStaffInput } from '../types.js'\n\nexport class StaffResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<StaffMember[]> {\n const res = await this.http.get<ApiResponse<StaffMember[]>>('/api/staff')\n return res.data\n }\n\n async get(id: string): Promise<StaffMember> {\n const res = await this.http.get<ApiResponse<StaffMember>>(`/api/staff/${id}`)\n return res.data\n }\n\n async me(): Promise<StaffProfile> {\n const res = await this.http.get<ApiResponse<StaffProfile>>('/api/staff/me')\n return res.data\n }\n\n async create(input: CreateStaffInput): Promise<StaffMember> {\n const res = await this.http.post<ApiResponse<StaffMember>>('/api/staff', input)\n return res.data\n }\n\n async update(id: string, input: UpdateStaffInput): Promise<StaffMember> {\n const res = await this.http.patch<ApiResponse<StaffMember>>(`/api/staff/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/staff/${id}`)\n }\n\n async regenerateKey(id: string): Promise<{ apiKey: string }> {\n const res = await this.http.post<ApiResponse<{ apiKey: string }>>(`/api/staff/${id}/regenerate-key`)\n return res.data\n }\n}\n","const MULTIPLIERS: Record<string, number> = {\n m: 1,\n h: 60,\n d: 1440,\n w: 10080,\n}\n\nexport function parseDelay(input: string): number {\n const match = input.match(/^(\\d+)([mhdw])$/)\n if (!match) {\n throw new Error(`Invalid delay format: \"${input}\". Use format like \"30m\", \"1h\", \"1d\", \"1w\".`)\n }\n return Number(match[1]) * MULTIPLIERS[match[2]]\n}\n","import type { FriendsResource } from './resources/friends.js'\nimport type { ScenariosResource } from './resources/scenarios.js'\nimport type { BroadcastsResource } from './resources/broadcasts.js'\nimport type { StepDefinition, ScenarioTriggerType, ScenarioWithSteps, Broadcast, MessageType, SegmentCondition } from './types.js'\nimport { parseDelay } from './delay.js'\n\nexport class Workflows {\n constructor(\n private readonly friends: FriendsResource,\n private readonly scenarios: ScenariosResource,\n private readonly broadcasts: BroadcastsResource,\n ) {}\n\n async createStepScenario(\n name: string,\n triggerType: ScenarioTriggerType,\n steps: StepDefinition[],\n ): Promise<ScenarioWithSteps> {\n const scenario = await this.scenarios.create({ name, triggerType })\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n await this.scenarios.addStep(scenario.id, {\n stepOrder: i + 1,\n delayMinutes: parseDelay(step.delay),\n messageType: step.type,\n messageContent: step.content,\n })\n }\n\n return this.scenarios.get(scenario.id)\n }\n\n async broadcastText(text: string): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: text.slice(0, 50),\n messageType: 'text',\n messageContent: text,\n targetType: 'all',\n })\n return this.broadcasts.send(broadcast.id)\n }\n\n async broadcastToTag(\n tagId: string,\n messageType: MessageType,\n content: string,\n ): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: content.slice(0, 50),\n messageType,\n messageContent: content,\n targetType: 'tag',\n targetTagId: tagId,\n })\n return this.broadcasts.send(broadcast.id)\n }\n\n async broadcastToSegment(\n messageType: MessageType,\n content: string,\n conditions: SegmentCondition,\n ): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: content.slice(0, 50),\n messageType,\n messageContent: content,\n targetType: 'all',\n })\n return this.broadcasts.sendToSegment(broadcast.id, conditions)\n }\n\n async sendTextToFriend(friendId: string, text: string): Promise<{ messageId: string }> {\n return this.friends.sendMessage(friendId, text, 'text')\n }\n\n async sendFlexToFriend(friendId: string, flexJson: string): Promise<{ messageId: string }> {\n return this.friends.sendMessage(friendId, flexJson, 'flex')\n }\n}\n","import { HttpClient } from './http.js'\nimport { FriendsResource } from './resources/friends.js'\nimport { TagsResource } from './resources/tags.js'\nimport { ScenariosResource } from './resources/scenarios.js'\nimport { BroadcastsResource } from './resources/broadcasts.js'\nimport { RichMenusResource } from './resources/rich-menus.js'\nimport { TrackedLinksResource } from './resources/tracked-links.js'\nimport { FormsResource } from './resources/forms.js'\nimport { AdPlatformsResource } from './resources/ad-platforms.js'\nimport { StaffResource } from './resources/staff.js'\nimport { Workflows } from './workflows.js'\nimport type { LineHarnessConfig, StepDefinition, ScenarioTriggerType, ScenarioWithSteps, Broadcast, MessageType, SegmentCondition } from './types.js'\n\nexport class LineHarness {\n readonly friends: FriendsResource\n readonly tags: TagsResource\n readonly scenarios: ScenariosResource\n readonly broadcasts: BroadcastsResource\n readonly richMenus: RichMenusResource\n readonly trackedLinks: TrackedLinksResource\n readonly forms: FormsResource\n readonly adPlatforms: AdPlatformsResource\n readonly staff: StaffResource\n\n private readonly apiUrl: string\n private readonly defaultAccountId: string | undefined\n private readonly workflows: Workflows\n\n readonly createStepScenario: (name: string, triggerType: ScenarioTriggerType, steps: StepDefinition[]) => Promise<ScenarioWithSteps>\n readonly broadcastText: (text: string) => Promise<Broadcast>\n readonly broadcastToTag: (tagId: string, messageType: MessageType, content: string) => Promise<Broadcast>\n readonly broadcastToSegment: (messageType: MessageType, content: string, conditions: SegmentCondition) => Promise<Broadcast>\n readonly sendTextToFriend: (friendId: string, text: string) => Promise<{ messageId: string }>\n readonly sendFlexToFriend: (friendId: string, flexJson: string) => Promise<{ messageId: string }>\n\n constructor(config: LineHarnessConfig) {\n this.apiUrl = config.apiUrl.replace(/\\/$/, '')\n this.defaultAccountId = config.lineAccountId\n\n const http = new HttpClient({\n baseUrl: this.apiUrl,\n apiKey: config.apiKey,\n timeout: config.timeout ?? 30_000,\n })\n\n this.friends = new FriendsResource(http, this.defaultAccountId)\n this.tags = new TagsResource(http)\n this.scenarios = new ScenariosResource(http, this.defaultAccountId)\n this.broadcasts = new BroadcastsResource(http, this.defaultAccountId)\n this.richMenus = new RichMenusResource(http)\n this.trackedLinks = new TrackedLinksResource(http)\n this.forms = new FormsResource(http)\n this.adPlatforms = new AdPlatformsResource(http)\n this.staff = new StaffResource(http)\n this.workflows = new Workflows(this.friends, this.scenarios, this.broadcasts)\n\n this.createStepScenario = this.workflows.createStepScenario.bind(this.workflows)\n this.broadcastText = this.workflows.broadcastText.bind(this.workflows)\n this.broadcastToTag = this.workflows.broadcastToTag.bind(this.workflows)\n this.broadcastToSegment = this.workflows.broadcastToSegment.bind(this.workflows)\n this.sendTextToFriend = this.workflows.sendTextToFriend.bind(this.workflows)\n this.sendFlexToFriend = this.workflows.sendFlexToFriend.bind(this.workflows)\n }\n\n /**\n * Generate friend-add URL with OAuth (bot_prompt=aggressive)\n * This URL does friend-add + UUID in one step.\n *\n * @param ref - Attribution code (e.g., 'lp-a', 'instagram', 'seminar-0322')\n * @param redirect - URL to redirect after completion\n */\n getAuthUrl(options?: { ref?: string; redirect?: string }): string {\n const url = new URL(`${this.apiUrl}/auth/line`)\n if (options?.ref) url.searchParams.set('ref', options.ref)\n if (options?.redirect) url.searchParams.set('redirect', options.redirect)\n return url.toString()\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/friends.ts","../src/resources/tags.ts","../src/resources/scenarios.ts","../src/resources/broadcasts.ts","../src/resources/rich-menus.ts","../src/resources/tracked-links.ts","../src/resources/forms.ts","../src/resources/ad-platforms.ts","../src/resources/staff.ts","../src/resources/images.ts","../src/delay.ts","../src/workflows.ts","../src/client.ts"],"sourcesContent":["export class LineHarnessError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly endpoint: string,\n ) {\n super(message)\n this.name = 'LineHarnessError'\n }\n}\n","import { LineHarnessError } from './errors.js'\n\ninterface HttpClientConfig {\n baseUrl: string\n apiKey: string\n timeout: number\n}\n\nexport class HttpClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n private readonly timeout: number\n\n constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '')\n this.apiKey = config.apiKey\n this.timeout = config.timeout\n }\n\n async get<T = unknown>(path: string): Promise<T> {\n return this.request<T>('GET', path)\n }\n\n async post<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('POST', path, body)\n }\n\n async put<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PUT', path, body)\n }\n\n async patch<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PATCH', path, body)\n }\n\n async delete<T = unknown>(path: string): Promise<T> {\n return this.request<T>('DELETE', path)\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n }\n\n const options: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeout),\n }\n\n if (body !== undefined) {\n options.body = JSON.stringify(body)\n }\n\n const res = await fetch(url, options)\n\n if (!res.ok) {\n let errorMessage = `HTTP ${res.status}`\n try {\n const errorBody = (await res.json()) as { error?: string }\n if (errorBody.error) errorMessage = errorBody.error\n } catch {\n // ignore parse errors\n }\n throw new LineHarnessError(errorMessage, res.status, `${method} ${path}`)\n }\n\n return res.json() as Promise<T>\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, PaginatedData, Friend, FriendListParams, MessageType } from '../types.js'\n\nexport class FriendsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: FriendListParams): Promise<PaginatedData<Friend>> {\n const query = new URLSearchParams()\n if (params?.limit !== undefined) query.set('limit', String(params.limit))\n if (params?.offset !== undefined) query.set('offset', String(params.offset))\n if (params?.tagId) query.set('tagId', params.tagId)\n if (params?.search) query.set('search', params.search)\n const accountId = params?.accountId ?? this.defaultAccountId\n if (accountId) query.set('lineAccountId', accountId)\n const qs = query.toString()\n const path = qs ? `/api/friends?${qs}` : '/api/friends'\n const res = await this.http.get<ApiResponse<PaginatedData<Friend>>>(path)\n return res.data\n }\n\n async get(id: string): Promise<Friend> {\n const res = await this.http.get<ApiResponse<Friend>>(`/api/friends/${id}`)\n return res.data\n }\n\n async count(): Promise<number> {\n const res = await this.http.get<ApiResponse<{ count: number }>>('/api/friends/count')\n return res.data.count\n }\n\n async addTag(friendId: string, tagId: string): Promise<void> {\n await this.http.post(`/api/friends/${friendId}/tags`, { tagId })\n }\n\n async removeTag(friendId: string, tagId: string): Promise<void> {\n await this.http.delete(`/api/friends/${friendId}/tags/${tagId}`)\n }\n\n async sendMessage(friendId: string, content: string, messageType: MessageType = 'text', altText?: string): Promise<{ messageId: string }> {\n const res = await this.http.post<ApiResponse<{ messageId: string }>>(`/api/friends/${friendId}/messages`, {\n messageType,\n content,\n ...(altText ? { altText } : {}),\n })\n return res.data\n }\n\n async setMetadata(friendId: string, fields: Record<string, unknown>): Promise<Friend> {\n const res = await this.http.put<ApiResponse<Friend>>(`/api/friends/${friendId}/metadata`, fields)\n return res.data\n }\n\n async setRichMenu(friendId: string, richMenuId: string): Promise<void> {\n await this.http.post(`/api/friends/${friendId}/rich-menu`, { richMenuId })\n }\n\n async removeRichMenu(friendId: string): Promise<void> {\n await this.http.delete(`/api/friends/${friendId}/rich-menu`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, Tag, CreateTagInput } from '../types.js'\n\nexport class TagsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Tag[]> {\n const res = await this.http.get<ApiResponse<Tag[]>>('/api/tags')\n return res.data\n }\n\n async create(input: CreateTagInput): Promise<Tag> {\n const res = await this.http.post<ApiResponse<Tag>>('/api/tags', input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/tags/${id}`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type {\n ApiResponse,\n Scenario,\n ScenarioListItem,\n ScenarioWithSteps,\n ScenarioStep,\n CreateScenarioInput,\n CreateStepInput,\n UpdateScenarioInput,\n UpdateStepInput,\n FriendScenarioEnrollment,\n} from '../types.js'\n\nexport class ScenariosResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: { accountId?: string }): Promise<ScenarioListItem[]> {\n const accountId = params?.accountId ?? this.defaultAccountId\n const query = accountId ? `?lineAccountId=${accountId}` : ''\n const res = await this.http.get<ApiResponse<ScenarioListItem[]>>(`/api/scenarios${query}`)\n return res.data\n }\n\n async get(id: string): Promise<ScenarioWithSteps> {\n const res = await this.http.get<ApiResponse<ScenarioWithSteps>>(`/api/scenarios/${id}`)\n return res.data\n }\n\n async create(input: CreateScenarioInput & { lineAccountId?: string }): Promise<Scenario> {\n const body = { ...input }\n if (!body.lineAccountId && this.defaultAccountId) {\n body.lineAccountId = this.defaultAccountId\n }\n const res = await this.http.post<ApiResponse<Scenario>>('/api/scenarios', body)\n return res.data\n }\n\n async update(id: string, input: UpdateScenarioInput): Promise<Scenario> {\n const res = await this.http.put<ApiResponse<Scenario>>(`/api/scenarios/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/scenarios/${id}`)\n }\n\n async addStep(scenarioId: string, input: CreateStepInput): Promise<ScenarioStep> {\n const res = await this.http.post<ApiResponse<ScenarioStep>>(`/api/scenarios/${scenarioId}/steps`, input)\n return res.data\n }\n\n async updateStep(scenarioId: string, stepId: string, input: UpdateStepInput): Promise<ScenarioStep> {\n const res = await this.http.put<ApiResponse<ScenarioStep>>(`/api/scenarios/${scenarioId}/steps/${stepId}`, input)\n return res.data\n }\n\n async deleteStep(scenarioId: string, stepId: string): Promise<void> {\n await this.http.delete(`/api/scenarios/${scenarioId}/steps/${stepId}`)\n }\n\n async enroll(scenarioId: string, friendId: string): Promise<FriendScenarioEnrollment> {\n const res = await this.http.post<ApiResponse<FriendScenarioEnrollment>>(\n `/api/scenarios/${scenarioId}/enroll/${friendId}`\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, Broadcast, CreateBroadcastInput, UpdateBroadcastInput, SegmentCondition } from '../types.js'\n\nexport class BroadcastsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly defaultAccountId?: string,\n ) {}\n\n async list(params?: { accountId?: string }): Promise<Broadcast[]> {\n const accountId = params?.accountId ?? this.defaultAccountId\n const query = accountId ? `?lineAccountId=${accountId}` : ''\n const res = await this.http.get<ApiResponse<Broadcast[]>>(`/api/broadcasts${query}`)\n return res.data\n }\n\n async get(id: string): Promise<Broadcast> {\n const res = await this.http.get<ApiResponse<Broadcast>>(`/api/broadcasts/${id}`)\n return res.data\n }\n\n async create(input: CreateBroadcastInput & { lineAccountId?: string }): Promise<Broadcast> {\n const body = { ...input }\n if (!body.lineAccountId && this.defaultAccountId) {\n body.lineAccountId = this.defaultAccountId\n }\n const res = await this.http.post<ApiResponse<Broadcast>>('/api/broadcasts', body)\n return res.data\n }\n\n async update(id: string, input: UpdateBroadcastInput): Promise<Broadcast> {\n const res = await this.http.put<ApiResponse<Broadcast>>(`/api/broadcasts/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/broadcasts/${id}`)\n }\n\n async send(id: string): Promise<Broadcast> {\n const res = await this.http.post<ApiResponse<Broadcast>>(`/api/broadcasts/${id}/send`)\n return res.data\n }\n\n async sendToSegment(id: string, conditions: SegmentCondition): Promise<Broadcast> {\n const res = await this.http.post<ApiResponse<Broadcast>>(\n `/api/broadcasts/${id}/send-segment`,\n { conditions },\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, RichMenu, CreateRichMenuInput } from '../types.js'\n\nexport class RichMenusResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<RichMenu[]> {\n const res = await this.http.get<ApiResponse<RichMenu[]>>('/api/rich-menus')\n return res.data\n }\n\n async create(menu: CreateRichMenuInput): Promise<{ richMenuId: string }> {\n const res = await this.http.post<ApiResponse<{ richMenuId: string }>>('/api/rich-menus', menu)\n return res.data\n }\n\n async delete(richMenuId: string): Promise<void> {\n await this.http.delete(`/api/rich-menus/${encodeURIComponent(richMenuId)}`)\n }\n\n async setDefault(richMenuId: string): Promise<void> {\n await this.http.post(`/api/rich-menus/${encodeURIComponent(richMenuId)}/default`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, TrackedLink, TrackedLinkWithClicks, CreateTrackedLinkInput } from '../types.js'\n\nexport class TrackedLinksResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<TrackedLink[]> {\n const res = await this.http.get<ApiResponse<TrackedLink[]>>('/api/tracked-links')\n return res.data\n }\n\n async create(input: CreateTrackedLinkInput): Promise<TrackedLink> {\n const res = await this.http.post<ApiResponse<TrackedLink>>('/api/tracked-links', input)\n return res.data\n }\n\n async get(id: string): Promise<TrackedLinkWithClicks> {\n const res = await this.http.get<ApiResponse<TrackedLinkWithClicks>>(`/api/tracked-links/${id}`)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/tracked-links/${id}`)\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type {\n ApiResponse,\n Form,\n FormSubmission,\n CreateFormInput,\n UpdateFormInput,\n} from '../types.js'\n\nexport class FormsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Form[]> {\n const res = await this.http.get<ApiResponse<Form[]>>('/api/forms')\n return res.data\n }\n\n async get(id: string): Promise<Form> {\n const res = await this.http.get<ApiResponse<Form>>(`/api/forms/${id}`)\n return res.data\n }\n\n async create(input: CreateFormInput): Promise<Form> {\n const res = await this.http.post<ApiResponse<Form>>('/api/forms', input)\n return res.data\n }\n\n async update(id: string, input: UpdateFormInput): Promise<Form> {\n const res = await this.http.put<ApiResponse<Form>>(`/api/forms/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/forms/${id}`)\n }\n\n async getSubmissions(formId: string): Promise<FormSubmission[]> {\n const res = await this.http.get<ApiResponse<FormSubmission[]>>(\n `/api/forms/${formId}/submissions`,\n )\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse } from '../types.js'\n\nexport interface AdPlatform {\n id: string\n name: string\n displayName: string | null\n config: Record<string, unknown>\n isActive: boolean\n createdAt: string\n updatedAt: string\n}\n\nexport interface AdConversionLog {\n id: string\n adPlatformId: string\n friendId: string\n eventName: string\n clickId: string | null\n clickIdType: string | null\n status: string\n errorMessage: string | null\n createdAt: string\n}\n\nexport interface CreateAdPlatformInput {\n name: 'meta' | 'x' | 'google' | 'tiktok'\n displayName?: string\n config: Record<string, unknown>\n}\n\nexport interface UpdateAdPlatformInput {\n name?: string\n displayName?: string | null\n config?: Record<string, unknown>\n isActive?: boolean\n}\n\nexport class AdPlatformsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<AdPlatform[]> {\n const res = await this.http.get<ApiResponse<AdPlatform[]>>('/api/ad-platforms')\n return res.data\n }\n\n async create(input: CreateAdPlatformInput): Promise<AdPlatform> {\n const res = await this.http.post<ApiResponse<AdPlatform>>('/api/ad-platforms', input)\n return res.data\n }\n\n async update(id: string, input: UpdateAdPlatformInput): Promise<AdPlatform> {\n const res = await this.http.put<ApiResponse<AdPlatform>>(`/api/ad-platforms/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/ad-platforms/${id}`)\n }\n\n async getLogs(id: string, limit?: number): Promise<AdConversionLog[]> {\n const path = limit\n ? `/api/ad-platforms/${id}/logs?limit=${limit}`\n : `/api/ad-platforms/${id}/logs`\n const res = await this.http.get<ApiResponse<AdConversionLog[]>>(path)\n return res.data\n }\n\n async test(platform: string, eventName: string, friendId?: string): Promise<{ message: string }> {\n const res = await this.http.post<ApiResponse<{ message: string }>>('/api/ad-platforms/test', {\n platform,\n eventName,\n friendId,\n })\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, StaffMember, StaffProfile, CreateStaffInput, UpdateStaffInput } from '../types.js'\n\nexport class StaffResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<StaffMember[]> {\n const res = await this.http.get<ApiResponse<StaffMember[]>>('/api/staff')\n return res.data\n }\n\n async get(id: string): Promise<StaffMember> {\n const res = await this.http.get<ApiResponse<StaffMember>>(`/api/staff/${id}`)\n return res.data\n }\n\n async me(): Promise<StaffProfile> {\n const res = await this.http.get<ApiResponse<StaffProfile>>('/api/staff/me')\n return res.data\n }\n\n async create(input: CreateStaffInput): Promise<StaffMember> {\n const res = await this.http.post<ApiResponse<StaffMember>>('/api/staff', input)\n return res.data\n }\n\n async update(id: string, input: UpdateStaffInput): Promise<StaffMember> {\n const res = await this.http.patch<ApiResponse<StaffMember>>(`/api/staff/${id}`, input)\n return res.data\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/api/staff/${id}`)\n }\n\n async regenerateKey(id: string): Promise<{ apiKey: string }> {\n const res = await this.http.post<ApiResponse<{ apiKey: string }>>(`/api/staff/${id}/regenerate-key`)\n return res.data\n }\n}\n","import type { HttpClient } from '../http.js'\nimport type { ApiResponse, UploadedImage, UploadImageInput } from '../types.js'\n\nexport class ImagesResource {\n constructor(private readonly http: HttpClient) {}\n\n async upload(input: UploadImageInput): Promise<UploadedImage> {\n const res = await this.http.post<ApiResponse<UploadedImage>>('/api/images', input)\n return res.data\n }\n\n async delete(key: string): Promise<void> {\n await this.http.delete(`/api/images/${key}`)\n }\n}\n","const MULTIPLIERS: Record<string, number> = {\n m: 1,\n h: 60,\n d: 1440,\n w: 10080,\n}\n\nexport function parseDelay(input: string): number {\n const match = input.match(/^(\\d+)([mhdw])$/)\n if (!match) {\n throw new Error(`Invalid delay format: \"${input}\". Use format like \"30m\", \"1h\", \"1d\", \"1w\".`)\n }\n return Number(match[1]) * MULTIPLIERS[match[2]]\n}\n","import type { FriendsResource } from './resources/friends.js'\nimport type { ScenariosResource } from './resources/scenarios.js'\nimport type { BroadcastsResource } from './resources/broadcasts.js'\nimport type { StepDefinition, ScenarioTriggerType, ScenarioWithSteps, Broadcast, MessageType, SegmentCondition } from './types.js'\nimport { parseDelay } from './delay.js'\n\nexport class Workflows {\n constructor(\n private readonly friends: FriendsResource,\n private readonly scenarios: ScenariosResource,\n private readonly broadcasts: BroadcastsResource,\n ) {}\n\n async createStepScenario(\n name: string,\n triggerType: ScenarioTriggerType,\n steps: StepDefinition[],\n ): Promise<ScenarioWithSteps> {\n const scenario = await this.scenarios.create({ name, triggerType })\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n await this.scenarios.addStep(scenario.id, {\n stepOrder: i + 1,\n delayMinutes: parseDelay(step.delay),\n messageType: step.type,\n messageContent: step.content,\n })\n }\n\n return this.scenarios.get(scenario.id)\n }\n\n async broadcastText(text: string): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: text.slice(0, 50),\n messageType: 'text',\n messageContent: text,\n targetType: 'all',\n })\n return this.broadcasts.send(broadcast.id)\n }\n\n async broadcastToTag(\n tagId: string,\n messageType: MessageType,\n content: string,\n ): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: content.slice(0, 50),\n messageType,\n messageContent: content,\n targetType: 'tag',\n targetTagId: tagId,\n })\n return this.broadcasts.send(broadcast.id)\n }\n\n async broadcastToSegment(\n messageType: MessageType,\n content: string,\n conditions: SegmentCondition,\n ): Promise<Broadcast> {\n const broadcast = await this.broadcasts.create({\n title: content.slice(0, 50),\n messageType,\n messageContent: content,\n targetType: 'all',\n })\n return this.broadcasts.sendToSegment(broadcast.id, conditions)\n }\n\n async sendTextToFriend(friendId: string, text: string): Promise<{ messageId: string }> {\n return this.friends.sendMessage(friendId, text, 'text')\n }\n\n async sendFlexToFriend(friendId: string, flexJson: string): Promise<{ messageId: string }> {\n return this.friends.sendMessage(friendId, flexJson, 'flex')\n }\n}\n","import { HttpClient } from './http.js'\nimport { FriendsResource } from './resources/friends.js'\nimport { TagsResource } from './resources/tags.js'\nimport { ScenariosResource } from './resources/scenarios.js'\nimport { BroadcastsResource } from './resources/broadcasts.js'\nimport { RichMenusResource } from './resources/rich-menus.js'\nimport { TrackedLinksResource } from './resources/tracked-links.js'\nimport { FormsResource } from './resources/forms.js'\nimport { AdPlatformsResource } from './resources/ad-platforms.js'\nimport { StaffResource } from './resources/staff.js'\nimport { ImagesResource } from './resources/images.js'\nimport { Workflows } from './workflows.js'\nimport type { LineHarnessConfig, StepDefinition, ScenarioTriggerType, ScenarioWithSteps, Broadcast, MessageType, SegmentCondition } from './types.js'\n\nexport class LineHarness {\n readonly friends: FriendsResource\n readonly tags: TagsResource\n readonly scenarios: ScenariosResource\n readonly broadcasts: BroadcastsResource\n readonly richMenus: RichMenusResource\n readonly trackedLinks: TrackedLinksResource\n readonly forms: FormsResource\n readonly adPlatforms: AdPlatformsResource\n readonly staff: StaffResource\n readonly images: ImagesResource\n\n private readonly apiUrl: string\n private readonly defaultAccountId: string | undefined\n private readonly workflows: Workflows\n\n readonly createStepScenario: (name: string, triggerType: ScenarioTriggerType, steps: StepDefinition[]) => Promise<ScenarioWithSteps>\n readonly broadcastText: (text: string) => Promise<Broadcast>\n readonly broadcastToTag: (tagId: string, messageType: MessageType, content: string) => Promise<Broadcast>\n readonly broadcastToSegment: (messageType: MessageType, content: string, conditions: SegmentCondition) => Promise<Broadcast>\n readonly sendTextToFriend: (friendId: string, text: string) => Promise<{ messageId: string }>\n readonly sendFlexToFriend: (friendId: string, flexJson: string) => Promise<{ messageId: string }>\n\n constructor(config: LineHarnessConfig) {\n this.apiUrl = config.apiUrl.replace(/\\/$/, '')\n this.defaultAccountId = config.lineAccountId\n\n const http = new HttpClient({\n baseUrl: this.apiUrl,\n apiKey: config.apiKey,\n timeout: config.timeout ?? 30_000,\n })\n\n this.friends = new FriendsResource(http, this.defaultAccountId)\n this.tags = new TagsResource(http)\n this.scenarios = new ScenariosResource(http, this.defaultAccountId)\n this.broadcasts = new BroadcastsResource(http, this.defaultAccountId)\n this.richMenus = new RichMenusResource(http)\n this.trackedLinks = new TrackedLinksResource(http)\n this.forms = new FormsResource(http)\n this.adPlatforms = new AdPlatformsResource(http)\n this.staff = new StaffResource(http)\n this.images = new ImagesResource(http)\n this.workflows = new Workflows(this.friends, this.scenarios, this.broadcasts)\n\n this.createStepScenario = this.workflows.createStepScenario.bind(this.workflows)\n this.broadcastText = this.workflows.broadcastText.bind(this.workflows)\n this.broadcastToTag = this.workflows.broadcastToTag.bind(this.workflows)\n this.broadcastToSegment = this.workflows.broadcastToSegment.bind(this.workflows)\n this.sendTextToFriend = this.workflows.sendTextToFriend.bind(this.workflows)\n this.sendFlexToFriend = this.workflows.sendFlexToFriend.bind(this.workflows)\n }\n\n /**\n * Generate friend-add URL with OAuth (bot_prompt=aggressive)\n * This URL does friend-add + UUID in one step.\n *\n * @param ref - Attribution code (e.g., 'lp-a', 'instagram', 'seminar-0322')\n * @param redirect - URL to redirect after completion\n */\n getAuthUrl(options?: { ref?: string; redirect?: string }): string {\n const url = new URL(`${this.apiUrl}/auth/line`)\n if (options?.ref) url.searchParams.set('ref', options.ref)\n if (options?.redirect) url.searchParams.set('redirect', options.redirect)\n return url.toString()\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@line-harness/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "AI-native SDK for LINE Harness — programmatic LINE official account automation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -13,21 +13,29 @@
|
|
|
13
13
|
"main": "./dist/index.cjs",
|
|
14
14
|
"module": "./dist/index.mjs",
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
|
-
"files": [
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
17
19
|
"publishConfig": {
|
|
18
20
|
"access": "public"
|
|
19
21
|
},
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
"keywords": [
|
|
23
|
+
"line",
|
|
24
|
+
"crm",
|
|
25
|
+
"marketing-automation",
|
|
26
|
+
"sdk",
|
|
27
|
+
"ai"
|
|
28
|
+
],
|
|
27
29
|
"license": "MIT",
|
|
28
30
|
"devDependencies": {
|
|
29
31
|
"tsup": "^8.0.0",
|
|
30
32
|
"typescript": "^5.5.0",
|
|
31
33
|
"vitest": "^2.0.0"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest",
|
|
39
|
+
"typecheck": "tsc --noEmit"
|
|
32
40
|
}
|
|
33
|
-
}
|
|
41
|
+
}
|