Update delivery report and message result objects to bring it in line with common Drupal standards, similar to the treatment applied to SmsMessage* classes.

  • Add setters
  • Add [missing] getters
  • Remove mystery meat constructors
  • Both objects have duplicated redundant status codes. Move to external class.
  • Change status codes to strings. Integers are meaningless. the 2,3,4,5 prefixes mapping to positivity or neg is not used. We have ->getStatus() to track positivity
  • Add unit tests, there are currently no tests.

Review result objects

\Drupal\sms\Message\SmsMessageResultInterface

new SmsMessageResult count: 3, zero are tests.

Review deliver report objects

\Drupal\sms\Message\SmsDeliveryReportInterface

new SmsDeliveryReport count: 4, zero are tests.

Comments

dpi created an issue. See original summary.

dpi’s picture

Issue summary: View changes
dpi’s picture

Issue summary: View changes
dpi’s picture

I'm doing some experimentation here https://github.com/dpi/smsframework/pull/51

The first commit adds the methods and simple stuff. Second commit onwards has some radical stuff. Did I go too far? Maybe. But I'm doing some real gateway development with this experimental report/result/status branch and it seems fine so far.

I'm working on the following gateways: Telstra (best example), Clickatell, and MailUp (not ready). And I may try Twilio if I have some time. This should give me an idea of how results and reports need to be implemented.

almaudoh’s picture

Just did a quick code check. The change from PHP arrays to objects with interfaces is a good one. So is the status constants move to a dedicated class.
However, I don't see the need why the Delivery report recipients property is an array. I don't see a use case for that. Even in your code, each delivery report is keyed by the same single recipient number.
I also still don't see the benefit of composing the SmsMessage object into the SmsResult object (especially if they are both serialized). I would rather compose the SmsResult into the SmsMessage object.

dpi’s picture

Just did a quick code check. The change from PHP arrays to objects with interfaces is a good one. So is the status constants move to a dedicated class.

Awesome.

However, I don't see the need why the Delivery report recipients property is an array. I don't see a use case for that. Even in your code, each delivery report is keyed by the same single recipient number.

The keying of Result::reports should probably be made unrelated to recipients. So far I see reports as an atomic operation, all recipients should have the same status. Otherwise create new reports if there are differing status.

I also still don't see the benefit of composing the SmsMessage object into the SmsResult object (especially if they are both serialized).

I added the message to the result purely for the benefit of post process hooks. There is no other reason, and yes I agree it is not ideal.

I would rather compose the SmsResult into the SmsMessage object.

Can give this a shot.

dpi’s picture

Pushed to the PR:

  • Added getResult/setResult to message objects for use in post process events in #2786865.
    Removed Result::setMessages/getMessages
  • Updated result::reports to have meaningless array keys.
  • Updated result::getReport to iterate over reports, since keys no longer are for recipient.
dpi’s picture

Status: Active » Needs review
StatusFileSize
new42.26 KB

Merged into #2786865: Replacing hooks with Symfony events. Updated provider to use message::setResult from #7

Changes pushed to PR

Status: Needs review » Needs work

The last submitted patch, 8: update-report-and-result-objects-2789237-8-21856ff.patch, failed testing.

The last submitted patch, 8: update-report-and-result-objects-2789237-8-21856ff.patch, failed testing.

The last submitted patch, 8: update-report-and-result-objects-2789237-8-21856ff.patch, failed testing.

The last submitted patch, 8: update-report-and-result-objects-2789237-8-21856ff.patch, failed testing.

dpi’s picture

Status: Needs work » Needs review

Ah, the tests exposed the reason why I chose the original design of tacking SMS message onto result:

the provider::send/incoming return an array of results, and there is no reference to the sent SMS messages (chunked, or otherwise).

  1. We can change the @return signature of send/incoming to be an array of SMS messages. (preferred)
  2. Or, revert to the original design of result->messages
almaudoh’s picture

We can change the @return signature of send/incoming to be an array of SMS messages. (preferred)
Or, revert to the original design of result->messages

#13.1 Is preferable.

Have you considered the case when delivery reports are updated at a later time (that happens to me all the time)? The message might be delayed by the SMSC for a while with a "pending" status. And thereafter updated to "delivered".

dpi’s picture

Have you considered the case when delivery reports are updated at a later time

Considering reports themselves arn't persistent it didnt seam to matter...?

If we want to force reports to be for a single recipient that's OK I suppose.

I imagined if a status needed to be updated you can programmatically find the old report by using message Id + recipient.

dpi’s picture

Status: Needs review » Needs work

The last submitted patch, 16: update-report-and-result-objects-2789237-16-cffe92c.patch, failed testing.

The last submitted patch, 16: update-report-and-result-objects-2789237-16-cffe92c.patch, failed testing.

The last submitted patch, 16: update-report-and-result-objects-2789237-16-cffe92c.patch, failed testing.

The last submitted patch, 16: update-report-and-result-objects-2789237-16-cffe92c.patch, failed testing.

almaudoh’s picture

+SMS International
+-----------------
+
+Status: Not upgraded for Drupal 8. See https://www.drupal.org/node/331629
+
 SMS Send to Phone
 -----------------
 
@@ -33,11 +38,25 @@ Status: Not upgraded for Drupal 8. See https://www.drupal.org/node/331629
 
 Provides ways to share nodes via SMS.
 
+SMS Track
+---------
+
+Status: May be deprecated
+
+Message archiving and delivery tracking for the SMS Framework.
+
 SMS User
 --------
 
 Provides integration with Drupal users.
 
+SMS Valid
+---------
+
+Status: May be deprecated. See https://www.drupal.org/node/2642946
+
+Provides number validation features to the SMS Framework.
+

These are unrelated changes (looks like it's already committed even)

dpi’s picture

Yeh don't worry about the patch, just using patches for test runner. Theres a bunch of random other junk in there too.

Just use PR for review.

dpi’s picture

And its not ready for review right now ;)

Probably this weekend sometime.

dpi’s picture

Status: Needs work » Needs review
StatusFileSize
new51.83 KB

Since #16: Split status classes into two, updated interface documentation to refer to these classes instead of the old status class.

---

So as I see it now, to programmatically determine if a message was sent successfully:

  • There must be *no* status set on result. The only status available for result are negative.
  • There must be at least one delivery report.

Does this make sense?

dpi’s picture

Ignore the SmsDevelMessageForm code in the patch, just review the commits in PR. I was experimenting with how the devel message form determines if a message was sent successfully. See question in #24.

Status: Needs review » Needs work

The last submitted patch, 24: update-report-and-result-objects-2789237-24-557a89f.patch, failed testing.

The last submitted patch, 24: update-report-and-result-objects-2789237-24-557a89f.patch, failed testing.

The last submitted patch, 24: update-report-and-result-objects-2789237-24-557a89f.patch, failed testing.

The last submitted patch, 24: update-report-and-result-objects-2789237-24-557a89f.patch, failed testing.

dpi’s picture

Patch will fail since I have not updated tests with new codes.

edit: codes, not return type

dpi’s picture

Status: Needs work » Needs review
StatusFileSize
new51.82 KB

Status: Needs review » Needs work

The last submitted patch, 31: update-report-and-result-objects-2789237-31-8b9f539.patch, failed testing.

The last submitted patch, 31: update-report-and-result-objects-2789237-31-8b9f539.patch, failed testing.

The last submitted patch, 31: update-report-and-result-objects-2789237-31-8b9f539.patch, failed testing.

The last submitted patch, 31: update-report-and-result-objects-2789237-31-8b9f539.patch, failed testing.

dpi’s picture

Status: Needs work » Needs review
StatusFileSize
new54.24 KB

Per #5

However, I don't see the need why the Delivery report recipients property is an array.

and #14

force reports to be for a single recipient

Updating report object to have only one recipient.

dpi’s picture

almaudoh’s picture

Overall, this is a good refactoring. I made comments in the PR. I'll still check out the code for any nitpicks left.

One good thing about the new return value of SmsProviderInterface::send () is that it is possible to track messages sent together even after chunking since they are all returned together in one array. I think we could add a tracking number field that allows custom generated identifiers to be stored. I'll raise a separate issue for that.

dpi’s picture

Fixed and pushed nitpicks, ive posted some replies if you can take a look at those.

Theres a question you may have missed in #24 during the barrage of testbot results.

Are you online now?

dpi’s picture

Working on unit tests.

dpi’s picture

Includes nit fixes and unit tests, stricter variable type handling

  • Added exception for incorrect variable type for setCreditsUsed and setCreditsBalance.
  • Made the existing public variables in SmsMessageResult protected.
  • Added unit test for message object and entity getResult and setResult methods.
  • Added unit test for delivery report class.
  • Added unit test for result class.

Status: Needs review » Needs work

The last submitted patch, 41: update-report-and-result-objects-2789237-40-a767828.patch, failed testing.

The last submitted patch, 41: update-report-and-result-objects-2789237-40-a767828.patch, failed testing.

The last submitted patch, 41: update-report-and-result-objects-2789237-40-a767828.patch, failed testing.

The last submitted patch, 41: update-report-and-result-objects-2789237-40-a767828.patch, failed testing.

dpi’s picture

Status: Needs work » Needs review
StatusFileSize
new64.7 KB

Fixed some @covers annotations from the new unit tests.

dpi’s picture

Pushed:

  • Renamed protected credit balance variable to match getter and setter
  • Added invalid parameters constant to result status class.
dpi’s picture

Going all in on the meaning of status messages for result. Per #2789237: Update delivery report and message result objects #24

Renaming result::*status* to result::*error*. Current head has getErrorMessage for result too, but it also has getStatus.

What do you think of:

result state evaluated status computed status - binary
Result object? Result object has error code? (result::getError() !== NULL) Has reports (count(reports) > 0)
N - - unknown error (FAILURE)
Yes Yes Yes ? (UNKNOWN STATE)
Yes Yes No see result error (FAILURE)
Yes No Yes no issues (SUCCESS)
Yes No No unknown error (FAILURE)

We should really arrange a d.o documentation page for this ;) (edit: 22 nov 2016, created: https://www.drupal.org/node/2829641)

dpi’s picture

Status: Needs review » Needs work

The last submitted patch, 49: update-report-and-result-objects-2789237-48-578f5cb.patch, failed testing.

The last submitted patch, 49: update-report-and-result-objects-2789237-48-578f5cb.patch, failed testing.

The last submitted patch, 49: update-report-and-result-objects-2789237-48-578f5cb.patch, failed testing.

The last submitted patch, 49: update-report-and-result-objects-2789237-48-578f5cb.patch, failed testing.

dpi’s picture

Status: Needs work » Needs review
StatusFileSize
new70.45 KB

Updated devel form asserts

almaudoh’s picture

Going all in on the meaning of status messages for result. Per #2789237: Update delivery report and message result objects #24

I actually thought I had commented on #24. Seems like I didn't post it.

I would look at maybe two or three SMS providers to get an idea of things. What I've seen typically is result::getStatus is false (and count of reports == 0) if there is an error that makes it impossible to send to any recipient. But once the message can be dispatched, then result::getStatus is true (and count of reports == count of recipients), while individual recipient status is reflected in the reports.

If we want to merge the "did this succeed or fail" function with the "why did this fail" function then maybe a NULL status could mean success (or a non-zero report count if we adhere to the contract mentioned above).

dpi’s picture

I would look at maybe two or three SMS providers to get an idea of things.

I'm working with three providers so far ;), however...

Just to be clear its just informational, the *why* isnt important since we are not acting apon the success or failure.

I had imagined something like $result->addTryAgain($recipient, 'some measure of time'); to resolve some types of failures. At least when using the queue system.

NULL status could mean success

The table I have has the error code == NULL as one of the variables to determine success. I think its reasonable to add the requirement of at least one report to be super sure about that. There would seem to be some kind of failure in some way if there are no reports?

dpi’s picture

I re-read your comment and see I can interpret it differently.

I think having setError instead of setStatus is better, gateways dont have to do anything on success. So we can easily determine if the whole transaction failed by checking if there is any error code. If it was binary/NULL, we have three states, where NULL == unknown status?. It makes it a lot harder to determine what happened this way.

count of reports == count of recipients

Im not sure you can qualify *success* from this equation, since reports now have their own status codes. We can assume all reports were *processed*.

This is where my aforementioned "try again?" idea comes from, since we cant tell easily from error codes whether its a good idea to retry the message (eg: such as flooded) or just dump it (eg: bad recipient).

Other than generating log data, what can we potentially automate from status codes?

  1. Retry the message later
  2. ...?
almaudoh’s picture

So as we stand now, we read errors for results and read status for reports. That makes sense. This is a big change and a huge patch, but it's a good change and I think we should push it and maybe make improvement's in follow-up issues.

I had imagined something like $result->addTryAgain($recipient, 'some measure of time'); to resolve some types of failures. At least when using the queue system.

We can do this in a follow-up.

Other than generating log data, what can we potentially automate from status codes?

Status codes are really mostly for informational purposes for the user or administrator. Maybe also for statistics (I typically use statistics of delivery status to determine the effectiveness of a gateway)
The only other thing I can think about (in terms of automation) similar to what I answered in the other thread is to automatically select gateways for particular routes based on effectiveness. But that's way out of scope of this issue.

almaudoh’s picture

I'm ready to RTBC this once you post the latest patch for the testbot.

dpi’s picture

Updated. Should be fine.

Status: Needs review » Needs work

The last submitted patch, 60: update-report-and-result-objects-2789237-60-dce3675.patch, failed testing.

The last submitted patch, 60: update-report-and-result-objects-2789237-60-dce3675.patch, failed testing.

The last submitted patch, 60: update-report-and-result-objects-2789237-60-dce3675.patch, failed testing.

The last submitted patch, 60: update-report-and-result-objects-2789237-60-dce3675.patch, failed testing.

dpi’s picture

Status: Needs work » Needs review
StatusFileSize
new70.46 KB

oops, forgot about tests

  • dpi committed 8f9bc7b on 8.x-1.x
    Issue #2789237 by dpi: Update delivery report and message result objects
    
dpi’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.