Skip to content
Closed
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# Change Log
## [4.61.0](https://github.com/plivo/plivo-python/tree/v4.61.0) (2026-05-23)
**Major - bulk_messages.create**
- Added `src`, `dst`, `text`, `type`, `url`, `method`, `log`, `powerpack_uuid` parameters to bulk_messages.create (POST /v1/Account/{auth_id}/Message/Bulk/)

_Source: plivo/api-messaging#9001_

## [4.60.1](https://github.com/plivo/plivo-python/tree/v4.60.1) (2026-04-17)
**Bug Fix - PhoneNumber Compliance API**
- Fixed Requirements.get() sending None values as query params when not provided
Expand Down
18 changes: 18 additions & 0 deletions examples/bulk_messages_create.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
import plivo

client = plivo.RestClient(auth_id='YOUR_AUTH_ID', auth_token='YOUR_AUTH_TOKEN')

response = client.bulk_messages.create(
src='+14155551234',
dst='+14155550001<+14155550002<+14155550003',
text='Hello from Plivo Bulk Messaging!',
type_='sms',
url='https://example.com/delivery_status',
method='POST',
log=False,
)

print('API ID:', response.api_id)
print('Message UUIDs:', response.message_uuid)
print('Status:', response.message)
47 changes: 47 additions & 0 deletions plivo/resources/bulk_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
from plivo.utils.validators import *

from ..base import PlivoResource, PlivoResourceInterface
from ..exceptions import *
from ..utils import *


class BulkMessage(PlivoResource):
_name = 'BulkMessage'
_identifier_string = 'message_uuid'

def delete(self):
raise InvalidRequestError('Cannot delete a BulkMessage resource')

def update(self):
raise InvalidRequestError('Cannot update a BulkMessage resource')


class BulkMessages(PlivoResourceInterface):
_resource_type = BulkMessage

@validate_args(
src=[of_type(six.text_type)],
dst=[is_iterable(of_type(six.text_type), '<')],
text=[of_type(six.text_type)],
type_=[optional(of_type(six.text_type))],
url=[optional(is_url())],
method=[optional(of_type(six.text_type))],
log=[optional(of_type_exact(bool))],
powerpack_uuid=[optional(of_type(six.text_type))],
)
def create(self,
src,
dst,
text,
type_=None,
url=None,
method=None,
log=None,
powerpack_uuid=None):
params = to_param_dict(self.create, locals())
# rename type_ -> type for API
if 'type_' in params:
params['type'] = params.pop('type_')
return self.client.request('POST', ('Message', 'Bulk'),
params)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

setup(
name='plivo',
version='4.60.1',
version='4.61.0',
description='A Python SDK to make voice calls & send SMS using Plivo and to generate Plivo XML',
long_description=long_description,
url='https://github.com/plivo/plivo-python',
Expand Down
70 changes: 70 additions & 0 deletions tests/resources/test_bulk_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
from tests.base import PlivoResourceTestCase


class BulkMessageTest(PlivoResourceTestCase):
def test_create_bulk_message(self):
expected_response = {
'api_id': 'api-id-123',
'message_uuid': ['uuid-1', 'uuid-2'],
'message': 'requests queued',
}
self.client.set_expected_response(
status_code=202, data_to_return=expected_response)

response = self.client.bulk_messages.create(
src='+14155551234',
dst='+14155550001<+14155550002',
text='Hello World')

self.assertUrlEqual(
self.client.current_request.url,
self.get_url('Message', 'Bulk'))
self.assertEqual(self.client.current_request.method, 'POST')
self.assertEqual(response.message_uuid, expected_response['message_uuid'])

def test_create_bulk_message_with_optional_params(self):
expected_response = {
'api_id': 'api-id-456',
'message_uuid': ['uuid-3'],
'message': 'requests queued',
}
self.client.set_expected_response(
status_code=202, data_to_return=expected_response)

response = self.client.bulk_messages.create(
src='+14155551234',
dst='+14155550001',
text='Hello World',
type_='sms',
url='https://example.com/status',
method='POST',
log=False,
powerpack_uuid='some-powerpack-uuid')

self.assertUrlEqual(
self.client.current_request.url,
self.get_url('Message', 'Bulk'))
self.assertEqual(self.client.current_request.method, 'POST')
self.assertEqual(response.message_uuid, expected_response['message_uuid'])

def test_create_bulk_message_with_invalid_numbers(self):
expected_response = {
'api_id': 'api-id-789',
'message_uuid': ['uuid-4'],
'message': 'requests queued',
'invalid_number': ['+1invalid'],
}
self.client.set_expected_response(
status_code=202, data_to_return=expected_response)

response = self.client.bulk_messages.create(
src='+14155551234',
dst='+14155550001<+1invalid',
text='Hello World')

self.assertUrlEqual(
self.client.current_request.url,
self.get_url('Message', 'Bulk'))
self.assertEqual(self.client.current_request.method, 'POST')
self.assertEqual(response.invalid_number, expected_response['invalid_number'])
Loading