<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Microsoft Graph Email: Unable to Add Multiple Recipients via SAS Code in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Microsoft-Graph-Email-Unable-to-Add-Multiple-Recipients-via-SAS/m-p/986928#M380003</link>
    <description>&lt;P&gt;This is not a complete answer, but you'll need to add some looping to generate the json array of email addresses.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You could try replacing your current line:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;put '      { "emailAddress": { "address": "' addr +(-1) '" } }';&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;With a macro loop like below:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  %local i ;
  %do i=1 %to %sysfunc(countw(&amp;amp;to,%str( ))) ;
    %if &amp;amp;i&amp;gt;1 %then %do ;
      put "," ;
    %end ;
    put "      { ""emailAddress"": { ""address"": ""%scan(&amp;amp;to,&amp;amp;i,%str( ))"" } }";
  %end ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;That would allow you to pass a space-delimited list of email addresses.&lt;/P&gt;</description>
    <pubDate>Tue, 28 Apr 2026 19:22:46 GMT</pubDate>
    <dc:creator>Quentin</dc:creator>
    <dc:date>2026-04-28T19:22:46Z</dc:date>
    <item>
      <title>Microsoft Graph Email: Unable to Add Multiple Recipients via SAS Code</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Microsoft-Graph-Email-Unable-to-Add-Multiple-Recipients-via-SAS/m-p/986912#M380002</link>
      <description>&lt;DIV&gt;
&lt;P&gt;&lt;FONT face="arial,helvetica,sans-serif" size="2"&gt;Hello,&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="arial,helvetica,sans-serif" size="2"&gt;Currently, we have configured an Azure app (Microsoft Graph) to send emails from our SAS Viya environment using SAS code. I am able to successfully send emails using this code.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="arial,helvetica,sans-serif" size="2"&gt;However, the issue is that I can only send an email to a single email address. I am unable to specify multiple email addresses in the &lt;STRONG&gt;To&lt;/STRONG&gt; field with the current code. I am struggling to update the code logic to support multiple recipients.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="arial,helvetica,sans-serif" size="2"&gt;Could you please help me with this?&lt;/FONT&gt;&lt;/P&gt;
&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;%macro send_graph_mail(
    to=,
    cc=,
    subject=,
    body=
);

    %local access_token has_cc CLIENT_ID CLIENT_SECRET TENANT_ID;
    %let has_cc = %sysfunc(ifc(%length(&amp;amp;cc) &amp;gt; 0, 1, 0));

    %let CLIENT_ID     = xxxxxxx;
    %let CLIENT_SECRET = xxxxxxx;
    %let TENANT_ID     = xxxxxxx;

    /*--------------------------------*/
    /* Get OAuth token                */
    /*--------------------------------*/
    filename resp temp;

    proc http
        url="https://login.microsoftonline.com/&amp;amp;TENANT_ID/oauth2/v2.0/token"
        method="POST"
        in="grant_type=client_credentials%str(&amp;amp;)
            client_id=&amp;amp;CLIENT_ID%str(&amp;amp;)
            client_secret=&amp;amp;CLIENT_SECRET%str(&amp;amp;)
            scope=https://graph.microsoft.com/.default"
        ct="application/x-www-form-urlencoded"
        out=resp;
    run;

    libname auth json fileref=resp;

    data _null_;
        set auth.root;
        call symputx('access_token', access_token );
    run;

    /*--------------------------------*/
    /* Build mail JSON                */
    /*--------------------------------*/

    filename mail temp;

    data _null_;
        length subject_txt body_txt addr $1000;
        file mail lrecl=32767;

        subject_txt = strip(symget('subject'));
        body_txt    = strip(symget('body'));

        subject_txt = tranwrd(subject_txt, '"', '\"');
        body_txt    = tranwrd(body_txt,    '"', '\"');

        addr = strip(symget('to'));

        put '{';
        put '  "message": {';
        put '    "subject": ' '"' subject_txt '"' ',';
        put '    "body": {';
        put '      "contentType": "Text",';
        put '      "content": ' '"' body_txt '"' ;
        put '    },';
        put '    "toRecipients": [';
        
        
        addr = symget('to');
        addr = strip(addr);
        addr = left(addr);


        put '      { "emailAddress": { "address": "' addr +(-1) '" } }';
        put '    ]';
        put '  }';
        put '}';
    run;

    /*-----------------------------*/
    /* Send email                  */
    /*-----------------------------*/
    filename sendresp temp;
    
    proc http
        url="https://graph.microsoft.com/v1.0/users/&amp;amp;SENDER_EMAIL/sendMail"
        method="POST"
        in=mail
        out=sendresp;
        headers
        "Authorization"="Bearer &amp;amp;access_token"
        "Content-Type"="application/json";
    run;

%mend;

data _null_;
    format dte ddmmyy10. tme time8.;
    dt = datetime();
    call symputx(
        'mail_body',
        cats(
            'Hello,', 
            'The scheduled job completed successfully at ',
            put(datepart(dt), ddmmyy10.), ' ',
            put(timepart(dt), time8.), 
            'Thank you', 
            'Platform Support Team'
        ),
        'L'
    );
run;


%send_graph_mail(
    to=fresh.starter@org.com,
    subject=Test SAS Completed Successfully,
    body=%superq(mail_body)
);
&lt;/PRE&gt;</description>
      <pubDate>Tue, 28 Apr 2026 17:24:15 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Microsoft-Graph-Email-Unable-to-Add-Multiple-Recipients-via-SAS/m-p/986912#M380002</guid>
      <dc:creator>freshstarter</dc:creator>
      <dc:date>2026-04-28T17:24:15Z</dc:date>
    </item>
    <item>
      <title>Re: Microsoft Graph Email: Unable to Add Multiple Recipients via SAS Code</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Microsoft-Graph-Email-Unable-to-Add-Multiple-Recipients-via-SAS/m-p/986928#M380003</link>
      <description>&lt;P&gt;This is not a complete answer, but you'll need to add some looping to generate the json array of email addresses.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You could try replacing your current line:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;put '      { "emailAddress": { "address": "' addr +(-1) '" } }';&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;With a macro loop like below:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  %local i ;
  %do i=1 %to %sysfunc(countw(&amp;amp;to,%str( ))) ;
    %if &amp;amp;i&amp;gt;1 %then %do ;
      put "," ;
    %end ;
    put "      { ""emailAddress"": { ""address"": ""%scan(&amp;amp;to,&amp;amp;i,%str( ))"" } }";
  %end ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;That would allow you to pass a space-delimited list of email addresses.&lt;/P&gt;</description>
      <pubDate>Tue, 28 Apr 2026 19:22:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Microsoft-Graph-Email-Unable-to-Add-Multiple-Recipients-via-SAS/m-p/986928#M380003</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2026-04-28T19:22:46Z</dc:date>
    </item>
    <item>
      <title>Re: Microsoft Graph Email: Unable to Add Multiple Recipients via SAS Code</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Microsoft-Graph-Email-Unable-to-Add-Multiple-Recipients-via-SAS/m-p/986936#M380004</link>
      <description>&lt;P&gt;Thank you so much&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/19879"&gt;@Quentin&lt;/a&gt;&amp;nbsp;.it worked.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But when I update the same code for cc Recipients, it throws me an error message.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;
&lt;PRE&gt;{"error":{"code":"BadRequest","message":"Unable to read JSON request payload. Please ensure Content-Type header is set and payload i
s of valid JSON format.","innerError":{"date":"2026-04-28T21:17:39","request-id":"xxxx","client-request-id":"xxxx"}}}&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;DIV&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro send_graph_mail(
    to=,
    cc=,
    subject=,
    body=
);

    %local access_token has_cc CLIENT_ID CLIENT_SECRET TENANT_ID;
    %let has_cc = %sysfunc(ifc(%length(&amp;amp;cc) &amp;gt; 0, 1, 0));

    %let CLIENT_ID     = xxxxxxxxxxxxxxxxxxxxx;
    %let CLIENT_SECRET = xxxxxxxxxxxxxxxxxxxxx;
    %let TENANT_ID     = xxxxxxxxxxxxxxxxxxxxx;

    /*--------------------------------*/
    /* Get OAuth token                */
    /*--------------------------------*/
    filename resp temp;

    proc http
        url="https://login.microsoftonline.com/&amp;amp;TENANT_ID/oauth2/v2.0/token"
        method="POST"
        in="grant_type=client_credentials%str(&amp;amp;)
            client_id=&amp;amp;CLIENT_ID%str(&amp;amp;)
            client_secret=&amp;amp;CLIENT_SECRET%str(&amp;amp;)
            scope=https://graph.microsoft.com/.default"
        ct="application/x-www-form-urlencoded"
        out=resp;
    run;

    libname auth json fileref=resp;

    data _null_;
        set auth.root;
        call symputx('access_token', access_token );
    run;

    /*--------------------------------*/
    /* Build mail JSON                */
    /*--------------------------------*/

    filename mail temp;

    data _null_;
        length subject_txt body_txt addr $1000;
        file mail lrecl=32767;

        subject_txt = strip(symget('subject'));
        body_txt    = strip(symget('body'));

        subject_txt = tranwrd(subject_txt, '"', '\"');
        body_txt    = tranwrd(body_txt,    '"', '\"');

        addr = strip(symget('to'));

        put '{';
        put '  "message": {';
        put '    "subject": ' '"' subject_txt '"' ',';
        put '    "body": {';
        put '      "contentType": "HTML",';
        put '      "content": ' '"' body_txt '"' ;
        put '    },';
        put '    "toRecipients": [';
        
        
        %local i ;
        %do i=1 %to %sysfunc(countw(&amp;amp;to,%str( ))) ;
        %if &amp;amp;i&amp;gt;1 %then %do ;
        put "," ;
        %end ;
        put "      { ""emailAddress"": { ""address"": ""%scan(&amp;amp;to,&amp;amp;i,%str( ))"" } }";
        %end ;
        put '    ]';

        put '    "ccRecipients": [';      
        %local j ;
        %do j=1 %to %sysfunc(countw(&amp;amp;cc,%str( ))) ;
        %if &amp;amp;j&amp;gt;1 %then %do ;
        put "," ;
        %end ;
        put "      { ""emailAddress"": { ""address"": ""%scan(&amp;amp;cc,&amp;amp;j,%str( ))"" } }";
        %end ;
        put '    ]';
      
        put '  }';
        put '}';
    run;

    /*-----------------------------*/
    /* Send email                  */
    /*-----------------------------*/
    filename sendresp temp;

    proc http
        url="https://graph.microsoft.com/v1.0/users/&amp;amp;SENDER_MAIL/sendMail"
        method="POST"
        in=mail
        out=sendresp;
        headers
        "Authorization"="Bearer &amp;amp;access_token"
        "Content-Type"="application/json";
    run;

    
data _null_;
    infile sendresp;
    input;
    putlog _infile_;
run;

%mend;

data _null_;
    format dte ddmmyy10. tme time8.;
    dt = datetime();

    call symputx(
        'mail_body',
        catx(
            '',
            '&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;',
            '&amp;lt;p&amp;gt;Hello,&amp;lt;/p&amp;gt;',
            '&amp;lt;p&amp;gt;The scheduled job completed successfully on ',
            put(datepart(dt), ddmmyy10.),
            ' at ',
            put(timepart(dt), time8.),
            '.&amp;lt;/p&amp;gt;',
            '&amp;lt;p&amp;gt;Thank you,&amp;lt;br&amp;gt;',
            'Platform Support Team&amp;lt;/p&amp;gt;',
            '&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'
        ),
        'L'
    );
run;


%send_graph_mail(
    to=fresh.starter@org.com freshstarter@gmail.com,
    cc=fresh.starter@org.com,
    subject=Test SAS Extract Completed Successfully,
    body=%superq(mail_body)
);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;</description>
      <pubDate>Tue, 28 Apr 2026 21:33:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Microsoft-Graph-Email-Unable-to-Add-Multiple-Recipients-via-SAS/m-p/986936#M380004</guid>
      <dc:creator>freshstarter</dc:creator>
      <dc:date>2026-04-28T21:33:43Z</dc:date>
    </item>
    <item>
      <title>Re: Microsoft Graph Email: Unable to Add Multiple Recipients via SAS Code</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Microsoft-Graph-Email-Unable-to-Add-Multiple-Recipients-via-SAS/m-p/986941#M380006</link>
      <description>&lt;P&gt;It is working now. I have missed a comma, Thanks for the support&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%if &amp;amp;has_cc %then %do;
    put '   , "ccRecipients": [';      
    %do j=1 %to %sysfunc(countw(&amp;amp;cc,%str( ))) ;
        %if &amp;amp;j&amp;gt;1 %then %do ;
            put "," ;
        %end ;
        put "      { ""emailAddress"": { ""address"": ""%scan(&amp;amp;cc,&amp;amp;j,%str( ))"" } }";
    %end ;
    put '    ]';
%end;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 29 Apr 2026 08:28:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Microsoft-Graph-Email-Unable-to-Add-Multiple-Recipients-via-SAS/m-p/986941#M380006</guid>
      <dc:creator>freshstarter</dc:creator>
      <dc:date>2026-04-29T08:28:42Z</dc:date>
    </item>
  </channel>
</rss>

