or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-auth.mddirect-messages.mdfavorites.mdindex.mdlists.mdplaces.mdsearch.mdstreaming.mdtimelines.mdtweets.mdusers.md

direct-messages.mddocs/

0

# Direct Messages

1

2

Private messaging functionality for sending and receiving direct messages.

3

4

## Core Direct Message Operations

5

6

### Sending Direct Messages

7

8

Send private messages to other Twitter users.

9

10

```java { .api }

11

interface DirectMessagesResources {

12

/**

13

* Send direct message by user ID

14

* @param userId Recipient user ID

15

* @param text Message text (max 10,000 characters)

16

* @return Sent direct message

17

*/

18

DirectMessage sendDirectMessage(long userId, String text) throws TwitterException;

19

20

/**

21

* Send direct message by screen name

22

* @param screenName Recipient screen name (without @)

23

* @param text Message text (max 10,000 characters)

24

* @return Sent direct message

25

*/

26

DirectMessage sendDirectMessage(String screenName, String text) throws TwitterException;

27

28

/**

29

* Send direct message with quick reply options

30

* @param userId Recipient user ID

31

* @param text Message text

32

* @param quickReplies Quick reply options

33

* @return Sent direct message

34

*/

35

DirectMessage sendDirectMessage(long userId, String text, QuickReply... quickReplies) throws TwitterException;

36

37

/**

38

* Send direct message as quick reply response

39

* @param userId Recipient user ID

40

* @param text Message text

41

* @param quickReplyResponse Quick reply response metadata

42

* @return Sent direct message

43

*/

44

DirectMessage sendDirectMessage(long userId, String text, String quickReplyResponse) throws TwitterException;

45

46

/**

47

* Send direct message with media attachment

48

* @param userId Recipient user ID

49

* @param text Message text

50

* @param mediaId Media ID from uploadMedia() call

51

* @return Sent direct message

52

*/

53

DirectMessage sendDirectMessage(long userId, String text, long mediaId) throws TwitterException;

54

}

55

```

56

57

**Usage Examples:**

58

59

```java

60

TwitterV1 v1 = twitter.v1();

61

62

// Send simple text message

63

DirectMessage dm = v1.directMessages().sendDirectMessage("recipient_user",

64

"Hello! This is a direct message.");

65

66

// Send message by user ID

67

DirectMessage dmById = v1.directMessages().sendDirectMessage(12345L,

68

"Hello via user ID!");

69

70

// Send message with media

71

File image = new File("attachment.jpg");

72

UploadedMedia media = v1.tweets().uploadMedia(image);

73

DirectMessage dmWithMedia = v1.directMessages().sendDirectMessage(12345L,

74

"Check out this image!", media.getMediaId());

75

76

// Send message with quick reply options

77

QuickReply option1 = QuickReply.of("yes", "Yes");

78

QuickReply option2 = QuickReply.of("no", "No");

79

DirectMessage dmWithOptions = v1.directMessages().sendDirectMessage(12345L,

80

"Do you like Twitter4J?", option1, option2);

81

```

82

83

### Retrieving Direct Messages

84

85

Get direct message conversations and individual messages.

86

87

```java { .api }

88

interface DirectMessagesResources {

89

/**

90

* Get direct messages (both sent and received)

91

* @param count Number of messages to retrieve (max 50)

92

* @return List of direct messages

93

*/

94

DirectMessageList getDirectMessages(int count) throws TwitterException;

95

96

/**

97

* Get direct messages with cursor pagination

98

* @param count Number of messages to retrieve (max 50)

99

* @param cursor Pagination cursor

100

* @return List of direct messages

101

*/

102

DirectMessageList getDirectMessages(int count, String cursor) throws TwitterException;

103

104

/**

105

* Get specific direct message by ID

106

* @param id Direct message ID

107

* @return Direct message

108

*/

109

DirectMessage showDirectMessage(long id) throws TwitterException;

110

}

111

```

112

113

**Usage Examples:**

114

115

```java

116

// Get recent direct messages

117

DirectMessageList messages = v1.directMessages().getDirectMessages(20);

118

for (DirectMessage dm : messages.getList()) {

119

System.out.println("From: " + dm.getSenderScreenName());

120

System.out.println("Text: " + dm.getText());

121

System.out.println("Date: " + dm.getCreatedAt());

122

}

123

124

// Paginate through all messages

125

String cursor = null;

126

do {

127

DirectMessageList batch = v1.directMessages().getDirectMessages(50, cursor);

128

for (DirectMessage dm : batch.getList()) {

129

processDirectMessage(dm);

130

}

131

cursor = batch.getNextCursor();

132

} while (cursor != null);

133

134

// Get specific message

135

DirectMessage specificDM = v1.directMessages().showDirectMessage(987654321L);

136

```

137

138

### Deleting Direct Messages

139

140

Delete direct messages from conversations.

141

142

```java { .api }

143

interface DirectMessagesResources {

144

/**

145

* Delete a direct message

146

* @param id Direct message ID to delete

147

*/

148

void destroyDirectMessage(long id) throws TwitterException;

149

}

150

```

151

152

**Usage Example:**

153

154

```java

155

// Delete a direct message

156

v1.directMessages().destroyDirectMessage(987654321L);

157

System.out.println("Direct message deleted");

158

```

159

160

## Media in Direct Messages

161

162

### Retrieving Media Content

163

164

Download media attachments from direct messages.

165

166

```java { .api }

167

interface DirectMessagesResources {

168

/**

169

* Get direct message image as input stream

170

* @param url Media URL from DirectMessage

171

* @return InputStream of image data

172

*/

173

InputStream getDMImageAsStream(String url) throws TwitterException;

174

}

175

```

176

177

**Usage Example:**

178

179

```java

180

DirectMessage dm = v1.directMessages().showDirectMessage(messageId);

181

182

// Check if message has media

183

if (dm.getMediaEntities().length > 0) {

184

MediaEntity media = dm.getMediaEntities()[0];

185

186

// Download the media

187

try (InputStream mediaStream = v1.directMessages().getDMImageAsStream(media.getMediaURL())) {

188

// Save to file

189

Files.copy(mediaStream, Paths.get("dm_image.jpg"));

190

}

191

}

192

```

193

194

## Quick Replies

195

196

### Quick Reply Options

197

198

Add interactive quick reply buttons to direct messages.

199

200

```java { .api }

201

class QuickReply {

202

/**

203

* Create quick reply option

204

* @param value Value returned when selected

205

* @param label Display text for button

206

* @return QuickReply option

207

*/

208

static QuickReply of(String value, String label);

209

210

/**

211

* Create quick reply with description

212

* @param value Value returned when selected

213

* @param label Display text for button

214

* @param description Additional description text

215

* @return QuickReply option

216

*/

217

static QuickReply of(String value, String label, String description);

218

219

/**

220

* Create quick reply with media

221

* @param value Value returned when selected

222

* @param label Display text for button

223

* @param mediaUrl URL of media to display

224

* @return QuickReply option

225

*/

226

static QuickReply withMedia(String value, String label, String mediaUrl);

227

228

/**

229

* Get option value

230

*/

231

String getValue();

232

233

/**

234

* Get display label

235

*/

236

String getLabel();

237

238

/**

239

* Get description text

240

*/

241

String getDescription();

242

243

/**

244

* Get media URL

245

*/

246

String getMediaUrl();

247

}

248

```

249

250

**Quick Reply Examples:**

251

252

```java

253

// Simple yes/no options

254

QuickReply yes = QuickReply.of("confirm_yes", "Yes");

255

QuickReply no = QuickReply.of("confirm_no", "No");

256

257

v1.directMessages().sendDirectMessage(userId,

258

"Would you like to receive notifications?", yes, no);

259

260

// Options with descriptions

261

QuickReply basic = QuickReply.of("plan_basic", "Basic", "$9.99/month");

262

QuickReply premium = QuickReply.of("plan_premium", "Premium", "$19.99/month");

263

QuickReply enterprise = QuickReply.of("plan_enterprise", "Enterprise", "Contact sales");

264

265

v1.directMessages().sendDirectMessage(userId,

266

"Choose your plan:", basic, premium, enterprise);

267

268

// Options with media

269

QuickReply red = QuickReply.withMedia("color_red", "Red", "https://example.com/red.png");

270

QuickReply blue = QuickReply.withMedia("color_blue", "Blue", "https://example.com/blue.png");

271

272

v1.directMessages().sendDirectMessage(userId,

273

"Pick your favorite color:", red, blue);

274

```

275

276

## Direct Message Data Model

277

278

### DirectMessage Interface

279

280

Complete direct message data structure.

281

282

```java { .api }

283

interface DirectMessage extends TwitterResponse {

284

/**

285

* Message unique identifier

286

*/

287

long getId();

288

289

/**

290

* Message text content

291

*/

292

String getText();

293

294

/**

295

* Sender user ID

296

*/

297

long getSenderId();

298

299

/**

300

* Sender screen name

301

*/

302

String getSenderScreenName();

303

304

/**

305

* Recipient user ID

306

*/

307

long getRecipientId();

308

309

/**

310

* Recipient screen name

311

*/

312

String getRecipientScreenName();

313

314

/**

315

* Message creation timestamp

316

*/

317

LocalDateTime getCreatedAt();

318

319

/**

320

* Quick reply options attached to message

321

*/

322

QuickReply[] getQuickReplies();

323

324

/**

325

* Quick reply response metadata (if this is a response)

326

*/

327

String getQuickReplyResponse();

328

329

/**

330

* URL entities in message text

331

*/

332

URLEntity[] getURLEntities();

333

334

/**

335

* User mention entities in message text

336

*/

337

UserMentionEntity[] getUserMentionEntities();

338

339

/**

340

* Hashtag entities in message text

341

*/

342

HashtagEntity[] getHashtagEntities();

343

344

/**

345

* Media entities (images, videos) attached to message

346

*/

347

MediaEntity[] getMediaEntities();

348

349

/**

350

* Symbol entities (cashtags) in message text

351

*/

352

SymbolEntity[] getSymbolEntities();

353

}

354

```

355

356

### DirectMessageList

357

358

Paginated list of direct messages.

359

360

```java { .api }

361

interface DirectMessageList extends TwitterResponse {

362

/**

363

* List of direct messages

364

*/

365

List<DirectMessage> getList();

366

367

/**

368

* Next cursor for pagination (null if no more)

369

*/

370

String getNextCursor();

371

372

/**

373

* Previous cursor for pagination

374

*/

375

String getPreviousCursor();

376

}

377

```

378

379

## Direct Message Management Patterns

380

381

### Conversation Threading

382

383

```java

384

public class DMConversationManager {

385

private final TwitterV1 v1;

386

387

public Map<String, List<DirectMessage>> getConversationsByUser() throws TwitterException {

388

DirectMessageList allMessages = v1.directMessages().getDirectMessages(50);

389

390

return allMessages.getList().stream()

391

.collect(Collectors.groupingBy(

392

dm -> getConversationKey(dm),

393

Collectors.toList()

394

));

395

}

396

397

private String getConversationKey(DirectMessage dm) {

398

// Create unique key for conversation between two users

399

long currentUserId = getCurrentUserId(); // Your implementation

400

long otherUserId = (dm.getSenderId() == currentUserId) ?

401

dm.getRecipientId() : dm.getSenderId();

402

403

return Math.min(currentUserId, otherUserId) + "_" +

404

Math.max(currentUserId, otherUserId);

405

}

406

}

407

```

408

409

### Auto-Response System

410

411

```java

412

public class DMAutoResponder {

413

private final TwitterV1 v1;

414

private final Map<String, String> responses;

415

416

public DMAutoResponder(TwitterV1 v1) {

417

this.v1 = v1;

418

this.responses = Map.of(

419

"help", "Here are the available commands: help, status, info",

420

"status", "All systems operational!",

421

"info", "This is an automated response system."

422

);

423

}

424

425

public void processQuickReplyResponse(DirectMessage dm) throws TwitterException {

426

String response = dm.getQuickReplyResponse();

427

428

if (response != null && responses.containsKey(response)) {

429

v1.directMessages().sendDirectMessage(

430

dm.getSenderId(),

431

responses.get(response)

432

);

433

}

434

}

435

436

public void handleTextMessage(DirectMessage dm) throws TwitterException {

437

String text = dm.getText().toLowerCase().trim();

438

439

if (responses.containsKey(text)) {

440

v1.directMessages().sendDirectMessage(

441

dm.getSenderId(),

442

responses.get(text)

443

);

444

} else {

445

// Send help with quick reply options

446

QuickReply help = QuickReply.of("help", "Help");

447

QuickReply status = QuickReply.of("status", "Status");

448

449

v1.directMessages().sendDirectMessage(

450

dm.getSenderId(),

451

"I didn't understand that. How can I help?",

452

help, status

453

);

454

}

455

}

456

}

457

```

458

459

### Bulk Message Operations

460

461

```java

462

public class BulkDMOperations {

463

private final TwitterV1 v1;

464

465

public void sendBulkMessage(List<Long> userIds, String message) throws TwitterException {

466

for (long userId : userIds) {

467

try {

468

v1.directMessages().sendDirectMessage(userId, message);

469

470

// Rate limiting - DM endpoint allows 1000 requests per 24 hours

471

Thread.sleep(100); // Small delay between messages

472

473

} catch (TwitterException e) {

474

if (e.getStatusCode() == 403) {

475

System.err.println("Cannot send DM to user " + userId + ": " + e.getMessage());

476

} else {

477

throw e; // Re-throw other errors

478

}

479

} catch (InterruptedException e) {

480

Thread.currentThread().interrupt();

481

break;

482

}

483

}

484

}

485

486

public void deleteAllMessagesFromUser(long userId) throws TwitterException {

487

DirectMessageList messages = v1.directMessages().getDirectMessages(50);

488

489

List<DirectMessage> toDelete = messages.getList().stream()

490

.filter(dm -> dm.getSenderId() == userId || dm.getRecipientId() == userId)

491

.collect(Collectors.toList());

492

493

for (DirectMessage dm : toDelete) {

494

try {

495

v1.directMessages().destroyDirectMessage(dm.getId());

496

Thread.sleep(100); // Rate limiting

497

} catch (TwitterException e) {

498

System.err.println("Failed to delete message " + dm.getId() + ": " + e.getMessage());

499

} catch (InterruptedException e) {

500

Thread.currentThread().interrupt();

501

break;

502

}

503

}

504

}

505

}

506

```

507

508

## Error Handling

509

510

Direct message operations can fail for various reasons:

511

512

```java

513

try {

514

DirectMessage dm = v1.directMessages().sendDirectMessage("user", "Hello!");

515

} catch (TwitterException e) {

516

switch (e.getStatusCode()) {

517

case 403:

518

if (e.getErrorCode() == 150) {

519

System.out.println("Cannot send DM: user doesn't follow you");

520

} else if (e.getErrorCode() == 151) {

521

System.out.println("Cannot send DM: user has disabled DMs");

522

} else {

523

System.out.println("Forbidden: " + e.getMessage());

524

}

525

break;

526

case 404:

527

System.out.println("User not found or account suspended");

528

break;

529

case 429:

530

System.out.println("Rate limit exceeded - DM limit reached");

531

break;

532

default:

533

System.out.println("Error sending DM: " + e.getMessage());

534

}

535

}

536

```