agent-messenger 2.15.0 → 2.16.0
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/.claude-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/dist/package.json +1 -1
- package/dist/src/platforms/kakaotalk/attachment-router.d.ts +25 -0
- package/dist/src/platforms/kakaotalk/attachment-router.d.ts.map +1 -0
- package/dist/src/platforms/kakaotalk/attachment-router.js +29 -0
- package/dist/src/platforms/kakaotalk/attachment-router.js.map +1 -0
- package/dist/src/platforms/kakaotalk/client.d.ts +14 -1
- package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/client.js +216 -0
- package/dist/src/platforms/kakaotalk/client.js.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/message.js +49 -0
- package/dist/src/platforms/kakaotalk/commands/message.js.map +1 -1
- package/dist/src/platforms/kakaotalk/image-meta.d.ts +7 -0
- package/dist/src/platforms/kakaotalk/image-meta.d.ts.map +1 -0
- package/dist/src/platforms/kakaotalk/image-meta.js +153 -0
- package/dist/src/platforms/kakaotalk/image-meta.js.map +1 -0
- package/dist/src/platforms/kakaotalk/index.d.ts +6 -2
- package/dist/src/platforms/kakaotalk/index.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/index.js +4 -1
- package/dist/src/platforms/kakaotalk/index.js.map +1 -1
- package/dist/src/platforms/kakaotalk/media-upload.d.ts +3 -0
- package/dist/src/platforms/kakaotalk/media-upload.d.ts.map +1 -0
- package/dist/src/platforms/kakaotalk/media-upload.js +44 -0
- package/dist/src/platforms/kakaotalk/media-upload.js.map +1 -0
- package/dist/src/platforms/kakaotalk/protocol/connection.d.ts +1 -0
- package/dist/src/platforms/kakaotalk/protocol/connection.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/connection.js +11 -0
- package/dist/src/platforms/kakaotalk/protocol/connection.js.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/media-uploader.d.ts +25 -0
- package/dist/src/platforms/kakaotalk/protocol/media-uploader.d.ts.map +1 -0
- package/dist/src/platforms/kakaotalk/protocol/media-uploader.js +99 -0
- package/dist/src/platforms/kakaotalk/protocol/media-uploader.js.map +1 -0
- package/dist/src/platforms/kakaotalk/protocol/session.d.ts +6 -0
- package/dist/src/platforms/kakaotalk/protocol/session.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/session.js +61 -0
- package/dist/src/platforms/kakaotalk/protocol/session.js.map +1 -1
- package/dist/src/platforms/kakaotalk/types.d.ts +44 -0
- package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/types.js +9 -0
- package/dist/src/platforms/kakaotalk/types.js.map +1 -1
- package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/auth.js +6 -2
- package/dist/src/platforms/slack/commands/auth.js.map +1 -1
- package/dist/src/platforms/slack/ensure-auth.d.ts +8 -2
- package/dist/src/platforms/slack/ensure-auth.d.ts.map +1 -1
- package/dist/src/platforms/slack/ensure-auth.js +67 -10
- package/dist/src/platforms/slack/ensure-auth.js.map +1 -1
- package/docs/content/docs/cli/kakaotalk.mdx +47 -2
- package/docs/content/docs/sdk/kakaotalk.mdx +32 -0
- package/package.json +1 -1
- package/skills/agent-channeltalk/SKILL.md +1 -1
- package/skills/agent-channeltalkbot/SKILL.md +1 -1
- package/skills/agent-discord/SKILL.md +1 -1
- package/skills/agent-discordbot/SKILL.md +1 -1
- package/skills/agent-instagram/SKILL.md +1 -1
- package/skills/agent-kakaotalk/SKILL.md +62 -4
- package/skills/agent-kakaotalk/references/common-patterns.md +50 -11
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +1 -1
- package/skills/agent-slackbot/SKILL.md +1 -1
- package/skills/agent-teams/SKILL.md +1 -1
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-telegrambot/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +1 -1
- package/skills/agent-wechatbot/SKILL.md +1 -1
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/platforms/kakaotalk/attachment-router.test.ts +102 -0
- package/src/platforms/kakaotalk/attachment-router.ts +50 -0
- package/src/platforms/kakaotalk/client.ts +315 -8
- package/src/platforms/kakaotalk/commands/message.ts +66 -0
- package/src/platforms/kakaotalk/image-meta.test.ts +90 -0
- package/src/platforms/kakaotalk/image-meta.ts +176 -0
- package/src/platforms/kakaotalk/index.ts +7 -0
- package/src/platforms/kakaotalk/media-upload.ts +44 -0
- package/src/platforms/kakaotalk/protocol/connection.ts +11 -0
- package/src/platforms/kakaotalk/protocol/media-uploader.ts +129 -0
- package/src/platforms/kakaotalk/protocol/session.ts +67 -0
- package/src/platforms/kakaotalk/types.ts +57 -0
- package/src/platforms/slack/commands/auth.ts +6 -4
- package/src/platforms/slack/ensure-auth.test.ts +223 -1
- package/src/platforms/slack/ensure-auth.ts +80 -11
- package/src/platforms/telegrambot/cli.ts +0 -0
|
@@ -21,20 +21,29 @@ export async function ensureSlackAuth(): Promise<void> {
|
|
|
21
21
|
const workspaces = await extractor.extract()
|
|
22
22
|
const workspaceDomains = extractor.getWorkspaceDomains()
|
|
23
23
|
|
|
24
|
-
const validWorkspaces = []
|
|
24
|
+
const validWorkspaces: ExtractedWorkspace[] = []
|
|
25
|
+
const resolvedTeamIds = new Set<string>()
|
|
26
|
+
const refreshCache = new Map<string, RefreshResult | null>()
|
|
27
|
+
|
|
25
28
|
for (const ws of workspaces) {
|
|
26
29
|
try {
|
|
27
30
|
const client = await new SlackClient().login({ token: ws.token, cookie: ws.cookie })
|
|
28
31
|
const authInfo = await client.testAuth()
|
|
32
|
+
if (!authInfo.team_id) throw new Error('testAuth returned empty team_id')
|
|
29
33
|
ws.workspace_id = authInfo.team_id
|
|
30
34
|
ws.workspace_name = authInfo.team || ws.workspace_name
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
if (!resolvedTeamIds.has(ws.workspace_id)) {
|
|
36
|
+
resolvedTeamIds.add(ws.workspace_id)
|
|
37
|
+
await credManager.setWorkspace(ws)
|
|
38
|
+
validWorkspaces.push(ws)
|
|
39
|
+
}
|
|
33
40
|
} catch {
|
|
34
|
-
const refreshed = await tryWebTokenRefresh(ws, workspaceDomains)
|
|
35
|
-
if (refreshed) {
|
|
41
|
+
const refreshed = await tryWebTokenRefresh(ws, workspaceDomains, { resolvedTeamIds, refreshCache })
|
|
42
|
+
if (refreshed && !resolvedTeamIds.has(refreshed.workspace_id)) {
|
|
36
43
|
ws.token = refreshed.token
|
|
44
|
+
ws.workspace_id = refreshed.workspace_id
|
|
37
45
|
ws.workspace_name = refreshed.workspace_name
|
|
46
|
+
resolvedTeamIds.add(ws.workspace_id)
|
|
38
47
|
await credManager.setWorkspace(ws)
|
|
39
48
|
validWorkspaces.push(ws)
|
|
40
49
|
}
|
|
@@ -54,21 +63,81 @@ export async function ensureSlackAuth(): Promise<void> {
|
|
|
54
63
|
}
|
|
55
64
|
}
|
|
56
65
|
|
|
66
|
+
// Bound worst-case HTTP traffic for users with very large root-state.json workspace lists.
|
|
67
|
+
const MAX_DOMAIN_ATTEMPTS = 16
|
|
68
|
+
|
|
69
|
+
// Slack workspace subdomains match `^[a-z][a-z0-9-]*$` per signup rules; validating here
|
|
70
|
+
// prevents a tampered root-state.json from steering the cookie-bearing fetch to a non-Slack
|
|
71
|
+
// host (e.g. a domain value containing `.`, `/`, `:`, `@`, `#`, or `?`).
|
|
72
|
+
const SLACK_DOMAIN_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9-]*$/
|
|
73
|
+
|
|
74
|
+
export type RefreshResult = { token: string; workspace_id: string; workspace_name: string }
|
|
75
|
+
|
|
76
|
+
export type RefreshContext = {
|
|
77
|
+
resolvedTeamIds?: Set<string>
|
|
78
|
+
refreshCache?: Map<string, RefreshResult | null>
|
|
79
|
+
}
|
|
80
|
+
|
|
57
81
|
export async function tryWebTokenRefresh(
|
|
58
82
|
ws: ExtractedWorkspace,
|
|
59
83
|
workspaceDomains: Record<string, string>,
|
|
60
|
-
|
|
84
|
+
context: RefreshContext = {},
|
|
85
|
+
): Promise<RefreshResult | null> {
|
|
61
86
|
if (!ws.cookie) return null
|
|
62
|
-
const domain = workspaceDomains[ws.workspace_id]
|
|
63
|
-
if (!domain) return null
|
|
64
87
|
|
|
88
|
+
// Try the domain that maps to this workspace_id first (when known), then fall back to
|
|
89
|
+
// every other known domain. Slack tokens extracted from LevelDB blobs sometimes carry
|
|
90
|
+
// workspace_id="unknown" because the regex window around the xoxc- bytes does not
|
|
91
|
+
// contain the T... team id; in that case the cookie may still be valid for one of the
|
|
92
|
+
// other workspaces the user is signed into.
|
|
93
|
+
const candidates = orderCandidateDomains(ws.workspace_id, workspaceDomains)
|
|
94
|
+
if (candidates.length === 0) return null
|
|
95
|
+
|
|
96
|
+
for (const { domain } of candidates) {
|
|
97
|
+
if (!SLACK_DOMAIN_REGEX.test(domain)) continue
|
|
98
|
+
|
|
99
|
+
const cacheKey = `${ws.cookie}\u0000${domain}`
|
|
100
|
+
const cached = context.refreshCache?.get(cacheKey)
|
|
101
|
+
let result: RefreshResult | null
|
|
102
|
+
if (cached !== undefined) {
|
|
103
|
+
result = cached
|
|
104
|
+
} else {
|
|
105
|
+
result = await refreshAndVerify(ws.cookie, domain, ws.workspace_name)
|
|
106
|
+
context.refreshCache?.set(cacheKey, result)
|
|
107
|
+
}
|
|
108
|
+
if (!result) continue
|
|
109
|
+
if (context.resolvedTeamIds?.has(result.workspace_id)) continue
|
|
110
|
+
return result
|
|
111
|
+
}
|
|
112
|
+
return null
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function orderCandidateDomains(
|
|
116
|
+
workspaceId: string,
|
|
117
|
+
workspaceDomains: Record<string, string>,
|
|
118
|
+
): Array<{ workspace_id: string; domain: string }> {
|
|
119
|
+
const entries = Object.entries(workspaceDomains).map(([workspace_id, domain]) => ({ workspace_id, domain }))
|
|
120
|
+
const exact = entries.findIndex((e) => e.workspace_id === workspaceId)
|
|
121
|
+
if (exact > 0) {
|
|
122
|
+
const [match] = entries.splice(exact, 1)
|
|
123
|
+
entries.unshift(match)
|
|
124
|
+
}
|
|
125
|
+
return entries.slice(0, MAX_DOMAIN_ATTEMPTS)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function refreshAndVerify(cookie: string, domain: string, fallbackName: string): Promise<RefreshResult | null> {
|
|
65
129
|
try {
|
|
66
|
-
const freshToken = await refreshTokenFromWeb(domain,
|
|
130
|
+
const freshToken = await refreshTokenFromWeb(domain, cookie)
|
|
67
131
|
if (!freshToken) return null
|
|
68
132
|
|
|
69
|
-
const client = await new SlackClient().login({ token: freshToken, cookie
|
|
133
|
+
const client = await new SlackClient().login({ token: freshToken, cookie })
|
|
70
134
|
const authInfo = await client.testAuth()
|
|
71
|
-
|
|
135
|
+
if (!authInfo.team_id) return null
|
|
136
|
+
return {
|
|
137
|
+
token: freshToken,
|
|
138
|
+
workspace_id: authInfo.team_id,
|
|
139
|
+
workspace_name: authInfo.team || fallbackName,
|
|
140
|
+
}
|
|
72
141
|
} catch {
|
|
73
142
|
return null
|
|
74
143
|
}
|
|
File without changes
|