You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Acumatica REST API(C#/.NET)发送邮件而非存为草稿?

解决Acumatica REST API发送邮件仅存草稿的问题

我刚处理过类似的场景——你遇到的核心问题是:Acumatica的Email实体端点默认会将新创建的邮件保存为草稿状态,即使返回200 OK,也不会自动发送。要触发实际发送,需要在请求中添加特定字段,或者调用邮件的Send动作。下面是两种可行的C#/.NET实现方案:

方案一:创建邮件时直接触发发送

这种方式最直接,在创建邮件的请求体中加入SendEmail字段并设置为true,让系统在创建邮件的同时触发发送流程。

完整代码示例

首先我们封装一个Acumatica邮件发送类,包含登录和直接发送的逻辑:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

public class AcumaticaEmailService
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl;
    private readonly string _companyId;

    public AcumaticaEmailService(string baseUrl, string username, string password, string companyId)
    {
        _baseUrl = baseUrl;
        _companyId = companyId;
        // 初始化HttpClient,自动处理Cookie会话
        _httpClient = new HttpClient(new HttpClientHandler { UseCookies = true })
        {
            BaseAddress = new Uri(baseUrl)
        };
        _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    /// <summary>
    /// 登录Acumatica获取认证会话
    /// </summary>
    public async Task LoginAsync(string username, string password)
    {
        var loginPayload = new
        {
            name = username,
            password = password,
            company = _companyId
        };

        var loginContent = new StringContent(
            JsonConvert.SerializeObject(loginPayload),
            Encoding.UTF8,
            "application/json");

        var response = await _httpClient.PostAsync("/entity/auth/login", loginContent);
        response.EnsureSuccessStatusCode();
        // 会话Cookie会自动保存到HttpClient中,后续请求无需重复携带
    }

    /// <summary>
    /// 创建并直接发送邮件
    /// </summary>
    public async Task SendEmailAsync(string from, string to, string subject, string body)
    {
        var emailPayload = new
        {
            From = new { value = from },
            To = new { value = to },
            Subject = new { value = subject },
            Body = new { value = body },
            SendEmail = new { value = true }, // 关键字段:触发邮件发送
            MailStatus = new { value = "ReadyToSend" } // 确保状态标记为待发送
        };

        var emailContent = new StringContent(
            JsonConvert.SerializeObject(emailPayload),
            Encoding.UTF8,
            "application/json");

        var response = await _httpClient.PostAsync(
            $"/entity/Default/17.200.001/Email?CompanyID={_companyId}&ScreenID=CR306015",
            emailContent);

        response.EnsureSuccessStatusCode();
        var result = JsonConvert.DeserializeObject<dynamic>(await response.Content.ReadAsStringAsync());
        
        if (result.MailStatus.value == "Sent")
        {
            Console.WriteLine("邮件已成功发送!");
        }
        else
        {
            Console.WriteLine($"邮件当前状态:{result.MailStatus.value}");
        }
    }
}

使用方式

class Program
{
    static async Task Main(string[] args)
    {
        var emailService = new AcumaticaEmailService(
            baseUrl: "https://your-acumatica-instance-url",
            username: "your-login-username",
            password: "your-login-password",
            companyId: "STS");

        // 先登录获取认证会话
        await emailService.LoginAsync("your-actual-username", "your-actual-password");

        // 发送测试邮件
        await emailService.SendEmailAsync(
            from: "abc.service@abc.com",
            to: "example@abc.com",
            subject: "Test Email",
            body: "Sample Erp Bot Mail Check");
    }
}

方案二:先创建草稿,再调用Send动作

如果方案一不生效(比如你的Acumatica版本不支持SendEmail字段),可以先创建草稿邮件,再调用该邮件的Send动作来触发发送。

核心代码补充

在上面的AcumaticaEmailService类中添加以下方法:

/// <summary>
/// 先创建草稿,再调用Send动作发送邮件
/// </summary>
public async Task SendEmailViaActionAsync(string from, string to, string subject, string body)
{
    // 1. 创建草稿邮件
    var draftPayload = new
    {
        From = new { value = from },
        To = new { value = to },
        Subject = new { value = subject },
        Body = new { value = body }
    };

    var draftContent = new StringContent(
        JsonConvert.SerializeObject(draftPayload),
        Encoding.UTF8,
        "application/json");

    var draftResponse = await _httpClient.PostAsync(
        $"/entity/Default/17.200.001/Email?CompanyID={_companyId}&ScreenID=CR306015",
        draftContent);
    draftResponse.EnsureSuccessStatusCode();

    var draftResult = JsonConvert.DeserializeObject<dynamic>(await draftResponse.Content.ReadAsStringAsync());
    string emailId = draftResult.id.Value; // 获取草稿邮件的唯一ID

    // 2. 调用Send动作触发发送
    var actionContent = new StringContent("{}", Encoding.UTF8, "application/json");
    var sendResponse = await _httpClient.PostAsync(
        $"/entity/Default/17.200.001/Email/{emailId}/Send?CompanyID={_companyId}",
        actionContent);
    
    sendResponse.EnsureSuccessStatusCode();
    Console.WriteLine("邮件已通过Send动作成功发送!");
}

关键注意事项

  • 权限检查:确保你的Acumatica用户拥有CR306015(Email屏幕)的发送权限,否则会触发权限错误。
  • SMTP配置:确认Acumatica实例已经正确配置了SMTP服务器,否则即使触发发送,邮件也无法实际发出。
  • 版本适配:代码中的端点版本17.200.001要和你的Acumatica版本对应,比如新版本可能是23.200.001,需要调整。
  • 字段验证:有些Acumatica版本中,SendEmail字段可能被命名为IsSend,如果方案一无效,可以尝试替换字段名。

内容的提问来源于stack exchange,提问作者priyathamkumar tomala

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 11:02:55