### Install SOLAPI SDK with npm Source: https://github.com/solapi/solapi-nodejs/blob/master/README.md Use this command to install the SOLAPI SDK for Node.js using the npm package manager. ```bash npm install --save solapi ``` -------------------------------- ### Install SOLAPI SDK with yarn Source: https://github.com/solapi/solapi-nodejs/blob/master/README.md Use this command to install the SOLAPI SDK for Node.js using the yarn package manager. ```bash yarn add solapi ``` -------------------------------- ### Install SOLAPI SDK with pnpm Source: https://github.com/solapi/solapi-nodejs/blob/master/README.md Use this command to install the SOLAPI SDK for Node.js using the pnpm package manager. ```bash pnpm add solapi ``` -------------------------------- ### Upload File for MMS and Kakao Friendtalk Source: https://context7.com/solapi/solapi-nodejs/llms.txt Upload files using `uploadFile` to get a `fileId` for MMS or Kakao Friendtalk messages. Note the different size limits and requirements for each type. ```typescript import path from 'path'; import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Upload for MMS const mmsFile = await messageService.uploadFile( path.join(__dirname, 'promo.jpg'), 'MMS', ); console.log(mmsFile.fileId); // use in send({ imageId: mmsFile.fileId, ... }) // Upload for Kakao Friendtalk (link is required) const kakaoFile = await messageService.uploadFile( 'https://example.com/banner.jpg', 'KAKAO', 'event-banner', 'https://example.com/event', ); console.log(kakaoFile.fileId); ``` -------------------------------- ### Send MMS with Image Source: https://context7.com/solapi/solapi-nodejs/llms.txt Sends an MMS message with an image. First, upload the file to get a `fileId`, then attach it using `imageId`. Adding a `subject` will automatically upgrade SMS to LMS/MMS. ```APIDOC ## `send(messages)` — Send MMS with Image Upload a file first to obtain `fileId`, then attach it as `imageId`. Adding `subject` automatically upgrades SMS to LMS/MMS. ```typescript import path from 'path'; import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); const { fileId } = await messageService.uploadFile( path.join(__dirname, 'photo.jpg'), 'MMS', ); const res = await messageService.send({ to: '01012345678', from: '029302266', imageId: fileId, subject: 'Photo message title', text: 'Here is your photo! ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789', }); console.log(res.groupInfo.count.registeredSuccess); // 1 ``` ``` -------------------------------- ### Query and Manage Groups Source: https://context7.com/solapi/solapi-nodejs/llms.txt Retrieve lists of groups, get details for a specific group, list messages within a group, and remove specific messages from a group. Supports pagination. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // List all groups (paginated) const groups = await messageService.getGroups({ limit: 10 }); console.log(groups.groupList); console.log(groups.nextKey); // use as startKey for next page // Get single group info const group = await messageService.getGroup('G4V20241208...'); console.log(group.count); // { total, registeredSuccess, registeredFailed, ... } // List messages in a group (paginated) const messages = await messageService.getGroupMessages('G4V20241208...', { limit: 100 }); console.log(messages.messageList); // Delete specific messages from a group await messageService.removeGroupMessages('G4V20241208...', [ 'M4V20241208...001', 'M4V20241208...002', ]); ``` -------------------------------- ### Group API - Query and Manage Groups/Messages Source: https://context7.com/solapi/solapi-nodejs/llms.txt Query and manage existing groups and their associated messages. Retrieve lists of groups, get details for a specific group, list messages within a group, or remove specific messages from a group. ```APIDOC ## `getGroups(data?)` / `getGroup(groupId)` / `getGroupMessages(groupId, data?)` / `removeGroupMessages(groupId, messageIds)` Query and manage groups and their messages. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // List all groups (paginated) const groups = await messageService.getGroups({ limit: 10 }); console.log(groups.groupList); console.log(groups.nextKey); // use as startKey for next page // Get single group info const group = await messageService.getGroup('G4V20241208...'); console.log(group.count); // { total, registeredSuccess, registeredFailed, ... } // List messages in a group (paginated) const messages = await messageService.getGroupMessages('G4V20241208...', { limit: 100 }); console.log(messages.messageList); // Delete specific messages from a group await messageService.removeGroupMessages('G4V20241208...', [ 'M4V20241208...001', 'M4V20241208...002', ]); ``` ``` -------------------------------- ### Instantiate SolapiMessageService Source: https://context7.com/solapi/solapi-nodejs/llms.txt Initializes the unified service client with your API key and secret. Both are required, and providing empty values will immediately throw an `ApiKeyError`. ```APIDOC ## `new SolapiMessageService(apiKey, apiSecret)` Instantiates the unified service client. Both `apiKey` and `apiSecret` are required; passing empty values throws an `ApiKeyError` immediately. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService( 'YOUR_API_KEY', 'YOUR_API_SECRET', ); ``` ``` -------------------------------- ### Instantiate SolapiMessageService Client Source: https://context7.com/solapi/solapi-nodejs/llms.txt Instantiate the unified service client with your API key and secret. Passing empty values will immediately throw an ApiKeyError. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService( 'YOUR_API_KEY', 'YOUR_API_SECRET', ); ``` -------------------------------- ### Manage Kakao Alimtalk Templates with Solapi Node.js SDK Source: https://context7.com/solapi/solapi-nodejs/llms.txt Full lifecycle management of Kakao Alimtalk templates: create, query, update, submit for inspection, cancel inspection, and delete. Requires fetching categories before creating a template. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Fetch categories (required before creating a template) const categories = await messageService.getKakaoAlimtalkTemplateCategories(); const categoryCode = categories[categories.length - 1].code; // Create template const template = await messageService.createKakaoAlimtalkTemplate({ name: 'Order Confirmation', content: 'Hello #{name}, your order #{orderNumber} has been confirmed.', channelId: 'your-channel-pfId', categoryCode: categoryCode, messageType: 'BA', // BA: basic | EX: extra info | AD: advertisement | MI: mixed buttons: [ { buttonName: 'Track Order', buttonType: 'WL', linkMo: 'https://m.example.com/orders', linkPc: 'https://example.com/orders', }, ], }); console.log(template.templateId); // List templates const templates = await messageService.getKakaoAlimtalkTemplates({ limit: 20 }); console.log(templates.templateList); // Get single template const detail = await messageService.getKakaoAlimtalkTemplate(template.templateId); // Update template content (only when not under inspection) await messageService.updateKakaoAlimtalkTemplate(template.templateId, { content: 'Updated content for #{name}, order #{orderNumber}.', }); // Rename template (allowed regardless of inspection status) await messageService.updateKakaoAlimtalkTemplateName(template.templateId, 'New Template Name'); // Cancel pending inspection await messageService.cancelInspectionKakaoAlimtalkTemplate(template.templateId); // Delete template (only when status is pending or rejected) await messageService.removeKakaoAlimtalkTemplate(template.templateId); ``` -------------------------------- ### Manage Kakao Business Channels with Solapi Node.js SDK Source: https://context7.com/solapi/solapi-nodejs/llms.txt Manage Kakao business channel connections. Connecting a new channel requires fetching categories, requesting a token to the channel manager's phone, and creating the channel with the received token. Supports listing, retrieving, and deleting channels. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Step 1: get categories const categories = await messageService.getKakaoChannelCategories(); const categoryCode = categories[115].code; // e.g., computer/software category // Step 2: request verification token (sent via SMS to the manager's phone) await messageService.requestKakaoChannelToken({ searchId: '@your-kakao-channel-id', phoneNumber: '01012345678', }); // Step 3: create channel with the received token const channel = await messageService.createKakaoChannel({ searchId: '@your-kakao-channel-id', phoneNumber: '01012345678', categoryCode: categoryCode, token: '123456', // token received via SMS }); console.log(channel.channelId); // pfId used for sending // List channels const channels = await messageService.getKakaoChannels({ limit: 10 }); console.log(channels.channelList); // Get single channel const singleChannel = await messageService.getKakaoChannel('your-channel-id'); // Delete channel (also deletes all associated templates!) await messageService.removeKakaoChannel('your-channel-id'); ``` -------------------------------- ### Manage Kakao Alimtalk Templates Source: https://context7.com/solapi/solapi-nodejs/llms.txt Full lifecycle management of Kakao Alimtalk templates: create, query, update, submit for inspection, cancel inspection, and delete. ```APIDOC ## `getKakaoAlimtalkTemplateCategories()` / `createKakaoAlimtalkTemplate(data)` / `getKakaoAlimtalkTemplates(data?)` / `getKakaoAlimtalkTemplate(templateId)` / `updateKakaoAlimtalkTemplate(templateId, data)` / `updateKakaoAlimtalkTemplateName(templateId, name)` / `cancelInspectionKakaoAlimtalkTemplate(templateId)` / `removeKakaoAlimtalkTemplate(templateId)` Full lifecycle management of Kakao Alimtalk templates: create, query, update, submit for inspection, cancel inspection, and delete. ### Usage ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Fetch categories (required before creating a template) const categories = await messageService.getKakaoAlimtalkTemplateCategories(); const categoryCode = categories[categories.length - 1].code; // Create template const template = await messageService.createKakaoAlimtalkTemplate({ name: 'Order Confirmation', content: 'Hello #{name}, your order #{orderNumber} has been confirmed.', channelId: 'your-channel-pfId', categoryCode: categoryCode, messageType: 'BA', // BA: basic | EX: extra info | AD: advertisement | MI: mixed buttons: [ { buttonName: 'Track Order', buttonType: 'WL', linkMo: 'https://m.example.com/orders', linkPc: 'https://example.com/orders', }, ], }); console.log(template.templateId); // List templates const templates = await messageService.getKakaoAlimtalkTemplates({ limit: 20 }); console.log(templates.templateList); // Get single template const detail = await messageService.getKakaoAlimtalkTemplate(template.templateId); // Update template content (only when not under inspection) await messageService.updateKakaoAlimtalkTemplate(template.templateId, { content: 'Updated content for #{name}, order #{orderNumber}.', }); // Rename template (allowed regardless of inspection status) await messageService.updateKakaoAlimtalkTemplateName(template.templateId, 'New Template Name'); // Cancel pending inspection await messageService.cancelInspectionKakaoAlimtalkTemplate(template.templateId); // Delete template (only when status is pending or rejected) await messageService.removeKakaoAlimtalkTemplate(template.templateId); ``` ``` -------------------------------- ### Schedule and Manage Group Sends Source: https://context7.com/solapi/solapi-nodejs/llms.txt This snippet demonstrates how to create a group, add messages, schedule them for a specific time, cancel reservations, and delete the group. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // --- Scheduled group send --- const scheduledGroupId = await messageService.createGroup(); await messageService.addMessagesToGroup(scheduledGroupId, [ { to: '01033333333', from: '029302266', text: 'Scheduled batch' }, ]); await messageService.reserveGroup(scheduledGroupId, '2025-12-25 09:00:00'); // Cancel reservation (marks all messages as failed) await messageService.removeReservationToGroup(scheduledGroupId); // Delete the group entirely await messageService.removeGroup(scheduledGroupId); ``` -------------------------------- ### Create, Add Messages, and Send Group Source: https://context7.com/solapi/solapi-nodejs/llms.txt Use this to create a group, add messages in batches, and send them immediately. Supports up to 1,000,000 messages per group. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // --- Immediate bulk send via group --- const groupId = await messageService.createGroup(); // Add messages in batches of up to 10,000 await messageService.addMessagesToGroup(groupId, [ { to: '01011111111', from: '029302266', text: 'Batch message 1' }, { to: '01022222222', from: '029302266', text: 'Batch message 2' }, // ... up to 10,000 per call ]); // Fire immediately await messageService.sendGroup(groupId); ``` -------------------------------- ### Manage Kakao Business Channels Source: https://context7.com/solapi/solapi-nodejs/llms.txt Manage Kakao business channel connections. Connecting a new channel requires fetching categories, requesting a token, and then creating the channel. ```APIDOC ## `getKakaoChannelCategories()` / `requestKakaoChannelToken(data)` / `createKakaoChannel(data)` / `getKakaoChannels(data?)` / `getKakaoChannel(channelId)` / `removeKakaoChannel(channelId)` Manage Kakao business channel connections. Connecting a new channel requires: (1) fetching categories, (2) requesting a token to the channel manager's phone, (3) creating the channel with the received token. ### Usage ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Step 1: get categories const categories = await messageService.getKakaoChannelCategories(); const categoryCode = categories[115].code; // e.g., computer/software category // Step 2: request verification token (sent via SMS to the manager's phone) await messageService.requestKakaoChannelToken({ searchId: '@your-kakao-channel-id', phoneNumber: '01012345678', }); // Step 3: create channel with the received token const channel = await messageService.createKakaoChannel({ searchId: '@your-kakao-channel-id', phoneNumber: '01012345678', categoryCode: categoryCode, token: '123456', // token received via SMS }); console.log(channel.channelId); // pfId used for sending // List channels const channels = await messageService.getKakaoChannels({ limit: 10 }); console.log(channels.channelList); // Get single channel const singleChannel = await messageService.getKakaoChannel('your-channel-id'); // Delete channel (also deletes all associated templates!) await messageService.removeKakaoChannel('your-channel-id'); ``` ``` -------------------------------- ### Error Classes and Handling Source: https://context7.com/solapi/solapi-nodejs/llms.txt Understand and handle various error classes thrown by the SOLAPI Node.js SDK using discriminated union patterns. ```APIDOC ## Error Classes All errors are tagged Effect `Data` classes accessible via the `_tag` property for discriminated union handling. ### Error Types and Handling - **MessageNotReceivedError**: Handles cases where all messages failed. Provides `totalCount` and `failedMessageList`. - **BadRequestError**: Catches invalid input parameters. Provides an error `message`. - **ClientError**: Catches 4xx HTTP errors from the SOLAPI API. Provides `errorCode` and `httpStatus`. - **ServerError**: Catches 5xx HTTP errors from the SOLAPI API. Provides `errorCode` and `httpStatus`. - **NetworkError**: Catches connection or timeout failures. Provides an error `message`. ``` -------------------------------- ### Upload File / Image Source: https://context7.com/solapi/solapi-nodejs/llms.txt Uploads a file (local path or accessible URL) and returns a `fileId` for use in MMS or Kakao Friendtalk messages. Size limits: KAKAO 500 KB, MMS 200 KB, DOCUMENT 2 MB. ```APIDOC ## `uploadFile(filePath, fileType, name?, link?)` — Upload File / Image Uploads a file (local path or accessible URL) and returns a `fileId` for use in MMS or Kakao Friendtalk messages. Size limits: KAKAO 500 KB, MMS 200 KB, DOCUMENT 2 MB. ### Request Example ```typescript import path from 'path'; import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Upload for MMS const mmsFile = await messageService.uploadFile( path.join(__dirname, 'promo.jpg'), 'MMS', ); console.log(mmsFile.fileId); // use in send({ imageId: mmsFile.fileId, ... }) // Upload for Kakao Friendtalk (link is required) const kakaoFile = await messageService.uploadFile( 'https://example.com/banner.jpg', 'KAKAO', 'event-banner', 'https://example.com/event', ); console.log(kakaoFile.fileId); ``` ``` -------------------------------- ### Query Account Balance Source: https://context7.com/solapi/solapi-nodejs/llms.txt Fetch the current cash and point balances for your SOLAPI account. Essential for monitoring your account's financial status. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); const balance = await messageService.getBalance(); console.log('Cash balance:', balance.balance); console.log('Points:', balance.point); ``` -------------------------------- ### Send Kakao Alimtalk Messages Source: https://context7.com/solapi/solapi-nodejs/llms.txt Use `send` with `kakaoOptions` to send Kakao notification talk. Pre-register templates and business channels. Use `variables` to populate placeholders. Supports single and bulk messages. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Single Alimtalk await messageService.send({ to: '01012345678', from: '029302266', kakaoOptions: { pfId: 'your-business-channel-pfId', templateId: 'your-alimtalk-template-id', variables: { '#{name}': 'John Doe', '#{orderNumber}': 'ORD-20241208', }, // disableSms: true, // disable SMS fallback }, }); // Bulk Alimtalk (up to 10,000 per call) await messageService.send([ { to: '01011111111', from: '029302266', kakaoOptions: { pfId: 'your-pfId', templateId: 'your-template-id', variables: { '#{name}': 'Alice' }, }, }, { to: '01022222222', from: '029302266', kakaoOptions: { pfId: 'your-pfId', templateId: 'your-template-id', variables: { '#{name}': 'Bob' }, }, }, ]); ``` -------------------------------- ### Query Account Balance Source: https://context7.com/solapi/solapi-nodejs/llms.txt Retrieve the current cash and point balances for your SOLAPI account. ```APIDOC ## `getBalance()` — Query Account Balance Returns the current cash balance and point balance for the SOLAPI account. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); const balance = await messageService.getBalance(); console.log('Cash balance:', balance.balance); console.log('Points:', balance.point); ``` ``` -------------------------------- ### Webhook Integration for Delivery Reports Source: https://context7.com/solapi/solapi-nodejs/llms.txt Configure webhook endpoints to receive real-time delivery reports for single messages, group sends, and fax messages. SOLAPI expects an HTTP 200 response; otherwise, it will retry the delivery up to 5 times. ```APIDOC ## Webhook Integration — Receiving Delivery Reports Configure a webhook endpoint in the SOLAPI dashboard to receive real-time delivery reports for single messages and group sends. Must respond with HTTP 200; otherwise SOLAPI retries up to 5 times. ### POST /webhooks/single-report **Description**: Receives delivery reports for single messages. The request body is an array of message info objects. **Request Body**: Array of message info objects. **Response**: Returns HTTP 200 on success. ### POST /webhooks/group-report **Description**: Receives delivery reports for group sends. The request body is an array of group info objects. **Request Body**: Array of group info objects. **Response**: Returns HTTP 200 on success. ### POST /webhooks/fax **Description**: Receives reports for fax messages. **Request Body**: Array of fax info objects. **Response**: Returns HTTP 200 on success. ``` -------------------------------- ### Configure Webhook Endpoint for Delivery Reports Source: https://context7.com/solapi/solapi-nodejs/llms.txt Set up an Express.js server to receive real-time delivery reports for single messages, group sends, and faxes. Ensure your endpoint responds with HTTP 200 to prevent retries. ```javascript const express = require('express'); const bodyParser = require('body-parser'); const asyncify = require('express-asyncify'); const { SolapiMessageService } = require('solapi'); const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); const app = asyncify(express()); app.use(bodyParser.json()); // Single message report: body is an array of message info objects app.post('/webhooks/single-report', async (req, res) => { for (const messageInfo of req.body) { // statusCode 4000 = delivered successfully (for both SMS and Alimtalk) console.log('Message report:', messageInfo); } return res.status(200).json({}); }); // Group report: body is an array of group info objects app.post('/webhooks/group-report', async (req, res) => { for (const groupInfo of req.body) { const result = await messageService.getGroupMessages(groupInfo.groupId); for (const messageId in result.messageList) { console.log('Message:', result.messageList[messageId]); // statusCode: https://developers.solapi.com/references/message-status-codes } } return res.status(200).json({}); }); // Fax receive report app.post('/webhooks/fax', async (req, res) => { for (const faxInfo of req.body) { console.log('Fax received:', faxInfo); } return res.status(200).json({}); }); app.listen(8080); ``` -------------------------------- ### Supported Message Types Source: https://context7.com/solapi/solapi-nodejs/llms.txt Lists all supported message types for the SOLAPI SDK, including standard SMS, MMS, KakaoTalk, Naver Smart Alert, RCS, Fax, and Voice messages. ```APIDOC ## TypeScript — Supported Message Types The `type` field accepts any of the following string literals. When `autoTypeDetect` is `true` (default behavior), the type is inferred from text length and options. ### Supported Message Types - **SMS**: Short text (≤90 chars English, ≤45 chars Korean) - **LMS**: Long text - **MMS**: Picture message - **ATA**: Kakao Alimtalk - **CTA**: Kakao Friendtalk (text) - **CTI**: Kakao Friendtalk (image) - **NSA**: Naver Smart Alert - **RCS_SMS**: RCS SMS - **RCS_LMS**: RCS LMS - **RCS_MMS**: RCS MMS - **RCS_TPL**: RCS template - **RCS_ITPL**: RCS image template - **RCS_LTPL**: RCS long template - **FAX**: Fax - **VOICE**: Voice (TTS) - **BMS_TEXT**: Kakao BMS free text - **BMS_IMAGE**: Kakao BMS free image - **BMS_WIDE**: Kakao BMS wide image - **BMS_WIDE_ITEM_LIST**: Kakao BMS wide item list - **BMS_CAROUSEL_FEED**: Kakao BMS carousel feed - **BMS_PREMIUM_VIDEO**: Kakao BMS premium video - **BMS_COMMERCE**: Kakao BMS commerce - **BMS_CAROUSEL_COMMERCE**: Kakao BMS carousel commerce - **BMS_FREE**: Kakao BMS free-form ``` -------------------------------- ### Group API - Create, Add Messages, Send, Reserve Source: https://context7.com/solapi/solapi-nodejs/llms.txt Manage groups for large-scale bulk sending. Create a group, add messages (up to 10,000 per call, 1,000,000 per group), and then send immediately or schedule for later. ```APIDOC ## Group API — `createGroup` / `addMessagesToGroup` / `sendGroup` / `reserveGroup` The Group API enables large-scale bulk sending: create a group, add up to 1,000,000 messages (10,000 per `addMessagesToGroup` call), then send or schedule the entire group atomically. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // --- Immediate bulk send via group --- const groupId = await messageService.createGroup(); // Add messages in batches of up to 10,000 await messageService.addMessagesToGroup(groupId, [ { to: '01011111111', from: '029302266', text: 'Batch message 1' }, { to: '01022222222', from: '029302266', text: 'Batch message 2' }, // ... up to 10,000 per call ]); // Fire immediately await messageService.sendGroup(groupId); // --- Scheduled group send --- const scheduledGroupId = await messageService.createGroup(); await messageService.addMessagesToGroup(scheduledGroupId, [ { to: '01033333333', from: '029302266', text: 'Scheduled batch' }, ]); await messageService.reserveGroup(scheduledGroupId, '2025-12-25 09:00:00'); // Cancel reservation (marks all messages as failed) await messageService.removeReservationToGroup(scheduledGroupId); // Delete the group entirely await messageService.removeGroup(scheduledGroupId); ``` ``` -------------------------------- ### Send MMS with Image Source: https://context7.com/solapi/solapi-nodejs/llms.txt Send an MMS by first uploading an image using `uploadFile` and then attaching the returned `fileId` to the `imageId` field. Adding a `subject` will automatically upgrade SMS to LMS/MMS. ```typescript import path from 'path'; import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); const { fileId } = await messageService.uploadFile( path.join(__dirname, 'photo.jpg'), 'MMS', ); const res = await messageService.send({ to: '01012345678', from: '029302266', imageId: fileId, subject: 'Photo message title', text: 'Here is your photo! ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789', }); console.log(res.groupInfo.count.registeredSuccess); // 1 ``` -------------------------------- ### Send Kakao Alimtalk Source: https://context7.com/solapi/solapi-nodejs/llms.txt Send Kakao notification talk (ATA) using a pre-registered template and business channel (`pfId`). Use `variables` to fill in template placeholders. Set `disableSms: true` to prevent SMS fallback. ```APIDOC ## `send(messages)` — Send Kakao Alimtalk Send Kakao notification talk (ATA) using a pre-registered template and business channel (`pfId`). Use `variables` to fill in template placeholders. Set `disableSms: true` to prevent SMS fallback. ### Request Example ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Single Alimtalk await messageService.send({ to: '01012345678', from: '029302266', kakaoOptions: { pfId: 'your-business-channel-pfId', templateId: 'your-alimtalk-template-id', variables: { '#{name}': 'John Doe', '#{orderNumber}': 'ORD-20241208', }, // disableSms: true, // disable SMS fallback }, }); // Bulk Alimtalk (up to 10,000 per call) await messageService.send([ { to: '01011111111', from: '029302266', kakaoOptions: { pfId: 'your-pfId', templateId: 'your-template-id', variables: { '#{name}': 'Alice' }, }, }, { to: '01022222222', from: '029302266', kakaoOptions: { pfId: 'your-pfId', templateId: 'your-template-id', variables: { '#{name}': 'Bob' }, }, }, ]); ``` ``` -------------------------------- ### List of Supported Message Types in Solapi Source: https://context7.com/solapi/solapi-nodejs/llms.txt An enumeration of all supported message types for the Solapi SDK. The `type` field can be explicitly set, or `autoTypeDetect` (default) can infer the type based on message content and options. ```typescript import type { MessageType } from 'solapi'; // All supported type values: const types: MessageType[] = [ 'SMS', // Short text (≤90 chars English, ≤45 chars Korean) 'LMS', // Long text 'MMS', // Picture message 'ATA', // Kakao Alimtalk 'CTA', // Kakao Friendtalk (text) 'CTI', // Kakao Friendtalk (image) 'NSA', // Naver Smart Alert 'RCS_SMS', // RCS SMS 'RCS_LMS', // RCS LMS 'RCS_MMS', // RCS MMS 'RCS_TPL', // RCS template 'RCS_ITPL', // RCS image template 'RCS_LTPL', // RCS long template 'FAX', // Fax 'VOICE', // Voice (TTS) 'BMS_TEXT', // Kakao BMS free text 'BMS_IMAGE', // Kakao BMS free image 'BMS_WIDE', // Kakao BMS wide image 'BMS_WIDE_ITEM_LIST', // Kakao BMS wide item list 'BMS_CAROUSEL_FEED', // Kakao BMS carousel feed 'BMS_PREMIUM_VIDEO', // Kakao BMS premium video 'BMS_COMMERCE', // Kakao BMS commerce 'BMS_CAROUSEL_COMMERCE', // Kakao BMS carousel commerce 'BMS_FREE', // Kakao BMS free-form ]; ``` -------------------------------- ### Query Opt-out Lists with Solapi Node.js SDK Source: https://context7.com/solapi/solapi-nodejs/llms.txt Query the 080 opt-out (block) lists, including individual numbers, block groups, and numbers within groups. Supports filtering by sender number or date and pagination. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Query 080 opt-out numbers, optionally filter by sender number or date const blacks = await messageService.getBlacks({ // senderNumber: '029302266', startDate: '2024-12-01 00:00:00', endDate: '2024-12-31 23:59:59', }); console.log(blacks.blackList); // Paginate const page2 = await messageService.getBlacks({ startKey: blacks.nextKey }); // Block groups and numbers const blockGroups = await messageService.getBlockGroups(); const blockNumbers = await messageService.getBlockNumbers(); console.log(blockGroups.groupList, blockNumbers.numberList); ``` -------------------------------- ### Send RCS with Buttons Source: https://context7.com/solapi/solapi-nodejs/llms.txt Send RCS messages with interactive buttons. Supports `WL` (web link), and other button types. Attach `replacements` for SMS fallback if RCS delivery fails. ```APIDOC ## `send(messages)` — Send RCS with Buttons Send RCS messages with interactive buttons. Supports `WL` (web link), and other button types. Attach `replacements` for SMS fallback if RCS delivery fails. ### Request Example ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); await messageService.send({ to: '01012345678', from: '029302266', text: 'Your RCS message content here.', rcsOptions: { brandId: 'your-rcs-brand-id', buttons: [ { buttonType: 'WL', buttonName: 'Visit Website', link: 'https://www.example.com', }, ], }, // Fallback to SMS if RCS fails replacements: [ { to: '01012345678', from: '029302266', text: 'SMS fallback content if RCS fails.', }, ], }); ``` ``` -------------------------------- ### Send SMS / LMS / MMS (single or bulk, with optional scheduling) Source: https://context7.com/solapi/solapi-nodejs/llms.txt Sends one or up to 10,000 messages in a single call. The message type is auto-detected. Throws `MessageNotReceivedError` if all messages fail, or `BadRequestError` for invalid parameters. ```APIDOC ## `send(messages, config?)` — Send SMS / LMS / MMS (single or bulk, with optional scheduling) Sends one or up to 10,000 messages in a single call. Message type (SMS/LMS/MMS) is auto-detected from text length or the presence of `imageId`. Throws `MessageNotReceivedError` if all messages fail, or `BadRequestError` for invalid parameters. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Single SMS const single = await messageService.send({ to: '01012345678', from: '029302266', text: 'Hello from SOLAPI! Under 90 chars → sent as SMS automatically.', }); console.log(single.groupInfo.count); // { total: 1, registeredSuccess: 1, registeredFailed: 0, ... } // Bulk send (up to 10,000 per call) const bulk = await messageService.send([ { to: '01011111111', from: '029302266', text: 'Bulk message 1' }, { to: '01022222222', from: '029302266', text: 'Bulk message 2' }, ]); // Scheduled send const scheduled = await messageService.send( { to: '01012345678', from: '029302266', text: 'Scheduled message' }, { scheduledDate: '2025-12-08 09:00:00' }, ); // Allow duplicate recipients const withDuplicates = await messageService.send( [ { to: '01012345678', from: '029302266', text: 'Dup OK message 1' }, { to: '01012345678', from: '029302266', text: 'Dup OK message 2' }, ], { allowDuplicates: true }, ); // Error handling try { await messageService.send({ to: '01012345678', from: '029302266', text: 'Hi' }); } catch (err) { if (err._tag === 'MessageNotReceivedError') { console.error('All messages failed:', err.failedMessageList); } else if (err._tag === 'BadRequestError') { console.error('Invalid parameters:', err.message); } } ``` ``` -------------------------------- ### Send RCS Messages with Buttons Source: https://context7.com/solapi/solapi-nodejs/llms.txt Send Rich Communication Services (RCS) messages with interactive buttons like web links. Use `replacements` for SMS fallback if RCS delivery fails. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); await messageService.send({ to: '01012345678', from: '029302266', text: 'Your RCS message content here.', rcsOptions: { brandId: 'your-rcs-brand-id', buttons: [ { buttonType: 'WL', buttonName: 'Visit Website', link: 'https://www.example.com', }, ], }, // Fallback to SMS if RCS fails replacements: [ { to: '01012345678', from: '029302266', text: 'SMS fallback content if RCS fails.', }, ], }); ``` -------------------------------- ### Send Kakao BMS (Brand Message Service) Source: https://context7.com/solapi/solapi-nodejs/llms.txt Send Kakao Brand Message using a pre-registered BMS template. The `targeting` field controls the target audience type (`I`: general, `M`/`N`: requires Kakao authorization). ```APIDOC ## `send(messages)` — Send Kakao BMS (Brand Message Service) Send Kakao Brand Message using a pre-registered BMS template. The `targeting` field controls the target audience type (`I`: general, `M`/`N`: requires Kakao authorization). ### Request Example ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); await messageService.send({ to: '01012345678', kakaoOptions: { pfId: 'your-business-channel-pfId', templateId: 'your-bms-template-id', variables: { orderAmount: '50,000' }, bms: { targeting: 'I', }, }, }); ``` ``` -------------------------------- ### Query Opt-out Lists Source: https://context7.com/solapi/solapi-nodejs/llms.txt Query the 080 opt-out (block) lists: individual numbers that have opted out, block groups, and numbers within groups. ```APIDOC ## `getBlacks(data?)` / `getBlockGroups(data?)` / `getBlockNumbers(data?)` Query the 080 opt-out (block) lists: individual numbers that have opted out, block groups, and numbers within groups. ### Usage ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Query 080 opt-out numbers, optionally filter by sender number or date const blacks = await messageService.getBlacks({ // senderNumber: '029302266', startDate: '2024-12-01 00:00:00', endDate: '2024-12-31 23:59:59', }); console.log(blacks.blackList); // Paginate const page2 = await messageService.getBlacks({ startKey: blacks.nextKey }); // Block groups and numbers const blockGroups = await messageService.getBlockGroups(); const blockNumbers = await messageService.getBlockNumbers(); console.log(blockGroups.groupList, blockNumbers.numberList); ``` ``` -------------------------------- ### Query Sending Statistics Source: https://context7.com/solapi/solapi-nodejs/llms.txt Retrieve aggregated sending statistics for your account, optionally filtered by a specific date range. Useful for analyzing message delivery performance. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); const stats = await messageService.getStatistics({ startDate: '2024-12-01 00:00:00', endDate: '2024-12-31 23:59:59', }); console.log(stats); // { SMS: { request: 100, success: 98, ... }, LMS: { ... }, ATA: { ... }, ... } ``` -------------------------------- ### Handle Solapi SDK Errors with Discriminated Unions Source: https://context7.com/solapi/solapi-nodejs/llms.txt Implement robust error handling for Solapi API calls using TypeScript's discriminated unions. This allows for specific handling of various error types like network issues, bad requests, or server errors. ```typescript import { SolapiMessageService, ApiKeyError, BadRequestError, MessageNotReceivedError, ClientError, ServerError, NetworkError, ResponseSchemaMismatchError, } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); try { await messageService.send({ to: '01012345678', from: '029302266', text: 'Hi' }); } catch (err) { switch ((err as { _tag: string })._tag) { case 'MessageNotReceivedError': // All messages failed; inspect each failure console.error('All failed. Count:', (err as MessageNotReceivedError).totalCount); console.error('Failed list:', (err as MessageNotReceivedError).failedMessageList); break; case 'BadRequestError': // Invalid input parameters console.error('Bad request:', (err as BadRequestError).message); break; case 'ClientError': // 4xx HTTP errors from SOLAPI API console.error('Client error:', (err as ClientError).errorCode, (err as ClientError).httpStatus); break; case 'ServerError': // 5xx HTTP errors from SOLAPI API console.error('Server error:', (err as ServerError).errorCode, (err as ServerError).httpStatus); break; case 'NetworkError': // Connection/timeout failures console.error('Network error:', (err as NetworkError).message); break; } } ``` -------------------------------- ### Schedule SMS Message Sending Source: https://context7.com/solapi/solapi-nodejs/llms.txt Schedule a message to be sent at a specific date and time using the `scheduledDate` option. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Scheduled send const scheduled = await messageService.send( { to: '01012345678', from: '029302266', text: 'Scheduled message' }, { scheduledDate: '2025-12-08 09:00:00' }, ); ``` -------------------------------- ### Query Sending Statistics Source: https://context7.com/solapi/solapi-nodejs/llms.txt Retrieve aggregated sending statistics for your account. The statistics can be optionally filtered by a specific date range. ```APIDOC ## `getStatistics(data?)` — Query Sending Statistics Retrieve aggregated sending statistics, optionally filtered by date range. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); const stats = await messageService.getStatistics({ startDate: '2024-12-01 00:00:00', endDate: '2024-12-31 23:59:59', }); console.log(stats); // { SMS: { request: 100, success: 98, ... }, LMS: { ... }, ATA: { ... }, ... } ``` ``` -------------------------------- ### Send Voice Messages (TTS) Source: https://context7.com/solapi/solapi-nodejs/llms.txt Send text-to-speech (TTS) voice calls using `voiceOptions`. Specify `voiceType` and optionally add `headerMessage`, `tailMessage`, or counselor transfer options. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); await messageService.send({ to: '01012345678', from: '029302266', text: 'Hello, this is an automated voice message.', voiceOptions: { voiceType: 'FEMALE', // 'MALE' or 'FEMALE' headerMessage: 'Welcome call', // optional intro spoken before text tailMessage: 'Thank you.', // optional outro (not played if counselor transfer) // replyRange: 1, // digits 1–9 the recipient can press (cannot use with counselorNumber) // counselorNumber: '029302266',// press 0 to connect to counselor }, }); ``` -------------------------------- ### Send Messages with Duplicate Recipients Source: https://context7.com/solapi/solapi-nodejs/llms.txt Allow duplicate recipients in a bulk send by setting the `allowDuplicates` option to `true`. ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Allow duplicate recipients const withDuplicates = await messageService.send( [ { to: '01012345678', from: '029302266', text: 'Dup OK message 1' }, { to: '01012345678', from: '029302266', text: 'Dup OK message 2' }, ], { allowDuplicates: true }, ); ``` -------------------------------- ### Handle Message Sending Errors Source: https://context7.com/solapi/solapi-nodejs/llms.txt Implement error handling for `MessageNotReceivedError` (all messages failed) and `BadRequestError` (invalid parameters). ```typescript import { SolapiMessageService } from 'solapi'; const messageService = new SolapiMessageService('YOUR_API_KEY', 'YOUR_API_SECRET'); // Error handling try { await messageService.send({ to: '01012345678', from: '029302266', text: 'Hi' }); } catch (err) { if (err._tag === 'MessageNotReceivedError') { console.error('All messages failed:', err.failedMessageList); } else if (err._tag === 'BadRequestError') { console.error('Invalid parameters:', err.message); } } ```