Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
**English** | [简体中文](./GUIDE.zh-CN.md)

# DingTalk Channel SDK Integration Guide

Connect your Agent to DingTalk for real-time conversations in **group chats and direct messages**. The SDK handles event ingestion, message parsing and deduplication, reply sending, streaming output (typewriter effect), media upload/download, and card interactions—you just need to tell it "what the user said and what the bot should respond with."
Expand Down
2 changes: 0 additions & 2 deletions OVERVIEW.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
**English** | [简体中文](./OVERVIEW.zh-CN.md)

# DingTalk Channel SDK Family · Project Overview

> Origin issue: [DingTalk-Real-AI/dingtalk-workspace-cli#796](https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli/issues/796)—"Will DingTalk offer a Channel-like integration SDK in the future?"
Expand Down
2 changes: 0 additions & 2 deletions SPEC.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
**English** | [简体中文](./SPEC.zh-CN.md)

# DingTalk Channel SDK — Four-Language Unified Contract (SPEC v0.1)

> Positioning: **A conversation access layer decoupled from Agent runtime**. The SDK handles the dirty work of the "channel",
Expand Down
14 changes: 12 additions & 2 deletions src/main/java/com/dingtalk/channel/DingTalkChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ public byte[] downloadFile(String downloadCode, String msgId, String mediaType)
try {
java.net.HttpURLConnection conn = openMediaConnection(downloadUrl);
try (java.io.InputStream in = conn.getInputStream()) {
return in.readAllBytes();
return readAll(in);
} finally {
conn.disconnect();
}
Expand Down Expand Up @@ -278,7 +278,7 @@ private java.net.HttpURLConnection openMediaConnection(String initialUrl) throws
if (status != 200) {
try (java.io.InputStream err = conn.getErrorStream()) {
if (err != null) {
err.readAllBytes();
readAll(err);
}
} finally {
conn.disconnect();
Expand All @@ -290,6 +290,16 @@ private java.net.HttpURLConnection openMediaConnection(String initialUrl) throws
throw new java.io.IOException("too many redirects");
}

private static byte[] readAll(java.io.InputStream in) throws java.io.IOException {
java.io.ByteArrayOutputStream buf = new java.io.ByteArrayOutputStream();
byte[] chunk = new byte[8192];
int n;
while ((n = in.read(chunk)) != -1) {
buf.write(chunk, 0, n);
}
return buf.toByteArray();
}

/** 换取媒体下载 URL(downloadCode → downloadUrl)。 */
private String resolveDownloadUrl(String downloadCode, String msgId) {
if (downloadCode == null || downloadCode.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.dingtalk.channel.IncomingMessage;
import org.junit.Test;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
Expand All @@ -29,7 +29,7 @@ public void overrideAdmitsGroupInAllowlistMode() {
Map<String, PolicyConfig.GroupOverride> ov = new HashMap<>();
ov.put("cid-other", new PolicyConfig.GroupOverride());
PolicyGate gate = new PolicyGate(new PolicyConfig()
.groupAllowlist(List.of("cid-allowed"))
.groupAllowlist(Arrays.asList("cid-allowed"))
.groupOverrides(ov));
assertTrue(gate.evaluate(msg("cid-other", "staff-1", true)).allowed);
assertEquals(RejectReason.GROUP_NOT_ALLOWED, gate.evaluate(msg("cid-unknown", "staff-1", true)).reason);
Expand All @@ -40,7 +40,7 @@ public void blocklistNeverOverridden() {
Map<String, PolicyConfig.GroupOverride> ov = new HashMap<>();
ov.put("cid-bad", new PolicyConfig.GroupOverride().enabled(true));
PolicyGate gate = new PolicyGate(new PolicyConfig()
.groupBlocklist(List.of("cid-bad"))
.groupBlocklist(Arrays.asList("cid-bad"))
.groupOverrides(ov));
assertEquals(RejectReason.GROUP_BLOCKED, gate.evaluate(msg("cid-bad", "staff-1", true)).reason);
}
Expand All @@ -66,8 +66,8 @@ public void overrideDisableAndRequireMention() {
public void overrideAllowFromAndBlockFrom() {
Map<String, PolicyConfig.GroupOverride> ov = new HashMap<>();
ov.put("cid-1", new PolicyConfig.GroupOverride()
.allowFrom(List.of("staff-1", "staff-2"))
.blockFrom(List.of("staff-2")));
.allowFrom(Arrays.asList("staff-1", "staff-2"))
.blockFrom(Arrays.asList("staff-2")));
PolicyGate gate = new PolicyGate(new PolicyConfig().groupOverrides(ov));
assertTrue(gate.evaluate(msg("cid-1", "staff-1", true)).allowed);
assertEquals(RejectReason.SENDER_NOT_ALLOWED, gate.evaluate(msg("cid-1", "staff-9", true)).reason);
Expand Down
Loading